/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.internal.telephony; import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM; import android.hardware.radio.RadioError; import android.hardware.radio.RadioResponseInfo; import android.hardware.radio.modem.IRadioModemResponse; import android.hardware.radio.modem.ImeiInfo; import android.os.SystemClock; import android.telephony.ActivityStatsTechSpecificInfo; import android.telephony.AnomalyReporter; import android.telephony.ModemActivityInfo; import java.util.ArrayList; import java.util.UUID; /** * Interface declaring response functions to solicited radio requests for modem APIs. */ public class ModemResponse extends IRadioModemResponse.Stub { private final RIL mRil; public ModemResponse(RIL ril) { mRil = ril; } /** * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for * radio request which take long time to respond. * For more details, refer https://source.android.com/devices/tech/connect/ril.html * @param serial Serial no. of the request whose acknowledgement is sent. */ public void acknowledgeRequest(int serial) { mRil.processRequestAck(serial); } /** * @param responseInfo Response info struct containing response type, serial number and error. */ public void enableModemResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param version String containing version string for log reporting */ public void getBasebandVersionResponse(RadioResponseInfo responseInfo, String version) { RadioResponse.responseString(HAL_SERVICE_MODEM, mRil, responseInfo, version); } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param imei IMEI if GSM subscription is available * @param imeisv IMEISV if GSM subscription is available * @param esn ESN if CDMA subscription is available * @param meid MEID if CDMA subscription is available */ public void getDeviceIdentityResponse(RadioResponseInfo responseInfo, String imei, String imeisv, String esn, String meid) { RadioResponse.responseStrings( HAL_SERVICE_MODEM, mRil, responseInfo, imei, imeisv, esn, meid); } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param imeiInfo object containing ImeiType, device IMEI and IMEISV */ public void getImeiResponse(RadioResponseInfo responseInfo, ImeiInfo imeiInfo) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { if (responseInfo.error == RadioError.NONE) { RadioResponse.sendMessageResponse(rr.mResult, imeiInfo); } mRil.processResponseDone(rr, responseInfo, imeiInfo); } } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param config Array of HardwareConfig of the radio */ public void getHardwareConfigResponse(RadioResponseInfo responseInfo, android.hardware.radio.modem.HardwareConfig[] config) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { ArrayList ret = RILUtils.convertHalHardwareConfigList(config); if (responseInfo.error == RadioError.NONE) { RadioResponse.sendMessageResponse(rr.mResult, ret); } mRil.processResponseDone(rr, responseInfo, ret); } } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param activityInfo modem activity information */ public void getModemActivityInfoResponse(RadioResponseInfo responseInfo, android.hardware.radio.modem.ActivityStatsInfo activityInfo) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { ModemActivityInfo ret = null; ActivityStatsTechSpecificInfo[] astsi = null; if (responseInfo.error == RadioError.NONE) { final int sleepModeTimeMs = activityInfo.sleepModeTimeMs; final int idleModeTimeMs = activityInfo.idleModeTimeMs; int size = activityInfo.techSpecificInfo.length; astsi = new ActivityStatsTechSpecificInfo[size]; for (int s = 0; s < size; s++) { int rat = activityInfo.techSpecificInfo[s].rat; int frequencyRange = activityInfo.techSpecificInfo[s].frequencyRange; int [] txModeTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()]; int rxModeTimeMs = activityInfo.techSpecificInfo[s].rxModeTimeMs; for (int i = 0; i < ModemActivityInfo.getNumTxPowerLevels(); i++) { txModeTimeMs[i] = activityInfo.techSpecificInfo[s].txmModetimeMs[i]; } astsi[s] = new ActivityStatsTechSpecificInfo( rat, frequencyRange, txModeTimeMs, rxModeTimeMs); } ret = new ModemActivityInfo(SystemClock.elapsedRealtime(), sleepModeTimeMs, idleModeTimeMs, astsi); } else { astsi = new ActivityStatsTechSpecificInfo[1]; astsi[0] = new ActivityStatsTechSpecificInfo(0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0); ret = new ModemActivityInfo(SystemClock.elapsedRealtime(), 0, 0, astsi); responseInfo.error = RadioError.NONE; } RadioResponse.sendMessageResponse(rr.mResult, ret); mRil.processResponseDone(rr, responseInfo, ret); } } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param isEnabled whether the modem stack is enabled. */ public void getModemStackStatusResponse(RadioResponseInfo responseInfo, boolean isEnabled) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { if (responseInfo.error == RadioError.NONE) { RadioResponse.sendMessageResponse(rr.mResult, isEnabled); } mRil.processResponseDone(rr, responseInfo, isEnabled); } } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param radioCapability RadioCapability from the modem */ public void getRadioCapabilityResponse(RadioResponseInfo responseInfo, android.hardware.radio.modem.RadioCapability radioCapability) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil); if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED || responseInfo.error == RadioError.GENERIC_FAILURE) { // TODO: Construct the supported RAF bitmask based on preferred network bitmasks ret = mRil.makeStaticRadioCapability(); responseInfo.error = RadioError.NONE; } if (responseInfo.error == RadioError.NONE) { RadioResponse.sendMessageResponse(rr.mResult, ret); } mRil.processResponseDone(rr, responseInfo, ret); } } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param result String containing the contents of the NV item */ public void nvReadItemResponse(RadioResponseInfo responseInfo, String result) { RadioResponse.responseString(HAL_SERVICE_MODEM, mRil, responseInfo, result); } /** * @param responseInfo Response info struct containing response type, serial no. and error */ public void nvResetConfigResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error */ public void nvWriteCdmaPrlResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error */ public void nvWriteItemResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error */ public void requestShutdownResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error */ public void sendDeviceStateResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); } /** * @param responseInfo Response info struct containing response type, serial no. and error * @param radioCapability RadioCapability to set */ public void setRadioCapabilityResponse(RadioResponseInfo responseInfo, android.hardware.radio.modem.RadioCapability radioCapability) { RILRequest rr = mRil.processResponse(HAL_SERVICE_MODEM, responseInfo); if (rr != null) { RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil); if (responseInfo.error == RadioError.NONE) { RadioResponse.sendMessageResponse(rr.mResult, ret); } mRil.processResponseDone(rr, responseInfo, ret); } } /** * @param responseInfo Response info struct containing response type, serial no. and error. */ public void setRadioPowerResponse(RadioResponseInfo responseInfo) { RadioResponse.responseVoid(HAL_SERVICE_MODEM, mRil, responseInfo); mRil.mLastRadioPowerResult = responseInfo.error; if (responseInfo.error == RadioError.RF_HARDWARE_ISSUE) { AnomalyReporter.reportAnomaly( UUID.fromString(RILUtils.RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID), "RF HW damaged"); } else if (responseInfo.error == RadioError.NO_RF_CALIBRATION_INFO) { AnomalyReporter.reportAnomaly( UUID.fromString(RILUtils.RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID), "No RF calibration data"); } else if (responseInfo.error != RadioError.RADIO_NOT_AVAILABLE && responseInfo.error != RadioError.NONE) { AnomalyReporter.reportAnomaly( UUID.fromString(RILUtils.RADIO_POWER_FAILURE_BUGREPORT_UUID), "Radio power failure"); } } @Override public String getInterfaceHash() { return IRadioModemResponse.HASH; } @Override public int getInterfaceVersion() { return IRadioModemResponse.VERSION; } }