| /* |
| * Copyright (c) 2016 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. |
| */ |
| |
| #define LOG_TAG "RILC" |
| |
| #include <android/hardware/radio/1.1/IRadio.h> |
| #include <android/hardware/radio/1.1/IRadioResponse.h> |
| #include <android/hardware/radio/1.1/IRadioIndication.h> |
| #include <android/hardware/radio/1.1/types.h> |
| |
| #include <hwbinder/IPCThreadState.h> |
| #include <hwbinder/ProcessState.h> |
| #include <telephony/ril.h> |
| #include <telephony/ril_mnc.h> |
| #include <telephony/ril_mcc.h> |
| #include <ril_service.h> |
| #include <hidl/HidlTransportSupport.h> |
| #include <utils/SystemClock.h> |
| #include <inttypes.h> |
| |
| #define INVALID_HEX_CHAR 16 |
| |
| using namespace android::hardware::radio; |
| using namespace android::hardware::radio::V1_0; |
| using ::android::hardware::configureRpcThreadpool; |
| using ::android::hardware::joinRpcThreadpool; |
| using ::android::hardware::Return; |
| using ::android::hardware::hidl_string; |
| using ::android::hardware::hidl_vec; |
| using ::android::hardware::hidl_array; |
| using ::android::hardware::Void; |
| using android::CommandInfo; |
| using android::RequestInfo; |
| using android::requestToString; |
| using android::sp; |
| |
| #define BOOL_TO_INT(x) (x ? 1 : 0) |
| #define ATOI_NULL_HANDLED(x) (x ? atoi(x) : -1) |
| #define ATOI_NULL_HANDLED_DEF(x, defaultVal) (x ? atoi(x) : defaultVal) |
| |
| #if defined(ANDROID_MULTI_SIM) |
| #define CALL_ONREQUEST(a, b, c, d, e) \ |
| s_vendorFunctions->onRequest((a), (b), (c), (d), ((RIL_SOCKET_ID)(e))) |
| #define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest((RIL_SOCKET_ID)(a)) |
| #else |
| #define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d)) |
| #define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest() |
| #endif |
| |
| RIL_RadioFunctions *s_vendorFunctions = NULL; |
| static CommandInfo *s_commands; |
| |
| struct RadioImpl; |
| |
| #if (SIM_COUNT >= 2) |
| sp<RadioImpl> radioService[SIM_COUNT]; |
| int64_t nitzTimeReceived[SIM_COUNT]; |
| // counter used for synchronization. It is incremented every time response callbacks are updated. |
| volatile int32_t mCounterRadio[SIM_COUNT]; |
| #else |
| sp<RadioImpl> radioService[1]; |
| int64_t nitzTimeReceived[1]; |
| // counter used for synchronization. It is incremented every time response callbacks are updated. |
| volatile int32_t mCounterRadio[1]; |
| #endif |
| |
| static pthread_rwlock_t radioServiceRwlock = PTHREAD_RWLOCK_INITIALIZER; |
| |
| #if (SIM_COUNT >= 2) |
| static pthread_rwlock_t radioServiceRwlock2 = PTHREAD_RWLOCK_INITIALIZER; |
| #if (SIM_COUNT >= 3) |
| static pthread_rwlock_t radioServiceRwlock3 = PTHREAD_RWLOCK_INITIALIZER; |
| #if (SIM_COUNT >= 4) |
| static pthread_rwlock_t radioServiceRwlock4 = PTHREAD_RWLOCK_INITIALIZER; |
| #endif |
| #endif |
| #endif |
| |
| void convertRilHardwareConfigListToHal(void *response, size_t responseLen, |
| hidl_vec<HardwareConfig>& records); |
| |
| void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc); |
| |
| void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce); |
| |
| void convertRilSignalStrengthToHal(void *response, size_t responseLen, |
| SignalStrength& signalStrength); |
| |
| void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, |
| SetupDataCallResult& dcResult); |
| |
| void convertRilDataCallListToHal(void *response, size_t responseLen, |
| hidl_vec<SetupDataCallResult>& dcResultList); |
| |
| void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records); |
| |
| struct RadioImpl : public V1_1::IRadio { |
| int32_t mSlotId; |
| sp<IRadioResponse> mRadioResponse; |
| sp<IRadioIndication> mRadioIndication; |
| sp<V1_1::IRadioResponse> mRadioResponseV1_1; |
| sp<V1_1::IRadioIndication> mRadioIndicationV1_1; |
| |
| Return<void> setResponseFunctions( |
| const ::android::sp<IRadioResponse>& radioResponse, |
| const ::android::sp<IRadioIndication>& radioIndication); |
| |
| Return<void> getIccCardStatus(int32_t serial); |
| |
| Return<void> supplyIccPinForApp(int32_t serial, const hidl_string& pin, |
| const hidl_string& aid); |
| |
| Return<void> supplyIccPukForApp(int32_t serial, const hidl_string& puk, |
| const hidl_string& pin, const hidl_string& aid); |
| |
| Return<void> supplyIccPin2ForApp(int32_t serial, |
| const hidl_string& pin2, |
| const hidl_string& aid); |
| |
| Return<void> supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, |
| const hidl_string& pin2, const hidl_string& aid); |
| |
| Return<void> changeIccPinForApp(int32_t serial, const hidl_string& oldPin, |
| const hidl_string& newPin, const hidl_string& aid); |
| |
| Return<void> changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, |
| const hidl_string& newPin2, const hidl_string& aid); |
| |
| Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin); |
| |
| Return<void> getCurrentCalls(int32_t serial); |
| |
| Return<void> dial(int32_t serial, const Dial& dialInfo); |
| |
| Return<void> getImsiForApp(int32_t serial, |
| const ::android::hardware::hidl_string& aid); |
| |
| Return<void> hangup(int32_t serial, int32_t gsmIndex); |
| |
| Return<void> hangupWaitingOrBackground(int32_t serial); |
| |
| Return<void> hangupForegroundResumeBackground(int32_t serial); |
| |
| Return<void> switchWaitingOrHoldingAndActive(int32_t serial); |
| |
| Return<void> conference(int32_t serial); |
| |
| Return<void> rejectCall(int32_t serial); |
| |
| Return<void> getLastCallFailCause(int32_t serial); |
| |
| Return<void> getSignalStrength(int32_t serial); |
| |
| Return<void> getVoiceRegistrationState(int32_t serial); |
| |
| Return<void> getDataRegistrationState(int32_t serial); |
| |
| Return<void> getOperator(int32_t serial); |
| |
| Return<void> setRadioPower(int32_t serial, bool on); |
| |
| Return<void> sendDtmf(int32_t serial, |
| const ::android::hardware::hidl_string& s); |
| |
| Return<void> sendSms(int32_t serial, const GsmSmsMessage& message); |
| |
| Return<void> sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message); |
| |
| Return<void> setupDataCall(int32_t serial, |
| RadioTechnology radioTechnology, |
| const DataProfileInfo& profileInfo, |
| bool modemCognitive, |
| bool roamingAllowed, |
| bool isRoaming); |
| |
| Return<void> iccIOForApp(int32_t serial, |
| const IccIo& iccIo); |
| |
| Return<void> sendUssd(int32_t serial, |
| const ::android::hardware::hidl_string& ussd); |
| |
| Return<void> cancelPendingUssd(int32_t serial); |
| |
| Return<void> getClir(int32_t serial); |
| |
| Return<void> setClir(int32_t serial, int32_t status); |
| |
| Return<void> getCallForwardStatus(int32_t serial, |
| const CallForwardInfo& callInfo); |
| |
| Return<void> setCallForward(int32_t serial, |
| const CallForwardInfo& callInfo); |
| |
| Return<void> getCallWaiting(int32_t serial, int32_t serviceClass); |
| |
| Return<void> setCallWaiting(int32_t serial, bool enable, int32_t serviceClass); |
| |
| Return<void> acknowledgeLastIncomingGsmSms(int32_t serial, |
| bool success, SmsAcknowledgeFailCause cause); |
| |
| Return<void> acceptCall(int32_t serial); |
| |
| Return<void> deactivateDataCall(int32_t serial, |
| int32_t cid, bool reasonRadioShutDown); |
| |
| Return<void> getFacilityLockForApp(int32_t serial, |
| const ::android::hardware::hidl_string& facility, |
| const ::android::hardware::hidl_string& password, |
| int32_t serviceClass, |
| const ::android::hardware::hidl_string& appId); |
| |
| Return<void> setFacilityLockForApp(int32_t serial, |
| const ::android::hardware::hidl_string& facility, |
| bool lockState, |
| const ::android::hardware::hidl_string& password, |
| int32_t serviceClass, |
| const ::android::hardware::hidl_string& appId); |
| |
| Return<void> setBarringPassword(int32_t serial, |
| const ::android::hardware::hidl_string& facility, |
| const ::android::hardware::hidl_string& oldPassword, |
| const ::android::hardware::hidl_string& newPassword); |
| |
| Return<void> getNetworkSelectionMode(int32_t serial); |
| |
| Return<void> setNetworkSelectionModeAutomatic(int32_t serial); |
| |
| Return<void> setNetworkSelectionModeManual(int32_t serial, |
| const ::android::hardware::hidl_string& operatorNumeric); |
| |
| Return<void> getAvailableNetworks(int32_t serial); |
| |
| Return<void> startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request); |
| |
| Return<void> stopNetworkScan(int32_t serial); |
| |
| Return<void> startDtmf(int32_t serial, |
| const ::android::hardware::hidl_string& s); |
| |
| Return<void> stopDtmf(int32_t serial); |
| |
| Return<void> getBasebandVersion(int32_t serial); |
| |
| Return<void> separateConnection(int32_t serial, int32_t gsmIndex); |
| |
| Return<void> setMute(int32_t serial, bool enable); |
| |
| Return<void> getMute(int32_t serial); |
| |
| Return<void> getClip(int32_t serial); |
| |
| Return<void> getDataCallList(int32_t serial); |
| |
| Return<void> setSuppServiceNotifications(int32_t serial, bool enable); |
| |
| Return<void> writeSmsToSim(int32_t serial, |
| const SmsWriteArgs& smsWriteArgs); |
| |
| Return<void> deleteSmsOnSim(int32_t serial, int32_t index); |
| |
| Return<void> setBandMode(int32_t serial, RadioBandMode mode); |
| |
| Return<void> getAvailableBandModes(int32_t serial); |
| |
| Return<void> sendEnvelope(int32_t serial, |
| const ::android::hardware::hidl_string& command); |
| |
| Return<void> sendTerminalResponseToSim(int32_t serial, |
| const ::android::hardware::hidl_string& commandResponse); |
| |
| Return<void> handleStkCallSetupRequestFromSim(int32_t serial, bool accept); |
| |
| Return<void> explicitCallTransfer(int32_t serial); |
| |
| Return<void> setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType); |
| |
| Return<void> getPreferredNetworkType(int32_t serial); |
| |
| Return<void> getNeighboringCids(int32_t serial); |
| |
| Return<void> setLocationUpdates(int32_t serial, bool enable); |
| |
| Return<void> setCdmaSubscriptionSource(int32_t serial, |
| CdmaSubscriptionSource cdmaSub); |
| |
| Return<void> setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type); |
| |
| Return<void> getCdmaRoamingPreference(int32_t serial); |
| |
| Return<void> setTTYMode(int32_t serial, TtyMode mode); |
| |
| Return<void> getTTYMode(int32_t serial); |
| |
| Return<void> setPreferredVoicePrivacy(int32_t serial, bool enable); |
| |
| Return<void> getPreferredVoicePrivacy(int32_t serial); |
| |
| Return<void> sendCDMAFeatureCode(int32_t serial, |
| const ::android::hardware::hidl_string& featureCode); |
| |
| Return<void> sendBurstDtmf(int32_t serial, |
| const ::android::hardware::hidl_string& dtmf, |
| int32_t on, |
| int32_t off); |
| |
| Return<void> sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms); |
| |
| Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial, |
| const CdmaSmsAck& smsAck); |
| |
| Return<void> getGsmBroadcastConfig(int32_t serial); |
| |
| Return<void> setGsmBroadcastConfig(int32_t serial, |
| const hidl_vec<GsmBroadcastSmsConfigInfo>& configInfo); |
| |
| Return<void> setGsmBroadcastActivation(int32_t serial, bool activate); |
| |
| Return<void> getCdmaBroadcastConfig(int32_t serial); |
| |
| Return<void> setCdmaBroadcastConfig(int32_t serial, |
| const hidl_vec<CdmaBroadcastSmsConfigInfo>& configInfo); |
| |
| Return<void> setCdmaBroadcastActivation(int32_t serial, bool activate); |
| |
| Return<void> getCDMASubscription(int32_t serial); |
| |
| Return<void> writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms); |
| |
| Return<void> deleteSmsOnRuim(int32_t serial, int32_t index); |
| |
| Return<void> getDeviceIdentity(int32_t serial); |
| |
| Return<void> exitEmergencyCallbackMode(int32_t serial); |
| |
| Return<void> getSmscAddress(int32_t serial); |
| |
| Return<void> setSmscAddress(int32_t serial, |
| const ::android::hardware::hidl_string& smsc); |
| |
| Return<void> reportSmsMemoryStatus(int32_t serial, bool available); |
| |
| Return<void> reportStkServiceIsRunning(int32_t serial); |
| |
| Return<void> getCdmaSubscriptionSource(int32_t serial); |
| |
| Return<void> requestIsimAuthentication(int32_t serial, |
| const ::android::hardware::hidl_string& challenge); |
| |
| Return<void> acknowledgeIncomingGsmSmsWithPdu(int32_t serial, |
| bool success, |
| const ::android::hardware::hidl_string& ackPdu); |
| |
| Return<void> sendEnvelopeWithStatus(int32_t serial, |
| const ::android::hardware::hidl_string& contents); |
| |
| Return<void> getVoiceRadioTechnology(int32_t serial); |
| |
| Return<void> getCellInfoList(int32_t serial); |
| |
| Return<void> setCellInfoListRate(int32_t serial, int32_t rate); |
| |
| Return<void> setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, |
| bool modemCognitive, bool isRoaming); |
| |
| Return<void> getImsRegistrationState(int32_t serial); |
| |
| Return<void> sendImsSms(int32_t serial, const ImsSmsMessage& message); |
| |
| Return<void> iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message); |
| |
| Return<void> iccOpenLogicalChannel(int32_t serial, |
| const ::android::hardware::hidl_string& aid, int32_t p2); |
| |
| Return<void> iccCloseLogicalChannel(int32_t serial, int32_t channelId); |
| |
| Return<void> iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message); |
| |
| Return<void> nvReadItem(int32_t serial, NvItem itemId); |
| |
| Return<void> nvWriteItem(int32_t serial, const NvWriteItem& item); |
| |
| Return<void> nvWriteCdmaPrl(int32_t serial, |
| const ::android::hardware::hidl_vec<uint8_t>& prl); |
| |
| Return<void> nvResetConfig(int32_t serial, ResetNvType resetType); |
| |
| Return<void> setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub); |
| |
| Return<void> setDataAllowed(int32_t serial, bool allow); |
| |
| Return<void> getHardwareConfig(int32_t serial); |
| |
| Return<void> requestIccSimAuthentication(int32_t serial, |
| int32_t authContext, |
| const ::android::hardware::hidl_string& authData, |
| const ::android::hardware::hidl_string& aid); |
| |
| Return<void> setDataProfile(int32_t serial, |
| const ::android::hardware::hidl_vec<DataProfileInfo>& profiles, bool isRoaming); |
| |
| Return<void> requestShutdown(int32_t serial); |
| |
| Return<void> getRadioCapability(int32_t serial); |
| |
| Return<void> setRadioCapability(int32_t serial, const RadioCapability& rc); |
| |
| Return<void> startLceService(int32_t serial, int32_t reportInterval, bool pullMode); |
| |
| Return<void> stopLceService(int32_t serial); |
| |
| Return<void> pullLceData(int32_t serial); |
| |
| Return<void> getModemActivityInfo(int32_t serial); |
| |
| Return<void> setAllowedCarriers(int32_t serial, |
| bool allAllowed, |
| const CarrierRestrictions& carriers); |
| |
| Return<void> getAllowedCarriers(int32_t serial); |
| |
| Return<void> sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state); |
| |
| Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter); |
| |
| Return<void> startKeepalive(int32_t serial, const V1_1::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 V1_1::CardPowerState state); |
| |
| Return<void> responseAcknowledgement(); |
| |
| Return<void> setCarrierInfoForImsiEncryption(int32_t serial, |
| const V1_1::ImsiEncryptionInfo& message); |
| |
| void checkReturnStatus(Return<void>& ret); |
| }; |
| |
| void memsetAndFreeStrings(int numPointers, ...) { |
| va_list ap; |
| va_start(ap, numPointers); |
| for (int i = 0; i < numPointers; i++) { |
| char *ptr = va_arg(ap, char *); |
| if (ptr) { |
| #ifdef MEMSET_FREED |
| #define MAX_STRING_LENGTH 4096 |
| memset(ptr, 0, strnlen(ptr, MAX_STRING_LENGTH)); |
| #endif |
| free(ptr); |
| } |
| } |
| va_end(ap); |
| } |
| |
| void sendErrorResponse(RequestInfo *pRI, RIL_Errno err) { |
| pRI->pCI->responseFunction((int) pRI->socket_id, |
| (int) RadioResponseType::SOLICITED, pRI->token, err, NULL, 0); |
| } |
| |
| /** |
| * Copies over src to dest. If memory allocation fails, responseFunction() is called for the |
| * request with error RIL_E_NO_MEMORY. The size() method is used to determine the size of the |
| * destination buffer into which the HIDL string is copied. If there is a discrepancy between |
| * the string length reported by the size() method, and the length of the string returned by |
| * the c_str() method, the function will return false indicating a failure. |
| * |
| * Returns true on success, and false on failure. |
| */ |
| bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI, bool allowEmpty) { |
| size_t len = src.size(); |
| if (len == 0 && !allowEmpty) { |
| *dest = NULL; |
| return true; |
| } |
| *dest = (char *) calloc(len + 1, sizeof(char)); |
| if (*dest == NULL) { |
| RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return false; |
| } |
| if (strlcpy(*dest, src.c_str(), len + 1) >= (len + 1)) { |
| RLOGE("Copy of the HIDL string has been truncated, as " |
| "the string length reported by size() does not " |
| "match the length of string returned by c_str()."); |
| free(*dest); |
| *dest = NULL; |
| sendErrorResponse(pRI, RIL_E_INTERNAL_ERR); |
| return false; |
| } |
| return true; |
| } |
| |
| bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) { |
| return copyHidlStringToRil(dest, src, pRI, false); |
| } |
| |
| hidl_string convertCharPtrToHidlString(const char *ptr) { |
| hidl_string ret; |
| if (ptr != NULL) { |
| // TODO: replace this with strnlen |
| ret.setToExternal(ptr, strlen(ptr)); |
| } |
| return ret; |
| } |
| |
| bool dispatchVoid(int serial, int slotId, int request) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| CALL_ONREQUEST(request, NULL, 0, pRI, slotId); |
| return true; |
| } |
| |
| bool dispatchString(int serial, int slotId, int request, const char * str) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| char *pString; |
| if (!copyHidlStringToRil(&pString, str, pRI)) { |
| return false; |
| } |
| |
| CALL_ONREQUEST(request, pString, sizeof(char *), pRI, slotId); |
| |
| memsetAndFreeStrings(1, pString); |
| return true; |
| } |
| |
| bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty, int countStrings, ...) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| char **pStrings; |
| pStrings = (char **)calloc(countStrings, sizeof(char *)); |
| if (pStrings == NULL) { |
| RLOGE("Memory allocation failed for request %s", requestToString(request)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return false; |
| } |
| va_list ap; |
| va_start(ap, countStrings); |
| for (int i = 0; i < countStrings; i++) { |
| const char* str = va_arg(ap, const char *); |
| if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI, allowEmpty)) { |
| va_end(ap); |
| for (int j = 0; j < i; j++) { |
| memsetAndFreeStrings(1, pStrings[j]); |
| } |
| free(pStrings); |
| return false; |
| } |
| } |
| va_end(ap); |
| |
| CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); |
| |
| if (pStrings != NULL) { |
| for (int i = 0 ; i < countStrings ; i++) { |
| memsetAndFreeStrings(1, pStrings[i]); |
| } |
| |
| #ifdef MEMSET_FREED |
| memset(pStrings, 0, countStrings * sizeof(char *)); |
| #endif |
| free(pStrings); |
| } |
| return true; |
| } |
| |
| bool dispatchStrings(int serial, int slotId, int request, const hidl_vec<hidl_string>& data) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| int countStrings = data.size(); |
| char **pStrings; |
| pStrings = (char **)calloc(countStrings, sizeof(char *)); |
| if (pStrings == NULL) { |
| RLOGE("Memory allocation failed for request %s", requestToString(request)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return false; |
| } |
| |
| for (int i = 0; i < countStrings; i++) { |
| if (!copyHidlStringToRil(&pStrings[i], data[i], pRI)) { |
| for (int j = 0; j < i; j++) { |
| memsetAndFreeStrings(1, pStrings[j]); |
| } |
| free(pStrings); |
| return false; |
| } |
| } |
| |
| CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId); |
| |
| if (pStrings != NULL) { |
| for (int i = 0 ; i < countStrings ; i++) { |
| memsetAndFreeStrings(1, pStrings[i]); |
| } |
| |
| #ifdef MEMSET_FREED |
| memset(pStrings, 0, countStrings * sizeof(char *)); |
| #endif |
| free(pStrings); |
| } |
| return true; |
| } |
| |
| bool dispatchInts(int serial, int slotId, int request, int countInts, ...) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| int *pInts = (int *)calloc(countInts, sizeof(int)); |
| |
| if (pInts == NULL) { |
| RLOGE("Memory allocation failed for request %s", requestToString(request)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return false; |
| } |
| va_list ap; |
| va_start(ap, countInts); |
| for (int i = 0; i < countInts; i++) { |
| pInts[i] = va_arg(ap, int); |
| } |
| va_end(ap); |
| |
| CALL_ONREQUEST(request, pInts, countInts * sizeof(int), pRI, slotId); |
| |
| if (pInts != NULL) { |
| #ifdef MEMSET_FREED |
| memset(pInts, 0, countInts * sizeof(int)); |
| #endif |
| free(pInts); |
| } |
| return true; |
| } |
| |
| bool dispatchCallForwardStatus(int serial, int slotId, int request, |
| const CallForwardInfo& callInfo) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| RIL_CallForwardInfo cf; |
| cf.status = (int) callInfo.status; |
| cf.reason = callInfo.reason; |
| cf.serviceClass = callInfo.serviceClass; |
| cf.toa = callInfo.toa; |
| cf.timeSeconds = callInfo.timeSeconds; |
| |
| if (!copyHidlStringToRil(&cf.number, callInfo.number, pRI)) { |
| return false; |
| } |
| |
| CALL_ONREQUEST(request, &cf, sizeof(cf), pRI, slotId); |
| |
| memsetAndFreeStrings(1, cf.number); |
| |
| return true; |
| } |
| |
| bool dispatchRaw(int serial, int slotId, int request, const hidl_vec<uint8_t>& rawBytes) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| const uint8_t *uData = rawBytes.data(); |
| |
| CALL_ONREQUEST(request, (void *) uData, rawBytes.size(), pRI, slotId); |
| |
| return true; |
| } |
| |
| bool dispatchIccApdu(int serial, int slotId, int request, const SimApdu& message) { |
| RequestInfo *pRI = android::addRequestToList(serial, slotId, request); |
| if (pRI == NULL) { |
| return false; |
| } |
| |
| RIL_SIM_APDU apdu = {}; |
| |
| apdu.sessionid = message.sessionId; |
| apdu.cla = message.cla; |
| apdu.instruction = message.instruction; |
| apdu.p1 = message.p1; |
| apdu.p2 = message.p2; |
| apdu.p3 = message.p3; |
| |
| if (!copyHidlStringToRil(&apdu.data, message.data, pRI)) { |
| return false; |
| } |
| |
| CALL_ONREQUEST(request, &apdu, sizeof(apdu), pRI, slotId); |
| |
| memsetAndFreeStrings(1, apdu.data); |
| |
| return true; |
| } |
| |
| void checkReturnStatus(int32_t slotId, Return<void>& ret, bool isRadioService) { |
| if (ret.isOk() == false) { |
| RLOGE("checkReturnStatus: unable to call response/indication callback"); |
| // Remote process hosting the callbacks must be dead. Reset the callback objects; |
| // there's no other recovery to be done here. When the client process is back up, it will |
| // call setResponseFunctions() |
| |
| // Caller should already hold rdlock, release that first |
| // note the current counter to avoid overwriting updates made by another thread before |
| // write lock is acquired. |
| int counter = mCounterRadio[slotId]; |
| pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(slotId); |
| int ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // acquire wrlock |
| ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // make sure the counter value has not changed |
| if (counter == mCounterRadio[slotId]) { |
| radioService[slotId]->mRadioResponse = NULL; |
| radioService[slotId]->mRadioIndication = NULL; |
| radioService[slotId]->mRadioResponseV1_1 = NULL; |
| radioService[slotId]->mRadioIndicationV1_1 = NULL; |
| mCounterRadio[slotId]++; |
| } else { |
| RLOGE("checkReturnStatus: not resetting responseFunctions as they likely " |
| "got updated on another thread"); |
| } |
| |
| // release wrlock |
| ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // Reacquire rdlock |
| ret = pthread_rwlock_rdlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| } |
| } |
| |
| void RadioImpl::checkReturnStatus(Return<void>& ret) { |
| ::checkReturnStatus(mSlotId, ret, true); |
| } |
| |
| Return<void> RadioImpl::setResponseFunctions( |
| const ::android::sp<IRadioResponse>& radioResponseParam, |
| const ::android::sp<IRadioIndication>& radioIndicationParam) { |
| RLOGD("setResponseFunctions"); |
| |
| pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId); |
| int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| mRadioResponse = radioResponseParam; |
| mRadioIndication = radioIndicationParam; |
| mRadioResponseV1_1 = V1_1::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr); |
| mRadioIndicationV1_1 = V1_1::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr); |
| if (mRadioResponseV1_1 == nullptr || mRadioIndicationV1_1 == nullptr) { |
| mRadioResponseV1_1 = nullptr; |
| mRadioIndicationV1_1 = nullptr; |
| } |
| |
| mCounterRadio[mSlotId]++; |
| |
| ret = pthread_rwlock_unlock(radioServiceRwlockPtr); |
| assert(ret == 0); |
| |
| // client is connected. Send initial indications. |
| android::onNewCommandConnect((RIL_SOCKET_ID) mSlotId); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getIccCardStatus(int32_t serial) { |
| #if VDBG |
| RLOGD("getIccCardStatus: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::supplyIccPinForApp(int32_t serial, const hidl_string& pin, |
| const hidl_string& aid) { |
| #if VDBG |
| RLOGD("supplyIccPinForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN, true, |
| 2, pin.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::supplyIccPukForApp(int32_t serial, const hidl_string& puk, |
| const hidl_string& pin, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("supplyIccPukForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK, true, |
| 3, puk.c_str(), pin.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2, |
| const hidl_string& aid) { |
| #if VDBG |
| RLOGD("supplyIccPin2ForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2, true, |
| 2, pin2.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, |
| const hidl_string& pin2, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("supplyIccPuk2ForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2, true, |
| 3, puk2.c_str(), pin2.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::changeIccPinForApp(int32_t serial, const hidl_string& oldPin, |
| const hidl_string& newPin, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("changeIccPinForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN, true, |
| 3, oldPin.c_str(), newPin.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, |
| const hidl_string& newPin2, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("changeIccPin2ForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2, true, |
| 3, oldPin2.c_str(), newPin2.c_str(), aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::supplyNetworkDepersonalization(int32_t serial, |
| const hidl_string& netPin) { |
| #if VDBG |
| RLOGD("supplyNetworkDepersonalization: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, true, |
| 1, netPin.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCurrentCalls(int32_t serial) { |
| #if VDBG |
| RLOGD("getCurrentCalls: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::dial(int32_t serial, const Dial& dialInfo) { |
| #if VDBG |
| RLOGD("dial: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_DIAL); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| RIL_Dial dial = {}; |
| RIL_UUS_Info uusInfo = {}; |
| int32_t sizeOfDial = sizeof(dial); |
| |
| if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) { |
| return Void(); |
| } |
| dial.clir = (int) dialInfo.clir; |
| |
| if (dialInfo.uusInfo.size() != 0) { |
| uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType; |
| uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs; |
| |
| if (dialInfo.uusInfo[0].uusData.size() == 0) { |
| uusInfo.uusData = NULL; |
| uusInfo.uusLength = 0; |
| } else { |
| if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) { |
| memsetAndFreeStrings(1, dial.address); |
| return Void(); |
| } |
| uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size(); |
| } |
| |
| dial.uusInfo = &uusInfo; |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_DIAL, &dial, sizeOfDial, pRI, mSlotId); |
| |
| memsetAndFreeStrings(2, dial.address, uusInfo.uusData); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getImsiForApp(int32_t serial, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("getImsiForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, false, |
| 1, aid.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::hangup(int32_t serial, int32_t gsmIndex) { |
| #if VDBG |
| RLOGD("hangup: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_HANGUP, 1, gsmIndex); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::hangupWaitingOrBackground(int32_t serial) { |
| #if VDBG |
| RLOGD("hangupWaitingOrBackground: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::hangupForegroundResumeBackground(int32_t serial) { |
| #if VDBG |
| RLOGD("hangupForegroundResumeBackground: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::switchWaitingOrHoldingAndActive(int32_t serial) { |
| #if VDBG |
| RLOGD("switchWaitingOrHoldingAndActive: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::conference(int32_t serial) { |
| #if VDBG |
| RLOGD("conference: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::rejectCall(int32_t serial) { |
| #if VDBG |
| RLOGD("rejectCall: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getLastCallFailCause(int32_t serial) { |
| #if VDBG |
| RLOGD("getLastCallFailCause: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_LAST_CALL_FAIL_CAUSE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getSignalStrength(int32_t serial) { |
| #if VDBG |
| RLOGD("getSignalStrength: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getVoiceRegistrationState(int32_t serial) { |
| #if VDBG |
| RLOGD("getVoiceRegistrationState: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getDataRegistrationState(int32_t serial) { |
| #if VDBG |
| RLOGD("getDataRegistrationState: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getOperator(int32_t serial) { |
| #if VDBG |
| RLOGD("getOperator: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setRadioPower(int32_t serial, bool on) { |
| RLOGD("setRadioPower: serial %d on %d", serial, on); |
| dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendDtmf(int32_t serial, const hidl_string& s) { |
| #if VDBG |
| RLOGD("sendDtmf: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_DTMF, s.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendSms(int32_t serial, const GsmSmsMessage& message) { |
| #if VDBG |
| RLOGD("sendSms: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, false, |
| 2, message.smscPdu.c_str(), message.pdu.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message) { |
| #if VDBG |
| RLOGD("sendSMSExpectMore: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE, false, |
| 2, message.smscPdu.c_str(), message.pdu.c_str()); |
| return Void(); |
| } |
| |
| static bool convertMvnoTypeToString(MvnoType type, char *&str) { |
| switch (type) { |
| case MvnoType::IMSI: |
| str = (char *)"imsi"; |
| return true; |
| case MvnoType::GID: |
| str = (char *)"gid"; |
| return true; |
| case MvnoType::SPN: |
| str = (char *)"spn"; |
| return true; |
| case MvnoType::NONE: |
| str = (char *)""; |
| return true; |
| } |
| return false; |
| } |
| |
| Return<void> RadioImpl::setupDataCall(int32_t serial, RadioTechnology radioTechnology, |
| const DataProfileInfo& dataProfileInfo, bool modemCognitive, |
| bool roamingAllowed, bool isRoaming) { |
| |
| #if VDBG |
| RLOGD("setupDataCall: serial %d", serial); |
| #endif |
| |
| if (s_vendorFunctions->version >= 4 && s_vendorFunctions->version <= 14) { |
| const hidl_string &protocol = |
| (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 7, |
| std::to_string((int) radioTechnology + 2).c_str(), |
| std::to_string((int) dataProfileInfo.profileId).c_str(), |
| dataProfileInfo.apn.c_str(), |
| dataProfileInfo.user.c_str(), |
| dataProfileInfo.password.c_str(), |
| std::to_string((int) dataProfileInfo.authType).c_str(), |
| protocol.c_str()); |
| } else if (s_vendorFunctions->version >= 15) { |
| char *mvnoTypeStr = NULL; |
| if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, mvnoTypeStr)) { |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SETUP_DATA_CALL); |
| if (pRI != NULL) { |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| } |
| return Void(); |
| } |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15, |
| std::to_string((int) radioTechnology + 2).c_str(), |
| std::to_string((int) dataProfileInfo.profileId).c_str(), |
| dataProfileInfo.apn.c_str(), |
| dataProfileInfo.user.c_str(), |
| dataProfileInfo.password.c_str(), |
| std::to_string((int) dataProfileInfo.authType).c_str(), |
| dataProfileInfo.protocol.c_str(), |
| dataProfileInfo.roamingProtocol.c_str(), |
| std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(), |
| std::to_string(dataProfileInfo.bearerBitmap).c_str(), |
| modemCognitive ? "1" : "0", |
| std::to_string(dataProfileInfo.mtu).c_str(), |
| mvnoTypeStr, |
| dataProfileInfo.mvnoMatchData.c_str(), |
| roamingAllowed ? "1" : "0"); |
| } else { |
| RLOGE("Unsupported RIL version %d, min version expected 4", s_vendorFunctions->version); |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SETUP_DATA_CALL); |
| if (pRI != NULL) { |
| sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); |
| } |
| } |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::iccIOForApp(int32_t serial, const IccIo& iccIo) { |
| #if VDBG |
| RLOGD("iccIOForApp: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_IO); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_SIM_IO_v6 rilIccIo = {}; |
| rilIccIo.command = iccIo.command; |
| rilIccIo.fileid = iccIo.fileId; |
| if (!copyHidlStringToRil(&rilIccIo.path, iccIo.path, pRI)) { |
| return Void(); |
| } |
| |
| rilIccIo.p1 = iccIo.p1; |
| rilIccIo.p2 = iccIo.p2; |
| rilIccIo.p3 = iccIo.p3; |
| |
| if (!copyHidlStringToRil(&rilIccIo.data, iccIo.data, pRI)) { |
| memsetAndFreeStrings(1, rilIccIo.path); |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&rilIccIo.pin2, iccIo.pin2, pRI)) { |
| memsetAndFreeStrings(2, rilIccIo.path, rilIccIo.data); |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&rilIccIo.aidPtr, iccIo.aid, pRI)) { |
| memsetAndFreeStrings(3, rilIccIo.path, rilIccIo.data, rilIccIo.pin2); |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_SIM_IO, &rilIccIo, sizeof(rilIccIo), pRI, mSlotId); |
| |
| memsetAndFreeStrings(4, rilIccIo.path, rilIccIo.data, rilIccIo.pin2, rilIccIo.aidPtr); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendUssd(int32_t serial, const hidl_string& ussd) { |
| #if VDBG |
| RLOGD("sendUssd: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_SEND_USSD, ussd.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::cancelPendingUssd(int32_t serial) { |
| #if VDBG |
| RLOGD("cancelPendingUssd: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getClir(int32_t serial) { |
| #if VDBG |
| RLOGD("getClir: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setClir(int32_t serial, int32_t status) { |
| #if VDBG |
| RLOGD("setClir: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CLIR, 1, status); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCallForwardStatus(int32_t serial, const CallForwardInfo& callInfo) { |
| #if VDBG |
| RLOGD("getCallForwardStatus: serial %d", serial); |
| #endif |
| dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, |
| callInfo); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCallForward(int32_t serial, const CallForwardInfo& callInfo) { |
| #if VDBG |
| RLOGD("setCallForward: serial %d", serial); |
| #endif |
| dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_SET_CALL_FORWARD, |
| callInfo); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCallWaiting(int32_t serial, int32_t serviceClass) { |
| #if VDBG |
| RLOGD("getCallWaiting: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_QUERY_CALL_WAITING, 1, serviceClass); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) { |
| #if VDBG |
| RLOGD("setCallWaiting: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CALL_WAITING, 2, BOOL_TO_INT(enable), |
| serviceClass); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::acknowledgeLastIncomingGsmSms(int32_t serial, |
| bool success, SmsAcknowledgeFailCause cause) { |
| #if VDBG |
| RLOGD("acknowledgeLastIncomingGsmSms: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SMS_ACKNOWLEDGE, 2, BOOL_TO_INT(success), |
| cause); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::acceptCall(int32_t serial) { |
| #if VDBG |
| RLOGD("acceptCall: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::deactivateDataCall(int32_t serial, |
| int32_t cid, bool reasonRadioShutDown) { |
| #if VDBG |
| RLOGD("deactivateDataCall: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL, false, |
| 2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0"); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getFacilityLockForApp(int32_t serial, const hidl_string& facility, |
| const hidl_string& password, int32_t serviceClass, |
| const hidl_string& appId) { |
| #if VDBG |
| RLOGD("getFacilityLockForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK, true, |
| 4, facility.c_str(), password.c_str(), |
| (std::to_string(serviceClass)).c_str(), appId.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setFacilityLockForApp(int32_t serial, const hidl_string& facility, |
| bool lockState, const hidl_string& password, |
| int32_t serviceClass, const hidl_string& appId) { |
| #if VDBG |
| RLOGD("setFacilityLockForApp: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK, true, |
| 5, facility.c_str(), lockState ? "1" : "0", password.c_str(), |
| (std::to_string(serviceClass)).c_str(), appId.c_str() ); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setBarringPassword(int32_t serial, const hidl_string& facility, |
| const hidl_string& oldPassword, |
| const hidl_string& newPassword) { |
| #if VDBG |
| RLOGD("setBarringPassword: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD, true, |
| 3, facility.c_str(), oldPassword.c_str(), newPassword.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getNetworkSelectionMode(int32_t serial) { |
| #if VDBG |
| RLOGD("getNetworkSelectionMode: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setNetworkSelectionModeAutomatic(int32_t serial) { |
| #if VDBG |
| RLOGD("setNetworkSelectionModeAutomatic: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setNetworkSelectionModeManual(int32_t serial, |
| const hidl_string& operatorNumeric) { |
| #if VDBG |
| RLOGD("setNetworkSelectionModeManual: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, |
| operatorNumeric.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getAvailableNetworks(int32_t serial) { |
| #if VDBG |
| RLOGD("getAvailableNetworks: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) { |
| #if VDBG |
| RLOGD("startNetworkScan: serial %d", serial); |
| #endif |
| |
| 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 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 V1_1::RadioAccessNetworks::GERAN: |
| ras_to.bands_length = ras_from.geranBands.size(); |
| bands = (std::vector<uint32_t> *) &ras_from.geranBands; |
| break; |
| case V1_1::RadioAccessNetworks::UTRAN: |
| ras_to.bands_length = ras_from.utranBands.size(); |
| bands = (std::vector<uint32_t> *) &ras_from.utranBands; |
| break; |
| case 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 |
| for (size_t idx = 0; idx < ras_to.bands_length; ++idx) { |
| ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx]; |
| } |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI, |
| mSlotId); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::stopNetworkScan(int32_t serial) { |
| #if VDBG |
| RLOGD("stopNetworkScan: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_NETWORK_SCAN); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::startDtmf(int32_t serial, const hidl_string& s) { |
| #if VDBG |
| RLOGD("startDtmf: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_DTMF_START, |
| s.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::stopDtmf(int32_t serial) { |
| #if VDBG |
| RLOGD("stopDtmf: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getBasebandVersion(int32_t serial) { |
| #if VDBG |
| RLOGD("getBasebandVersion: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::separateConnection(int32_t serial, int32_t gsmIndex) { |
| #if VDBG |
| RLOGD("separateConnection: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SEPARATE_CONNECTION, 1, gsmIndex); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setMute(int32_t serial, bool enable) { |
| #if VDBG |
| RLOGD("setMute: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_MUTE, 1, BOOL_TO_INT(enable)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getMute(int32_t serial) { |
| #if VDBG |
| RLOGD("getMute: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getClip(int32_t serial) { |
| #if VDBG |
| RLOGD("getClip: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getDataCallList(int32_t serial) { |
| #if VDBG |
| RLOGD("getDataCallList: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setSuppServiceNotifications(int32_t serial, bool enable) { |
| #if VDBG |
| RLOGD("setSuppServiceNotifications: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, 1, |
| BOOL_TO_INT(enable)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::writeSmsToSim(int32_t serial, const SmsWriteArgs& smsWriteArgs) { |
| #if VDBG |
| RLOGD("writeSmsToSim: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_WRITE_SMS_TO_SIM); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_SMS_WriteArgs args; |
| args.status = (int) smsWriteArgs.status; |
| |
| if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) { |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&args.smsc, smsWriteArgs.smsc, pRI)) { |
| memsetAndFreeStrings(1, args.pdu); |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_WRITE_SMS_TO_SIM, &args, sizeof(args), pRI, mSlotId); |
| |
| memsetAndFreeStrings(2, args.smsc, args.pdu); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::deleteSmsOnSim(int32_t serial, int32_t index) { |
| #if VDBG |
| RLOGD("deleteSmsOnSim: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_DELETE_SMS_ON_SIM, 1, index); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setBandMode(int32_t serial, RadioBandMode mode) { |
| #if VDBG |
| RLOGD("setBandMode: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_BAND_MODE, 1, mode); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getAvailableBandModes(int32_t serial) { |
| #if VDBG |
| RLOGD("getAvailableBandModes: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendEnvelope(int32_t serial, const hidl_string& command) { |
| #if VDBG |
| RLOGD("sendEnvelope: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, |
| command.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendTerminalResponseToSim(int32_t serial, |
| const hidl_string& commandResponse) { |
| #if VDBG |
| RLOGD("sendTerminalResponseToSim: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, |
| commandResponse.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) { |
| #if VDBG |
| RLOGD("handleStkCallSetupRequestFromSim: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, |
| 1, BOOL_TO_INT(accept)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::explicitCallTransfer(int32_t serial) { |
| #if VDBG |
| RLOGD("explicitCallTransfer: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType) { |
| #if VDBG |
| RLOGD("setPreferredNetworkType: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, 1, nwType); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getPreferredNetworkType(int32_t serial) { |
| #if VDBG |
| RLOGD("getPreferredNetworkType: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getNeighboringCids(int32_t serial) { |
| #if VDBG |
| RLOGD("getNeighboringCids: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_NEIGHBORING_CELL_IDS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setLocationUpdates(int32_t serial, bool enable) { |
| #if VDBG |
| RLOGD("setLocationUpdates: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_LOCATION_UPDATES, 1, BOOL_TO_INT(enable)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCdmaSubscriptionSource(int32_t serial, CdmaSubscriptionSource cdmaSub) { |
| #if VDBG |
| RLOGD("setCdmaSubscriptionSource: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, 1, cdmaSub); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type) { |
| #if VDBG |
| RLOGD("setCdmaRoamingPreference: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, 1, type); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCdmaRoamingPreference(int32_t serial) { |
| #if VDBG |
| RLOGD("getCdmaRoamingPreference: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setTTYMode(int32_t serial, TtyMode mode) { |
| #if VDBG |
| RLOGD("setTTYMode: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_TTY_MODE, 1, mode); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getTTYMode(int32_t serial) { |
| #if VDBG |
| RLOGD("getTTYMode: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setPreferredVoicePrivacy(int32_t serial, bool enable) { |
| #if VDBG |
| RLOGD("setPreferredVoicePrivacy: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, |
| 1, BOOL_TO_INT(enable)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getPreferredVoicePrivacy(int32_t serial) { |
| #if VDBG |
| RLOGD("getPreferredVoicePrivacy: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) { |
| #if VDBG |
| RLOGD("sendCDMAFeatureCode: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_CDMA_FLASH, |
| featureCode.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on, |
| int32_t off) { |
| #if VDBG |
| RLOGD("sendBurstDtmf: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF, false, |
| 3, dtmf.c_str(), (std::to_string(on)).c_str(), |
| (std::to_string(off)).c_str()); |
| return Void(); |
| } |
| |
| void constructCdmaSms(RIL_CDMA_SMS_Message &rcsm, const CdmaSmsMessage& sms) { |
| rcsm.uTeleserviceID = sms.teleserviceId; |
| rcsm.bIsServicePresent = BOOL_TO_INT(sms.isServicePresent); |
| rcsm.uServicecategory = sms.serviceCategory; |
| rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) sms.address.digitMode; |
| rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) sms.address.numberMode; |
| rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) sms.address.numberType; |
| rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) sms.address.numberPlan; |
| |
| rcsm.sAddress.number_of_digits = sms.address.digits.size(); |
| int digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); |
| for (int i = 0; i < digitLimit; i++) { |
| rcsm.sAddress.digits[i] = sms.address.digits[i]; |
| } |
| |
| rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) sms.subAddress.subaddressType; |
| rcsm.sSubAddress.odd = BOOL_TO_INT(sms.subAddress.odd); |
| |
| rcsm.sSubAddress.number_of_digits = sms.subAddress.digits.size(); |
| digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); |
| for (int i = 0; i < digitLimit; i++) { |
| rcsm.sSubAddress.digits[i] = sms.subAddress.digits[i]; |
| } |
| |
| rcsm.uBearerDataLen = sms.bearerData.size(); |
| digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); |
| for (int i = 0; i < digitLimit; i++) { |
| rcsm.aBearerData[i] = sms.bearerData[i]; |
| } |
| } |
| |
| Return<void> RadioImpl::sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms) { |
| #if VDBG |
| RLOGD("sendCdmaSms: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_CDMA_SMS_Message rcsm = {}; |
| constructCdmaSms(rcsm, sms); |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) { |
| #if VDBG |
| RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_CDMA_SMS_Ack rcsa = {}; |
| |
| rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) smsAck.errorClass; |
| rcsa.uSMSCauseCode = smsAck.smsCauseCode; |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa), pRI, mSlotId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getGsmBroadcastConfig(int32_t serial) { |
| #if VDBG |
| RLOGD("getGsmBroadcastConfig: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setGsmBroadcastConfig(int32_t serial, |
| const hidl_vec<GsmBroadcastSmsConfigInfo>& |
| configInfo) { |
| #if VDBG |
| RLOGD("setGsmBroadcastConfig: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| uint32_t num = configInfo.size(); |
| if (num > MAX_BROADCAST_SMS_CONFIG_INFO) { |
| RLOGE("setGsmBroadcastConfig: Invalid configInfo length %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return Void(); |
| } |
| auto gsmBci = new RIL_GSM_BroadcastSmsConfigInfo[num]; |
| if (gsmBci == nullptr) { |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| std::vector<RIL_GSM_BroadcastSmsConfigInfo*> gsmBciPtrs(num); |
| |
| for (uint32_t i = 0 ; i < num ; i++ ) { |
| gsmBciPtrs[i] = &gsmBci[i]; |
| gsmBci[i].fromServiceId = configInfo[i].fromServiceId; |
| gsmBci[i].toServiceId = configInfo[i].toServiceId; |
| gsmBci[i].fromCodeScheme = configInfo[i].fromCodeScheme; |
| gsmBci[i].toCodeScheme = configInfo[i].toCodeScheme; |
| gsmBci[i].selected = BOOL_TO_INT(configInfo[i].selected); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs.data(), |
| num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId); |
| |
| delete []gsmBci; |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setGsmBroadcastActivation(int32_t serial, bool activate) { |
| #if VDBG |
| RLOGD("setGsmBroadcastActivation: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, |
| 1, BOOL_TO_INT(!activate)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCdmaBroadcastConfig(int32_t serial) { |
| #if VDBG |
| RLOGD("getCdmaBroadcastConfig: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCdmaBroadcastConfig(int32_t serial, |
| const hidl_vec<CdmaBroadcastSmsConfigInfo>& |
| configInfo) { |
| #if VDBG |
| RLOGD("setCdmaBroadcastConfig: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| uint32_t num = configInfo.size(); |
| if (num > MAX_BROADCAST_SMS_CONFIG_INFO) { |
| RLOGE("setCdmaBroadcastConfig: Invalid configInfo length %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return Void(); |
| } |
| auto cdmaBci = new RIL_CDMA_BroadcastSmsConfigInfo[num]; |
| if (cdmaBci == nullptr) { |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| std::vector<RIL_CDMA_BroadcastSmsConfigInfo*> cdmaBciPtrs(num); |
| for (uint32_t i = 0 ; i < num ; i++ ) { |
| cdmaBciPtrs[i] = &cdmaBci[i]; |
| cdmaBci[i].service_category = configInfo[i].serviceCategory; |
| cdmaBci[i].language = configInfo[i].language; |
| cdmaBci[i].selected = BOOL_TO_INT(configInfo[i].selected); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs.data(), |
| num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId); |
| |
| delete []cdmaBci; |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCdmaBroadcastActivation(int32_t serial, bool activate) { |
| #if VDBG |
| RLOGD("setCdmaBroadcastActivation: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, |
| 1, BOOL_TO_INT(!activate)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCDMASubscription(int32_t serial) { |
| #if VDBG |
| RLOGD("getCDMASubscription: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms) { |
| #if VDBG |
| RLOGD("writeSmsToRuim: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_CDMA_SMS_WriteArgs rcsw = {}; |
| rcsw.status = (int) cdmaSms.status; |
| constructCdmaSms(rcsw.message, cdmaSms.message); |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw), pRI, mSlotId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::deleteSmsOnRuim(int32_t serial, int32_t index) { |
| #if VDBG |
| RLOGD("deleteSmsOnRuim: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, 1, index); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getDeviceIdentity(int32_t serial) { |
| #if VDBG |
| RLOGD("getDeviceIdentity: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::exitEmergencyCallbackMode(int32_t serial) { |
| #if VDBG |
| RLOGD("exitEmergencyCallbackMode: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getSmscAddress(int32_t serial) { |
| #if VDBG |
| RLOGD("getSmscAddress: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setSmscAddress(int32_t serial, const hidl_string& smsc) { |
| #if VDBG |
| RLOGD("setSmscAddress: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_SET_SMSC_ADDRESS, |
| smsc.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::reportSmsMemoryStatus(int32_t serial, bool available) { |
| #if VDBG |
| RLOGD("reportSmsMemoryStatus: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, 1, |
| BOOL_TO_INT(available)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::reportStkServiceIsRunning(int32_t serial) { |
| #if VDBG |
| RLOGD("reportStkServiceIsRunning: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCdmaSubscriptionSource(int32_t serial) { |
| #if VDBG |
| RLOGD("getCdmaSubscriptionSource: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) { |
| #if VDBG |
| RLOGD("requestIsimAuthentication: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_ISIM_AUTHENTICATION, |
| challenge.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success, |
| const hidl_string& ackPdu) { |
| #if VDBG |
| RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial); |
| #endif |
| dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, false, |
| 2, success ? "1" : "0", ackPdu.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) { |
| #if VDBG |
| RLOGD("sendEnvelopeWithStatus: serial %d", serial); |
| #endif |
| dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, |
| contents.c_str()); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getVoiceRadioTechnology(int32_t serial) { |
| #if VDBG |
| RLOGD("getVoiceRadioTechnology: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getCellInfoList(int32_t serial) { |
| #if VDBG |
| RLOGD("getCellInfoList: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CELL_INFO_LIST); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCellInfoListRate(int32_t serial, int32_t rate) { |
| #if VDBG |
| RLOGD("setCellInfoListRate: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, 1, rate); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, |
| bool modemCognitive, bool isRoaming) { |
| #if VDBG |
| RLOGD("setInitialAttachApn: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SET_INITIAL_ATTACH_APN); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| if (s_vendorFunctions->version <= 14) { |
| RIL_InitialAttachApn iaa = {}; |
| |
| if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) { |
| return Void(); |
| } |
| |
| const hidl_string &protocol = |
| (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol); |
| |
| if (!copyHidlStringToRil(&iaa.protocol, protocol, pRI)) { |
| memsetAndFreeStrings(1, iaa.apn); |
| return Void(); |
| } |
| iaa.authtype = (int) dataProfileInfo.authType; |
| if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { |
| memsetAndFreeStrings(2, iaa.apn, iaa.protocol); |
| return Void(); |
| } |
| if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { |
| memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.username); |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); |
| |
| memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.username, iaa.password); |
| } else { |
| RIL_InitialAttachApn_v15 iaa = {}; |
| |
| if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) { |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) { |
| memsetAndFreeStrings(1, iaa.apn); |
| return Void(); |
| } |
| if (!copyHidlStringToRil(&iaa.roamingProtocol, dataProfileInfo.roamingProtocol, pRI)) { |
| memsetAndFreeStrings(2, iaa.apn, iaa.protocol); |
| return Void(); |
| } |
| iaa.authtype = (int) dataProfileInfo.authType; |
| if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) { |
| memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.roamingProtocol); |
| return Void(); |
| } |
| if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) { |
| memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username); |
| return Void(); |
| } |
| iaa.supportedTypesBitmask = dataProfileInfo.supportedApnTypesBitmap; |
| iaa.bearerBitmask = dataProfileInfo.bearerBitmap; |
| iaa.modemCognitive = BOOL_TO_INT(modemCognitive); |
| iaa.mtu = dataProfileInfo.mtu; |
| |
| if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, iaa.mvnoType)) { |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, |
| iaa.password); |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&iaa.mvnoMatchData, dataProfileInfo.mvnoMatchData, pRI)) { |
| memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, |
| iaa.password); |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId); |
| |
| memsetAndFreeStrings(6, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username, |
| iaa.password, iaa.mvnoMatchData); |
| } |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getImsRegistrationState(int32_t serial) { |
| #if VDBG |
| RLOGD("getImsRegistrationState: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_IMS_REGISTRATION_STATE); |
| return Void(); |
| } |
| |
| bool dispatchImsGsmSms(const ImsSmsMessage& message, RequestInfo *pRI) { |
| RIL_IMS_SMS_Message rism = {}; |
| char **pStrings; |
| int countStrings = 2; |
| int dataLen = sizeof(char *) * countStrings; |
| |
| rism.tech = RADIO_TECH_3GPP; |
| rism.retry = BOOL_TO_INT(message.retry); |
| rism.messageRef = message.messageRef; |
| |
| if (message.gsmMessage.size() != 1) { |
| RLOGE("dispatchImsGsmSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return false; |
| } |
| |
| pStrings = (char **)calloc(countStrings, sizeof(char *)); |
| if (pStrings == NULL) { |
| RLOGE("dispatchImsGsmSms: Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return false; |
| } |
| |
| if (!copyHidlStringToRil(&pStrings[0], message.gsmMessage[0].smscPdu, pRI)) { |
| #ifdef MEMSET_FREED |
| memset(pStrings, 0, dataLen); |
| #endif |
| free(pStrings); |
| return false; |
| } |
| |
| if (!copyHidlStringToRil(&pStrings[1], message.gsmMessage[0].pdu, pRI)) { |
| memsetAndFreeStrings(1, pStrings[0]); |
| #ifdef MEMSET_FREED |
| memset(pStrings, 0, dataLen); |
| #endif |
| free(pStrings); |
| return false; |
| } |
| |
| rism.message.gsmMessage = pStrings; |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) + |
| sizeof(uint8_t) + sizeof(int32_t) + dataLen, pRI, pRI->socket_id); |
| |
| for (int i = 0 ; i < countStrings ; i++) { |
| memsetAndFreeStrings(1, pStrings[i]); |
| } |
| |
| #ifdef MEMSET_FREED |
| memset(pStrings, 0, dataLen); |
| #endif |
| free(pStrings); |
| |
| return true; |
| } |
| |
| struct ImsCdmaSms { |
| RIL_IMS_SMS_Message imsSms; |
| RIL_CDMA_SMS_Message cdmaSms; |
| }; |
| |
| bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) { |
| ImsCdmaSms temp = {}; |
| |
| if (message.cdmaMessage.size() != 1) { |
| RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| return false; |
| } |
| |
| temp.imsSms.tech = RADIO_TECH_3GPP2; |
| temp.imsSms.retry = BOOL_TO_INT(message.retry); |
| temp.imsSms.messageRef = message.messageRef; |
| temp.imsSms.message.cdmaMessage = &temp.cdmaSms; |
| |
| constructCdmaSms(temp.cdmaSms, message.cdmaMessage[0]); |
| |
| // Vendor code expects payload length to include actual msg payload |
| // (sizeof(RIL_CDMA_SMS_Message)) instead of (RIL_CDMA_SMS_Message *) + size of other fields in |
| // RIL_IMS_SMS_Message |
| int payloadLen = sizeof(RIL_RadioTechnologyFamily) + sizeof(uint8_t) + sizeof(int32_t) |
| + sizeof(RIL_CDMA_SMS_Message); |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &temp.imsSms, payloadLen, pRI, pRI->socket_id); |
| |
| return true; |
| } |
| |
| Return<void> RadioImpl::sendImsSms(int32_t serial, const ImsSmsMessage& message) { |
| #if VDBG |
| RLOGD("sendImsSms: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_IMS_SEND_SMS); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| if (RadioTechnologyFamily::THREE_GPP == message.tech) { |
| dispatchImsGsmSms(message, pRI); |
| } else if (RadioTechnologyFamily::THREE_GPP2 == message.tech) { |
| dispatchImsCdmaSms(message, pRI); |
| } else { |
| RLOGE("sendImsSms: Invalid radio tech %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| } |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message) { |
| #if VDBG |
| RLOGD("iccTransmitApduBasicChannel: serial %d", serial); |
| #endif |
| dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, message); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) { |
| #if VDBG |
| RLOGD("iccOpenLogicalChannel: serial %d", serial); |
| #endif |
| if (s_vendorFunctions->version < 15) { |
| dispatchString(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL, aid.c_str()); |
| } else { |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_OpenChannelParams params = {}; |
| |
| params.p2 = p2; |
| |
| if (!copyHidlStringToRil(¶ms.aidPtr, aid, pRI)) { |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, ¶ms, sizeof(params), pRI, mSlotId); |
| |
| memsetAndFreeStrings(1, params.aidPtr); |
| } |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::iccCloseLogicalChannel(int32_t serial, int32_t channelId) { |
| #if VDBG |
| RLOGD("iccCloseLogicalChannel: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SIM_CLOSE_CHANNEL, 1, channelId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message) { |
| #if VDBG |
| RLOGD("iccTransmitApduLogicalChannel: serial %d", serial); |
| #endif |
| dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, message); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::nvReadItem(int32_t serial, NvItem itemId) { |
| #if VDBG |
| RLOGD("nvReadItem: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_READ_ITEM); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_NV_ReadItem nvri = {}; |
| nvri.itemID = (RIL_NV_Item) itemId; |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, mSlotId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::nvWriteItem(int32_t serial, const NvWriteItem& item) { |
| #if VDBG |
| RLOGD("nvWriteItem: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_WRITE_ITEM); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_NV_WriteItem nvwi = {}; |
| |
| nvwi.itemID = (RIL_NV_Item) item.itemId; |
| |
| if (!copyHidlStringToRil(&nvwi.value, item.value, pRI)) { |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, mSlotId); |
| |
| memsetAndFreeStrings(1, nvwi.value); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) { |
| #if VDBG |
| RLOGD("nvWriteCdmaPrl: serial %d", serial); |
| #endif |
| dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::nvResetConfig(int32_t serial, ResetNvType resetType) { |
| int rilResetType = -1; |
| #if VDBG |
| RLOGD("nvResetConfig: serial %d", serial); |
| #endif |
| /* Convert ResetNvType to RIL.h values |
| * RIL_REQUEST_NV_RESET_CONFIG |
| * 1 - reload all NV items |
| * 2 - erase NV reset (SCRTN) |
| * 3 - factory reset (RTN) |
| */ |
| switch(resetType) { |
| case ResetNvType::RELOAD: |
| rilResetType = 1; |
| break; |
| case ResetNvType::ERASE: |
| rilResetType = 2; |
| break; |
| case ResetNvType::FACTORY_RESET: |
| rilResetType = 3; |
| break; |
| } |
| dispatchInts(serial, mSlotId, RIL_REQUEST_NV_RESET_CONFIG, 1, rilResetType); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub) { |
| #if VDBG |
| RLOGD("setUiccSubscription: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SET_UICC_SUBSCRIPTION); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_SelectUiccSub rilUiccSub = {}; |
| |
| rilUiccSub.slot = uiccSub.slot; |
| rilUiccSub.app_index = uiccSub.appIndex; |
| rilUiccSub.sub_type = (RIL_SubscriptionType) uiccSub.subType; |
| rilUiccSub.act_status = (RIL_UiccSubActStatus) uiccSub.actStatus; |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rilUiccSub, sizeof(rilUiccSub), pRI, mSlotId); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setDataAllowed(int32_t serial, bool allow) { |
| #if VDBG |
| RLOGD("setDataAllowed: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_ALLOW_DATA, 1, BOOL_TO_INT(allow)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getHardwareConfig(int32_t serial) { |
| #if VDBG |
| RLOGD("getHardwareConfig: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::requestIccSimAuthentication(int32_t serial, int32_t authContext, |
| const hidl_string& authData, const hidl_string& aid) { |
| #if VDBG |
| RLOGD("requestIccSimAuthentication: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_AUTHENTICATION); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_SimAuthentication pf = {}; |
| |
| pf.authContext = authContext; |
| |
| if (!copyHidlStringToRil(&pf.authData, authData, pRI)) { |
| return Void(); |
| } |
| |
| if (!copyHidlStringToRil(&pf.aid, aid, pRI)) { |
| memsetAndFreeStrings(1, pf.authData); |
| return Void(); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, mSlotId); |
| |
| memsetAndFreeStrings(2, pf.authData, pf.aid); |
| return Void(); |
| } |
| |
| /** |
| * @param numProfiles number of data profile |
| * @param dataProfiles the pointer to the actual data profiles. The acceptable type is |
| RIL_DataProfileInfo or RIL_DataProfileInfo_v15. |
| * @param dataProfilePtrs the pointer to the pointers that point to each data profile structure |
| * @param numfields number of string-type member in the data profile structure |
| * @param ... the variadic parameters are pointers to each string-type member |
| **/ |
| template <typename T> |
| void freeSetDataProfileData(int numProfiles, T *dataProfiles, T **dataProfilePtrs, |
| int numfields, ...) { |
| va_list args; |
| va_start(args, numfields); |
| |
| // Iterate through each string-type field that need to be free. |
| for (int i = 0; i < numfields; i++) { |
| // Iterate through each data profile and free that specific string-type field. |
| // The type 'char *T::*' is a type of pointer to a 'char *' member inside T structure. |
| char *T::*ptr = va_arg(args, char *T::*); |
| for (int j = 0; j < numProfiles; j++) { |
| memsetAndFreeStrings(1, dataProfiles[j].*ptr); |
| } |
| } |
| |
| va_end(args); |
| |
| #ifdef MEMSET_FREED |
| memset(dataProfiles, 0, numProfiles * sizeof(T)); |
| memset(dataProfilePtrs, 0, numProfiles * sizeof(T *)); |
| #endif |
| free(dataProfiles); |
| free(dataProfilePtrs); |
| } |
| |
| Return<void> RadioImpl::setDataProfile(int32_t serial, const hidl_vec<DataProfileInfo>& profiles, |
| bool isRoaming) { |
| #if VDBG |
| RLOGD("setDataProfile: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_DATA_PROFILE); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| size_t num = profiles.size(); |
| bool success = false; |
| |
| if (s_vendorFunctions->version <= 14) { |
| |
| RIL_DataProfileInfo *dataProfiles = |
| (RIL_DataProfileInfo *) calloc(num, sizeof(RIL_DataProfileInfo)); |
| |
| if (dataProfiles == NULL) { |
| RLOGE("Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| |
| RIL_DataProfileInfo **dataProfilePtrs = |
| (RIL_DataProfileInfo **) calloc(num, sizeof(RIL_DataProfileInfo *)); |
| if (dataProfilePtrs == NULL) { |
| RLOGE("Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| free(dataProfiles); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| |
| for (size_t i = 0; i < num; i++) { |
| dataProfilePtrs[i] = &dataProfiles[i]; |
| |
| success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true); |
| |
| const hidl_string &protocol = |
| (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol); |
| |
| if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI, true)) { |
| success = false; |
| } |
| |
| if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI, |
| true)) { |
| success = false; |
| } |
| if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, |
| pRI, true)) { |
| success = false; |
| } |
| |
| if (!success) { |
| freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, |
| &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, |
| &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); |
| return Void(); |
| } |
| |
| dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; |
| dataProfiles[i].authType = (int) profiles[i].authType; |
| dataProfiles[i].type = (int) profiles[i].type; |
| dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; |
| dataProfiles[i].maxConns = profiles[i].maxConns; |
| dataProfiles[i].waitTime = profiles[i].waitTime; |
| dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, |
| num * sizeof(RIL_DataProfileInfo *), pRI, mSlotId); |
| |
| freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4, |
| &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol, |
| &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password); |
| } else { |
| RIL_DataProfileInfo_v15 *dataProfiles = |
| (RIL_DataProfileInfo_v15 *) calloc(num, sizeof(RIL_DataProfileInfo_v15)); |
| |
| if (dataProfiles == NULL) { |
| RLOGE("Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| |
| RIL_DataProfileInfo_v15 **dataProfilePtrs = |
| (RIL_DataProfileInfo_v15 **) calloc(num, sizeof(RIL_DataProfileInfo_v15 *)); |
| if (dataProfilePtrs == NULL) { |
| RLOGE("Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| free(dataProfiles); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| |
| for (size_t i = 0; i < num; i++) { |
| dataProfilePtrs[i] = &dataProfiles[i]; |
| |
| success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true); |
| if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol, |
| pRI)) { |
| success = false; |
| } |
| if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol, |
| profiles[i].roamingProtocol, pRI, true)) { |
| success = false; |
| } |
| if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI, |
| true)) { |
| success = false; |
| } |
| if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, |
| pRI, true)) { |
| success = false; |
| } |
| if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData, |
| profiles[i].mvnoMatchData, pRI, true)) { |
| success = false; |
| } |
| |
| if (success && !convertMvnoTypeToString(profiles[i].mvnoType, |
| dataProfiles[i].mvnoType)) { |
| sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); |
| success = false; |
| } |
| |
| if (!success) { |
| freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, |
| &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, |
| &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, |
| &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); |
| return Void(); |
| } |
| |
| dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId; |
| dataProfiles[i].authType = (int) profiles[i].authType; |
| dataProfiles[i].type = (int) profiles[i].type; |
| dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime; |
| dataProfiles[i].maxConns = profiles[i].maxConns; |
| dataProfiles[i].waitTime = profiles[i].waitTime; |
| dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled); |
| dataProfiles[i].supportedTypesBitmask = profiles[i].supportedApnTypesBitmap; |
| dataProfiles[i].bearerBitmask = profiles[i].bearerBitmap; |
| dataProfiles[i].mtu = profiles[i].mtu; |
| } |
| |
| CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs, |
| num * sizeof(RIL_DataProfileInfo_v15 *), pRI, mSlotId); |
| |
| freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6, |
| &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol, |
| &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user, |
| &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData); |
| } |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::requestShutdown(int32_t serial) { |
| #if VDBG |
| RLOGD("requestShutdown: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getRadioCapability(int32_t serial) { |
| #if VDBG |
| RLOGD("getRadioCapability: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setRadioCapability(int32_t serial, const RadioCapability& rc) { |
| #if VDBG |
| RLOGD("setRadioCapability: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_RADIO_CAPABILITY); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_RadioCapability rilRc = {}; |
| |
| // TODO : set rilRc.version using HIDL version ? |
| rilRc.session = rc.session; |
| rilRc.phase = (int) rc.phase; |
| rilRc.rat = (int) rc.raf; |
| rilRc.status = (int) rc.status; |
| strlcpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), sizeof(rilRc.logicalModemUuid)); |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId); |
| |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) { |
| #if VDBG |
| RLOGD("startLceService: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_START_LCE, 2, reportInterval, |
| BOOL_TO_INT(pullMode)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::stopLceService(int32_t serial) { |
| #if VDBG |
| RLOGD("stopLceService: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::pullLceData(int32_t serial) { |
| #if VDBG |
| RLOGD("pullLceData: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getModemActivityInfo(int32_t serial) { |
| #if VDBG |
| RLOGD("getModemActivityInfo: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setAllowedCarriers(int32_t serial, bool allAllowed, |
| const CarrierRestrictions& carriers) { |
| #if VDBG |
| RLOGD("setAllowedCarriers: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SET_CARRIER_RESTRICTIONS); |
| if (pRI == NULL) { |
| return Void(); |
| } |
| |
| RIL_CarrierRestrictions cr = {}; |
| RIL_Carrier *allowedCarriers = NULL; |
| RIL_Carrier *excludedCarriers = NULL; |
| |
| cr.len_allowed_carriers = carriers.allowedCarriers.size(); |
| allowedCarriers = (RIL_Carrier *)calloc(cr.len_allowed_carriers, sizeof(RIL_Carrier)); |
| if (allowedCarriers == NULL) { |
| RLOGE("setAllowedCarriers: Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| return Void(); |
| } |
| cr.allowed_carriers = allowedCarriers; |
| |
| cr.len_excluded_carriers = carriers.excludedCarriers.size(); |
| excludedCarriers = (RIL_Carrier *)calloc(cr.len_excluded_carriers, sizeof(RIL_Carrier)); |
| if (excludedCarriers == NULL) { |
| RLOGE("setAllowedCarriers: Memory allocation failed for request %s", |
| requestToString(pRI->pCI->requestNumber)); |
| sendErrorResponse(pRI, RIL_E_NO_MEMORY); |
| #ifdef MEMSET_FREED |
| memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier)); |
| #endif |
| free(allowedCarriers); |
| return Void(); |
| } |
| cr.excluded_carriers = excludedCarriers; |
| |
| for (int i = 0; i < cr.len_allowed_carriers; i++) { |
| allowedCarriers[i].mcc = carriers.allowedCarriers[i].mcc.c_str(); |
| allowedCarriers[i].mnc = carriers.allowedCarriers[i].mnc.c_str(); |
| allowedCarriers[i].match_type = (RIL_CarrierMatchType) carriers.allowedCarriers[i].matchType; |
| allowedCarriers[i].match_data = carriers.allowedCarriers[i].matchData.c_str(); |
| } |
| |
| for (int i = 0; i < cr.len_excluded_carriers; i++) { |
| excludedCarriers[i].mcc = carriers.excludedCarriers[i].mcc.c_str(); |
| excludedCarriers[i].mnc = carriers.excludedCarriers[i].mnc.c_str(); |
| excludedCarriers[i].match_type = |
| (RIL_CarrierMatchType) carriers.excludedCarriers[i].matchType; |
| excludedCarriers[i].match_data = carriers.excludedCarriers[i].matchData.c_str(); |
| } |
| |
| CALL_ONREQUEST(pRI->pCI->requestNumber, &cr, sizeof(RIL_CarrierRestrictions), pRI, mSlotId); |
| |
| #ifdef MEMSET_FREED |
| memset(allowedCarriers, 0, cr.len_allowed_carriers * sizeof(RIL_Carrier)); |
| memset(excludedCarriers, 0, cr.len_excluded_carriers * sizeof(RIL_Carrier)); |
| #endif |
| free(allowedCarriers); |
| free(excludedCarriers); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::getAllowedCarriers(int32_t serial) { |
| #if VDBG |
| RLOGD("getAllowedCarriers: serial %d", serial); |
| #endif |
| dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::sendDeviceState(int32_t serial, DeviceStateType deviceStateType, |
| bool state) { |
| #if VDBG |
| RLOGD("sendDeviceState: serial %d", serial); |
| #endif |
| if (s_vendorFunctions->version < 15) { |
| if (deviceStateType == DeviceStateType::LOW_DATA_EXPECTED) { |
| RLOGD("sendDeviceState: calling screen state %d", BOOL_TO_INT(!state)); |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SCREEN_STATE, 1, BOOL_TO_INT(!state)); |
| } else { |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SEND_DEVICE_STATE); |
| sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); |
| } |
| return Void(); |
| } |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SEND_DEVICE_STATE, 2, (int) deviceStateType, |
| BOOL_TO_INT(state)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setIndicationFilter(int32_t serial, int32_t indicationFilter) { |
| #if VDBG |
| RLOGD("setIndicationFilter: serial %d", serial); |
| #endif |
| if (s_vendorFunctions->version < 15) { |
| RequestInfo *pRI = android::addRequestToList(serial, mSlotId, |
| RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER); |
| sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED); |
| return Void(); |
| } |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, 1, indicationFilter); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setSimCardPower(int32_t serial, bool powerUp) { |
| #if VDBG |
| RLOGD("setSimCardPower: serial %d", serial); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, BOOL_TO_INT(powerUp)); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setSimCardPower_1_1(int32_t serial, const V1_1::CardPowerState state) { |
| #if VDBG |
| RLOGD("setSimCardPower_1_1: serial %d state %d", serial, state); |
| #endif |
| dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, state); |
| return Void(); |
| } |
| |
| Return<void> RadioImpl::setCarrierInfoForImsiEncryption(int32_t serial, |
| const V1_1::ImsiEncryptionInfo& data) { |
| #if VDBG |
| RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial); |
| #endif |
| RequestInfo *pRI = android::addRequestToList( |
|