OSDN Git Service

Handle empty apn string in setInitialAttachApn HIDL API.
[android-x86/hardware-ril.git] / libril / ril_service.cpp
index 607574a..5a2825d 100644 (file)
@@ -41,6 +41,7 @@ using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::hidl_array;
 using ::android::hardware::radio::V1_1::NetworkScanRequest;
+using ::android::hardware::radio::V1_1::KeepaliveRequest;
 using ::android::hardware::Void;
 using android::CommandInfo;
 using android::RequestInfo;
@@ -436,6 +437,10 @@ struct RadioImpl : public ::android::hardware::radio::V1_1::IRadio {
 
     Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter);
 
+    Return<void> startKeepalive(int32_t serial, const KeepaliveRequest& keepalive);
+
+    Return<void> stopKeepalive(int32_t serial, int32_t sessionHandle);
+
     Return<void> setSimCardPower(int32_t serial, bool powerUp);
     Return<void> setSimCardPower_1_1(int32_t serial,
             const ::android::hardware::radio::V1_1::CardPowerState state);
@@ -443,8 +448,7 @@ struct RadioImpl : public ::android::hardware::radio::V1_1::IRadio {
     Return<void> responseAcknowledgement();
 
     Return<void> setCarrierInfoForImsiEncryption(int32_t serial,
-            const ::android::hardware::hidl_vec<uint8_t>& carrierKey,
-            const hidl_string& keyIdentifier);
+            const ::android::hardware::radio::V1_1::ImsiEncryptionInfo& message);
 
     void checkReturnStatus(Return<void>& ret);
 };
@@ -1289,7 +1293,7 @@ Return<void> RadioImpl::setBarringPassword(int32_t serial, const hidl_string& fa
     RLOGD("setBarringPassword: serial %d", serial);
 #endif
     dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
-            2, oldPassword.c_str(), newPassword.c_str());
+            3, facility.c_str(), oldPassword.c_str(), newPassword.c_str());
     return Void();
 }
 
@@ -1331,8 +1335,63 @@ Return<void> RadioImpl::startNetworkScan(int32_t serial, const NetworkScanReques
 #if VDBG
     RLOGD("startNetworkScan: serial %d", serial);
 #endif
-    // TODO(b/30954762): Add implementation to start network scan.
-    dispatchVoid(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    if (request.specifiers.size() > MAX_RADIO_ACCESS_NETWORKS) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return Void();
+    }
+
+    RIL_NetworkScanRequest scan_request = {};
+
+    scan_request.type = (RIL_ScanType) request.type;
+    scan_request.interval = request.interval;
+    scan_request.specifiers_length = request.specifiers.size();
+    for (size_t i = 0; i < request.specifiers.size(); ++i) {
+        if (request.specifiers[i].geranBands.size() > MAX_BANDS ||
+            request.specifiers[i].utranBands.size() > MAX_BANDS ||
+            request.specifiers[i].eutranBands.size() > MAX_BANDS ||
+            request.specifiers[i].channels.size() > MAX_CHANNELS) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            return Void();
+        }
+        const ::android::hardware::radio::V1_1::RadioAccessSpecifier& ras_from =
+                request.specifiers[i];
+        RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i];
+
+        ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork;
+        ras_to.channels_length = ras_from.channels.size();
+
+        std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels);
+        const std::vector<uint32_t> * bands = nullptr;
+        switch (request.specifiers[i].radioAccessNetwork) {
+            case ::android::hardware::radio::V1_1::RadioAccessNetworks::GERAN:
+                ras_to.bands_length = ras_from.geranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.geranBands;
+                break;
+            case ::android::hardware::radio::V1_1::RadioAccessNetworks::UTRAN:
+                ras_to.bands_length = ras_from.utranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.utranBands;
+                break;
+            case ::android::hardware::radio::V1_1::RadioAccessNetworks::EUTRAN:
+                ras_to.bands_length = ras_from.eutranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.eutranBands;
+                break;
+            default:
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return Void();
+        }
+        // safe to copy to geran_bands because it's a union member
+        std::memcpy(&ras_to.bands.geran_bands, bands, ras_to.bands_length * sizeof(uint32_t));
+    }
+
+    s_vendorFunctions->onRequest(
+            RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI);
+
     return Void();
 }
 
@@ -1340,7 +1399,6 @@ Return<void> RadioImpl::stopNetworkScan(int32_t serial) {
 #if VDBG
     RLOGD("stopNetworkScan: serial %d", serial);
 #endif
-    // TODO(b/30954762): Add implementation to stop network scan.
     dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_NETWORK_SCAN);
     return Void();
 }
@@ -1932,8 +1990,19 @@ Return<void> RadioImpl::setInitialAttachApn(int32_t serial, const DataProfileInf
     if (s_vendorFunctions->version <= 14) {
         RIL_InitialAttachApn iaa = {};
 
-        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
-            return Void();
+        if (dataProfileInfo.apn.size() == 0) {
+            iaa.apn = (char *) calloc(1, sizeof(char));
+            if (iaa.apn == NULL) {
+                RLOGE("Memory allocation failed for request %s",
+                        requestToString(pRI->pCI->requestNumber));
+                sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+                return Void();
+            }
+            iaa.apn[0] = '\0';
+        } else {
+            if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
+                return Void();
+            }
         }
 
         const hidl_string &protocol =
@@ -1959,9 +2028,21 @@ Return<void> RadioImpl::setInitialAttachApn(int32_t serial, const DataProfileInf
     } else {
         RIL_InitialAttachApn_v15 iaa = {};
 
-        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
-            return Void();
+        if (dataProfileInfo.apn.size() == 0) {
+            iaa.apn = (char *) calloc(1, sizeof(char));
+            if (iaa.apn == NULL) {
+                RLOGE("Memory allocation failed for request %s",
+                        requestToString(pRI->pCI->requestNumber));
+                sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+                return Void();
+            }
+            iaa.apn[0] = '\0';
+        } else {
+            if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
+                return Void();
+            }
         }
+
         if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) {
             memsetAndFreeStrings(1, iaa.apn);
             return Void();
@@ -2459,7 +2540,6 @@ Return<void> RadioImpl::setDataProfile(int32_t serial, const hidl_vec<DataProfil
                     pRI)) {
                 success = false;
             }
-
             if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData,
                     profiles[i].mvnoMatchData, pRI)) {
                 success = false;
@@ -2744,13 +2824,42 @@ Return<void> OemHookImpl::sendRequestStrings(int32_t serial,
 }
 
 Return<void> RadioImpl::setCarrierInfoForImsiEncryption(int32_t serial,
-        const ::android::hardware::hidl_vec<uint8_t>& carrierKey,
-        const hidl_string& keyIdentifier) {
+        const ::android::hardware::radio::V1_1::ImsiEncryptionInfo& data) {
     RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial);
-    dispatchRaw(serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, carrierKey);
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION);
+    RIL_CarrierInfoForImsiEncryption imsiEncryption = {};
+
+    if (!copyHidlStringToRil(&imsiEncryption.mnc, data.mnc, pRI)) {
+        return Void();
+    }
+    if (!copyHidlStringToRil(&imsiEncryption.mcc, data.mcc, pRI)) {
+        memsetAndFreeStrings(1, imsiEncryption.mnc);
+        return Void();
+    }
+    if (!copyHidlStringToRil(&imsiEncryption.keyIdentifier, data.keyIdentifier, pRI)) {
+        memsetAndFreeStrings(2, imsiEncryption.mnc, imsiEncryption.mcc);
+        return Void();
+    }
+    int32_t lSize = data.carrierKey.size();
+    imsiEncryption.carrierKey = new uint8_t[lSize];
+    memcpy(imsiEncryption.carrierKey, data.carrierKey.data(), lSize);
+    imsiEncryption.expirationTime = data.expirationTime;
+    s_vendorFunctions->onRequest(pRI->pCI->requestNumber, &imsiEncryption, sizeof(RIL_CarrierInfoForImsiEncryption), pRI);
+    delete(imsiEncryption.carrierKey);
     return Void();
 }
 
+Return<void> RadioImpl::startKeepalive(int32_t serial, const KeepaliveRequest& keepalive) {
+    RLOGD("startKeepalive: serial %d", serial);
+    return Void();
+}
+
+Return<void> RadioImpl::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+    RLOGD("stopKeepalive: serial %d", serial);
+    return Void();
+}
+
+
 /***************************************************************************************************
  * RESPONSE FUNCTIONS
  * Functions above are used for requests going from framework to vendor code. The ones below are
@@ -2821,11 +2930,14 @@ int radio::getIccCardStatusResponse(int slotId,
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         CardStatus cardStatus = {};
-        if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6)) {
+        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+        if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6)
+                || p_cur->gsm_umts_subscription_app_index >= p_cur->num_applications
+                || p_cur->cdma_subscription_app_index >= p_cur->num_applications
+                || p_cur->ims_subscription_app_index >= p_cur->num_applications) {
             RLOGE("getIccCardStatusResponse: Invalid response");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
-            RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
             cardStatus.cardState = (CardState) p_cur->card_state;
             cardStatus.universalPinState = (PinState) p_cur->universal_pin_state;
             cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index;
@@ -3021,7 +3133,8 @@ int radio::getCurrentCallsResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         hidl_vec<Call> calls;
-        if (response == NULL || (responseLen % sizeof(RIL_Call *)) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || (responseLen % sizeof(RIL_Call *)) != 0) {
             RLOGE("getCurrentCallsResponse: Invalid response");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -3437,6 +3550,20 @@ int convertResponseStringEntryToInt(char **response, int index, int numStrings)
     return -1;
 }
 
+int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) {
+    const int hexBase = 16;
+    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
+        return strtol(response[index], NULL, hexBase);
+    }
+
+    return -1;
+}
+
+/* Fill Cell Identity info from Voice Registration State Response.
+ * This fucntion is applicable only for RIL Version < 15.
+ * Response is a  "char **".
+ * First and Second entries are in hex string format
+ * and rest are integers represented in ascii format. */
 void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
         int numStrings, char** response) {
 
@@ -3447,28 +3574,37 @@ void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
     switch(rilCellIdentity.cellInfoType) {
 
         case RIL_CELL_INFO_TYPE_GSM: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityGsm.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityGsm.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
 
         case RIL_CELL_INFO_TYPE_WCDMA: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityWcdma.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityWcdma.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             rilCellIdentity.cellIdentityWcdma.psc =
                     convertResponseStringEntryToInt(response, 14, numStrings);
             break;
         }
 
         case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityTdscdma.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityTdscdma.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
 
@@ -3487,10 +3623,13 @@ void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
         }
 
         case RIL_CELL_INFO_TYPE_LTE:{
+            /* valid TAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityLte.tac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityLte.ci =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
 
@@ -3502,6 +3641,11 @@ void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
     fillCellIdentityResponse(cellIdentity, rilCellIdentity);
 }
 
+/* Fill Cell Identity info from Data Registration State Response.
+ * This fucntion is applicable only for RIL Version < 15.
+ * Response is a  "char **".
+ * First and Second entries are in hex string format
+ * and rest are integers represented in ascii format. */
 void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity,
         int numStrings, char** response) {
 
@@ -3511,24 +3655,33 @@ void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity,
     rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
     switch(rilCellIdentity.cellInfoType) {
         case RIL_CELL_INFO_TYPE_GSM: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityGsm.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityGsm.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
         case RIL_CELL_INFO_TYPE_WCDMA: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityWcdma.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityWcdma.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
         case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
             rilCellIdentity.cellIdentityTdscdma.lac =
-                    convertResponseStringEntryToInt(response, 1, numStrings);
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
             rilCellIdentity.cellIdentityTdscdma.cid =
-                    convertResponseStringEntryToInt(response, 2, numStrings);
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
             break;
         }
         case RIL_CELL_INFO_TYPE_LTE: {
@@ -3817,9 +3970,11 @@ int radio::setupDataCallResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         SetupDataCallResult result = {};
-        if (response == NULL || responseLen != sizeof(RIL_Data_Call_Response_v11)) {
-            RLOGE("setupDataCallResponse: Invalid response");
-            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) {
+            if (response != NULL) {
+                RLOGE("setupDataCallResponse: Invalid response");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
             result.status = DataCallFailCause::ERROR_UNSPECIFIED;
             result.type = hidl_string();
             result.ifname = hidl_string();
@@ -3985,7 +4140,8 @@ int radio::getCallForwardStatusResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<CallForwardInfo> callForwardInfos;
 
-        if (response == NULL || responseLen % sizeof(RIL_CallForwardInfo *) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CallForwardInfo *) != 0) {
             RLOGE("getCallForwardStatusResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -4313,7 +4469,8 @@ int radio::getAvailableNetworksResponse(int slotId,
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<OperatorInfo> networks;
-        if (response == NULL || responseLen % (4 * sizeof(char *))!= 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % (4 * sizeof(char *))!= 0) {
             RLOGE("getAvailableNetworksResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -4344,24 +4501,6 @@ int radio::getAvailableNetworksResponse(int slotId,
     return 0;
 }
 
-int radio::startNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
-                                    void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("startNetworkScanResponse: serial %d", serial);
-#endif
-    // TODO(b/30954762): Add implementation to generate startNetworkScanResponse.
-    return 0;
-}
-
-int radio::stopNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
-                                   void *response, size_t responseLen) {
-#if VDBG
-    RLOGD("stopNetworkScanResponse: serial %d", serial);
-#endif
-    // TODO(b/30954762): Add implementation to generate stopNetworkScanResponse.
-    return 0;
-}
-
 int radio::startDtmfResponse(int slotId,
                             int responseType, int serial, RIL_Errno e,
                             void *response, size_t responseLen) {
@@ -4525,7 +4664,8 @@ int radio::getDataCallListResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         hidl_vec<SetupDataCallResult> ret;
-        if (response == NULL || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
             RLOGE("getDataCallListResponse: invalid response");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -4635,7 +4775,7 @@ int radio::getAvailableBandModesResponse(int slotId,
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<RadioBandMode> modes;
-        if (response == NULL || responseLen % sizeof(int) != 0) {
+        if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) {
             RLOGE("getAvailableBandModesResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -4802,7 +4942,8 @@ int radio::getNeighboringCidsResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<NeighboringCell> cells;
 
-        if (response == NULL || responseLen % sizeof(RIL_NeighboringCell *) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_NeighboringCell *) != 0) {
             RLOGE("getNeighboringCidsResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -5105,7 +5246,8 @@ int radio::getGsmBroadcastConfigResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<GsmBroadcastSmsConfigInfo> configs;
 
-        if (response == NULL || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) {
             RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -5189,7 +5331,8 @@ int radio::getCdmaBroadcastConfigResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<CdmaBroadcastSmsConfigInfo> configs;
 
-        if (response == NULL || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) {
             RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -5610,7 +5753,8 @@ int radio::getCellInfoListResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         hidl_vec<CellInfo> ret;
-        if (response == NULL || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
             RLOGE("getCellInfoListResponse: Invalid response");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -5764,7 +5908,9 @@ int radio::iccOpenLogicalChannelResponse(int slotId,
         int numInts = responseLen / sizeof(int);
         if (response == NULL || responseLen % sizeof(int) != 0) {
             RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL");
-            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            if (response != NULL) {
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
         } else {
             int *pInt = (int *) response;
             channelId = pInt[0];
@@ -5965,7 +6111,8 @@ int radio::getHardwareConfigResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         hidl_vec<HardwareConfig> result;
-        if (response == NULL || responseLen % sizeof(RIL_HardwareConfig) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
             RLOGE("hardwareConfigChangedInd: invalid response");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -6411,6 +6558,58 @@ int radio::setSimCardPowerResponse(int slotId,
     return 0;
 }
 
+int radio::startNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("startNetworkScanResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<sp<::android::hardware::radio::V1_1::IRadioResponse>> ret =
+                ::android::hardware::radio::V1_1::IRadioResponse::castFrom(
+                        radioService[slotId]->mRadioResponse);
+        if (ret.isOk()) {
+            sp<::android::hardware::radio::V1_1::IRadioResponse> radioResponseV1_1 = ret;
+            Return<void> retStatus = radioResponseV1_1->startNetworkScanResponse(responseInfo);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGD("startNetworkScanResponse: ret.isOK() == false for radioService[%d]", slotId);
+        }
+    } else {
+        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio::stopNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("stopNetworkScanResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<sp<::android::hardware::radio::V1_1::IRadioResponse>> ret =
+                ::android::hardware::radio::V1_1::IRadioResponse::castFrom(
+                        radioService[slotId]->mRadioResponse);
+        if (ret.isOk()) {
+            sp<::android::hardware::radio::V1_1::IRadioResponse> radioResponseV1_1 = ret;
+            Return<void> retStatus = radioResponseV1_1->stopNetworkScanResponse(responseInfo);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGD("stopNetworkScanResponse: ret.isOK() == false for radioService[%d]", slotId);
+        }
+    } else {
+        RLOGE("stopNetworkScanResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
 int radio::sendRequestRawResponse(int slotId,
                                   int responseType, int serial, RIL_Errno e,
                                   void *response, size_t responseLen) {
@@ -6452,7 +6651,7 @@ int radio::sendRequestStringsResponse(int slotId,
         populateResponseInfo(responseInfo, serial, responseType, e);
         hidl_vec<hidl_string> data;
 
-        if (response == NULL || responseLen % sizeof(char *) != 0) {
+        if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) {
             RLOGE("sendRequestStringsResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
         } else {
@@ -6800,7 +6999,8 @@ int radio::dataCallListChangedInd(int slotId,
                                   int indicationType, int token, RIL_Errno e, void *response,
                                   size_t responseLen) {
     if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
-        if (response == NULL || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
             RLOGE("dataCallListChangedInd: invalid response");
             return 0;
         }
@@ -7683,7 +7883,7 @@ int radio::cellInfoListInd(int slotId,
                            int indicationType, int token, RIL_Errno e, void *response,
                            size_t responseLen) {
     if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
-        if (response == NULL || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
+        if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
             RLOGE("cellInfoListInd: invalid response");
             return 0;
         }
@@ -7804,7 +8004,8 @@ int radio::hardwareConfigChangedInd(int slotId,
                                     int indicationType, int token, RIL_Errno e, void *response,
                                     size_t responseLen) {
     if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
-        if (response == NULL || responseLen % sizeof(RIL_HardwareConfig) != 0) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
             RLOGE("hardwareConfigChangedInd: invalid response");
             return 0;
         }
@@ -8061,11 +8262,46 @@ int radio::modemResetInd(int slotId,
 
 int radio::networkScanResultInd(int slotId,
                                 int indicationType, int token, RIL_Errno e, void *response,
-                                size_t responselen) {
+                                size_t responseLen) {
 #if VDBG
     RLOGD("networkScanResultInd");
 #endif
-    // TODO(b/30954762): Add implementation for networkScanResultInd.
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("networkScanResultInd: invalid response");
+            return 0;
+        }
+        RLOGD("networkScanResultInd");
+
+#if VDBG
+        RLOGD("networkScanResultInd");
+#endif
+
+        Return<sp<::android::hardware::radio::V1_1::IRadioIndication>> ret =
+            ::android::hardware::radio::V1_1::IRadioIndication::castFrom(
+            radioService[slotId]->mRadioIndication);
+        if (ret.isOk()) {
+            RIL_NetworkScanResult *networkScanResult = (RIL_NetworkScanResult *) response;
+
+            ::android::hardware::radio::V1_1::NetworkScanResult result;
+            result.status =
+                    (::android::hardware::radio::V1_1::ScanStatus) networkScanResult->status;
+            result.error = (RadioError) e;
+            convertRilCellInfoListToHal(
+                    networkScanResult->network_infos,
+                    networkScanResult->network_infos_length * sizeof(RIL_CellInfo_v12),
+                    result.networkInfos);
+
+            sp<::android::hardware::radio::V1_1::IRadioIndication> radioIndicationV1_1 = ret;
+            Return<void> retStatus = radioIndicationV1_1->networkScanResult(
+                    convertIntToRadioIndicationType(indicationType), result);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGE("networkScanResultInd: ret.isOk() == false for radioService[%d]", slotId);
+        }
+    } else {
+        RLOGE("networkScanResultInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
     return 0;
 }