From 8688abd15e76c8c8adbd6b2136a813536bb1de8d Mon Sep 17 00:00:00 2001 From: yinxu Date: Mon, 22 May 2017 11:26:45 -0700 Subject: Implement the new network scan RIL API. Test: Telephony sanity tests Bug: 30954762 Change-Id: I3a4b7f7b642b266fb2c6f75bc3c7fd947dfe6ad0 --- include/telephony/ril.h | 12 +++- libril/ril_service.cpp | 169 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 155 insertions(+), 26 deletions(-) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 4f0dee0..23d06d0 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -2138,16 +2138,22 @@ typedef enum { typedef struct { RIL_RadioAccessNetworks radio_access_network; // The type of network to scan. + uint32_t bands_length; // Length of bands union { RIL_GeranBands geran_bands[MAX_BANDS]; RIL_UtranBands utran_bands[MAX_BANDS]; RIL_EutranBands eutran_bands[MAX_BANDS]; } bands; + uint32_t channels_length; // Length of channels uint32_t channels[MAX_CHANNELS]; // Frequency channels to scan } RIL_RadioAccessSpecifier; typedef struct { RIL_ScanType type; // Type of the scan + int32_t interval; // Time interval in seconds + // between periodic scans, only + // valid when type=RIL_PERIODIC + uint32_t specifiers_length; // Length of specifiers RIL_RadioAccessSpecifier specifiers[MAX_RADIO_ACCESS_NETWORKS]; // Radio access networks // with bands/channels. } RIL_NetworkScanRequest; @@ -2158,9 +2164,9 @@ typedef enum { } RIL_ScanStatus; typedef struct { - RIL_ScanStatus status; // The status of the scan - uint32_t network_infos_length; // Total length of RIL_CellInfo - RIL_CellInfo* network_infos; // List of network information + RIL_ScanStatus status; // The status of the scan + uint32_t network_infos_length; // Total length of RIL_CellInfo + RIL_CellInfo_v12* network_infos; // List of network information } RIL_NetworkScanResult; /** diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp index ea85054..cb4fb5c 100644 --- a/libril/ril_service.cpp +++ b/libril/ril_service.cpp @@ -1322,8 +1322,63 @@ Return 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 * 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 *) &ras_from.geranBands; + break; + case ::android::hardware::radio::V1_1::RadioAccessNetworks::UTRAN: + ras_to.bands_length = ras_from.utranBands.size(); + bands = (std::vector *) &ras_from.utranBands; + break; + case ::android::hardware::radio::V1_1::RadioAccessNetworks::EUTRAN: + ras_to.bands_length = ras_from.eutranBands.size(); + bands = (std::vector *) &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(); } @@ -1331,7 +1386,6 @@ Return 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(); } @@ -4334,24 +4388,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) { @@ -6401,6 +6437,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> 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 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> 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 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) { @@ -8050,11 +8138,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> 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 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; } -- cgit v1.2.3