diff --git a/include/libril/ril_ex.h b/include/libril/ril_ex.h new file mode 100644 index 0000000..757bcf9 --- /dev/null +++ b/include/libril/ril_ex.h @@ -0,0 +1,49 @@ +/* +* Copyright (C) 2014 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. +*/ + +#ifndef RIL_EX_H_INCLUDED +#define RIL_EX_H_INCLUDED + +#include +#include + +#define NUM_ELEMS_SOCKET(a) (sizeof (a) / sizeof (a)[0]) + +struct ril_event; + +void rilEventAddWakeup_helper(struct ril_event *ev); +int blockingWrite_helper(int fd, void* data, size_t len); + +enum SocketWakeType {DONT_WAKE, WAKE_PARTIAL}; + +typedef enum { + RIL_TELEPHONY_SOCKET, + RIL_SAP_SOCKET +} RIL_SOCKET_TYPE; + +typedef struct SocketListenParam { + RIL_SOCKET_ID socket_id; + int fdListen; + int fdCommand; + const char* processName; + struct ril_event* commands_event; + struct ril_event* listen_event; + void (*processCommandsCallback)(int fd, short flags, void *param); + RecordStream *p_rs; + RIL_SOCKET_TYPE type; +} SocketListenParam; + +#endif diff --git a/include/telephony/ril.h b/include/telephony/ril.h new file mode 100644 index 0000000..0512f52 --- /dev/null +++ b/include/telephony/ril.h @@ -0,0 +1,7343 @@ +/* + * Copyright (C) 2006 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. + */ + +#ifndef ANDROID_RIL_H +#define ANDROID_RIL_H 1 + +#include +#include +#include +#include +#include + +#ifndef FEATURE_UNIT_TEST +#include +#endif /* !FEATURE_UNIT_TEST */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SIM_COUNT +#if defined(ANDROID_SIM_COUNT_2) +#define SIM_COUNT 2 +#elif defined(ANDROID_SIM_COUNT_3) +#define SIM_COUNT 3 +#elif defined(ANDROID_SIM_COUNT_4) +#define SIM_COUNT 4 +#else +#define SIM_COUNT 1 +#endif + +#ifndef ANDROID_MULTI_SIM +#define SIM_COUNT 1 +#endif +#endif + +/* + * RIL version. + * Value of RIL_VERSION should not be changed in future. Here onwards, + * when a new change is supposed to be introduced which could involve new + * schemes added like Wakelocks, data structures added/updated, etc, we would + * just document RIL version associated with that change below. When OEM updates its + * RIL with those changes, they would return that new RIL version during RIL_REGISTER. + * We should make use of the returned version by vendor to identify appropriate scheme + * or data structure version to use. + * + * Documentation of RIL version and associated changes + * RIL_VERSION = 12 : This version corresponds to updated data structures namely + * RIL_Data_Call_Response_v11, RIL_SIM_IO_v6, RIL_CardStatus_v6, + * RIL_SimRefreshResponse_v7, RIL_CDMA_CallWaiting_v6, + * RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_CellIdentityGsm_v12 + * RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,RIL_CellInfoGsm_v12, + * RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12. + * + * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first + * strongly versioned version it enforces structure use. + * + * RIL_VERSION = 14 : New data structures are added, namely RIL_CarrierMatchType, + * RIL_Carrier, RIL_CarrierRestrictions and RIL_PCO_Data. + * New commands added: RIL_REQUEST_SET_CARRIER_RESTRICTIONS, + * RIL_REQUEST_SET_CARRIER_RESTRICTIONS and RIL_UNSOL_PCO_DATA. + * + * RIL_VERSION = 15 : New commands added: + * RIL_UNSOL_MODEM_RESTART, + * RIL_REQUEST_SEND_DEVICE_STATE, + * RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, + * RIL_REQUEST_SET_SIM_CARD_POWER, + * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, + * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION + * The new parameters for RIL_REQUEST_SETUP_DATA_CALL, + * Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15 + * New data structure RIL_DataRegistrationStateResponse, + * RIL_VoiceRegistrationStateResponse same is + * used in RIL_REQUEST_DATA_REGISTRATION_STATE and + * RIL_REQUEST_VOICE_REGISTRATION_STATE respectively. + * New data structure RIL_OpenChannelParams. + * RIL_REQUEST_START_NETWORK_SCAN + * RIL_REQUEST_STOP_NETWORK_SCAN + * RIL_UNSOL_NETWORK_SCAN_RESULT + */ +#define RIL_VERSION 12 +#define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name +#define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ + +#define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 +#define CDMA_NUMBER_INFO_BUFFER_LENGTH 81 + +#define MAX_RILDS 3 +#define MAX_SERVICE_NAME_LENGTH 6 +#define MAX_CLIENT_ID_LENGTH 2 +#define MAX_DEBUG_SOCKET_NAME_LENGTH 12 +#define MAX_QEMU_PIPE_NAME_LENGTH 11 +#define MAX_UUID_LENGTH 64 +#define MAX_BANDS 8 +#define MAX_CHANNELS 32 +#define MAX_RADIO_ACCESS_NETWORKS 8 + + +typedef void * RIL_Token; + +typedef enum { + RIL_SOCKET_1, +#if (SIM_COUNT >= 2) + RIL_SOCKET_2, +#if (SIM_COUNT >= 3) + RIL_SOCKET_3, +#endif +#if (SIM_COUNT >= 4) + RIL_SOCKET_4, +#endif +#endif + RIL_SOCKET_NUM +} RIL_SOCKET_ID; + + +typedef enum { + RIL_E_SUCCESS = 0, + RIL_E_RADIO_NOT_AVAILABLE = 1, /* If radio did not start or is resetting */ + RIL_E_GENERIC_FAILURE = 2, + RIL_E_PASSWORD_INCORRECT = 3, /* for PIN/PIN2 methods only! */ + RIL_E_SIM_PIN2 = 4, /* Operation requires SIM PIN2 to be entered */ + RIL_E_SIM_PUK2 = 5, /* Operation requires SIM PIN2 to be entered */ + RIL_E_REQUEST_NOT_SUPPORTED = 6, + RIL_E_CANCELLED = 7, + RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, /* data ops are not allowed during voice + call on a Class C GPRS device */ + RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9, /* data ops are not allowed before device + registers in network */ + RIL_E_SMS_SEND_FAIL_RETRY = 10, /* fail to send sms and need retry */ + RIL_E_SIM_ABSENT = 11, /* fail to set the location where CDMA subscription + shall be retrieved because of SIM or RUIM + card absent */ + RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12, /* fail to find CDMA subscription from specified + location */ + RIL_E_MODE_NOT_SUPPORTED = 13, /* HW does not support preferred network type */ + RIL_E_FDN_CHECK_FAILURE = 14, /* command failed because recipient is not on FDN list */ + RIL_E_ILLEGAL_SIM_OR_ME = 15, /* network selection failed due to + illegal SIM or ME */ + RIL_E_MISSING_RESOURCE = 16, /* no logical channel available */ + RIL_E_NO_SUCH_ELEMENT = 17, /* application not found on SIM */ + RIL_E_DIAL_MODIFIED_TO_USSD = 18, /* DIAL request modified to USSD */ + RIL_E_DIAL_MODIFIED_TO_SS = 19, /* DIAL request modified to SS */ + RIL_E_DIAL_MODIFIED_TO_DIAL = 20, /* DIAL request modified to DIAL with different + data */ + RIL_E_USSD_MODIFIED_TO_DIAL = 21, /* USSD request modified to DIAL */ + RIL_E_USSD_MODIFIED_TO_SS = 22, /* USSD request modified to SS */ + RIL_E_USSD_MODIFIED_TO_USSD = 23, /* USSD request modified to different USSD + request */ + RIL_E_SS_MODIFIED_TO_DIAL = 24, /* SS request modified to DIAL */ + RIL_E_SS_MODIFIED_TO_USSD = 25, /* SS request modified to USSD */ + RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26, /* Subscription not supported by RIL */ + RIL_E_SS_MODIFIED_TO_SS = 27, /* SS request modified to different SS request */ + RIL_E_LCE_NOT_SUPPORTED = 36, /* LCE service not supported(36 in RILConstants.java) */ + RIL_E_NO_MEMORY = 37, /* Not sufficient memory to process the request */ + RIL_E_INTERNAL_ERR = 38, /* Modem hit unexpected error scenario while handling + this request */ + RIL_E_SYSTEM_ERR = 39, /* Hit platform or system error */ + RIL_E_MODEM_ERR = 40, /* Vendor RIL got unexpected or incorrect response + from modem for this request */ + RIL_E_INVALID_STATE = 41, /* Unexpected request for the current state */ + RIL_E_NO_RESOURCES = 42, /* Not sufficient resource to process the request */ + RIL_E_SIM_ERR = 43, /* Received error from SIM card */ + RIL_E_INVALID_ARGUMENTS = 44, /* Received invalid arguments in request */ + RIL_E_INVALID_SIM_STATE = 45, /* Can not process the request in current SIM state */ + RIL_E_INVALID_MODEM_STATE = 46, /* Can not process the request in current Modem state */ + RIL_E_INVALID_CALL_ID = 47, /* Received invalid call id in request */ + RIL_E_NO_SMS_TO_ACK = 48, /* ACK received when there is no SMS to ack */ + RIL_E_NETWORK_ERR = 49, /* Received error from network */ + RIL_E_REQUEST_RATE_LIMITED = 50, /* Operation denied due to overly-frequent requests */ + RIL_E_SIM_BUSY = 51, /* SIM is busy */ + RIL_E_SIM_FULL = 52, /* The target EF is full */ + RIL_E_NETWORK_REJECT = 53, /* Request is rejected by network */ + RIL_E_OPERATION_NOT_ALLOWED = 54, /* Not allowed the request now */ + RIL_E_EMPTY_RECORD = 55, /* The request record is empty */ + RIL_E_INVALID_SMS_FORMAT = 56, /* Invalid sms format */ + RIL_E_ENCODING_ERR = 57, /* Message not encoded properly */ + RIL_E_INVALID_SMSC_ADDRESS = 58, /* SMSC address specified is invalid */ + RIL_E_NO_SUCH_ENTRY = 59, /* No such entry present to perform the request */ + RIL_E_NETWORK_NOT_READY = 60, /* Network is not ready to perform the request */ + RIL_E_NOT_PROVISIONED = 61, /* Device doesnot have this value provisioned */ + RIL_E_NO_SUBSCRIPTION = 62, /* Device doesnot have subscription */ + RIL_E_NO_NETWORK_FOUND = 63, /* Network cannot be found */ + RIL_E_DEVICE_IN_USE = 64, /* Operation cannot be performed because the device + is currently in use */ + RIL_E_ABORTED = 65, /* Operation aborted */ + RIL_E_INVALID_RESPONSE = 66, /* Invalid response sent by vendor code */ + // OEM specific error codes. To be used by OEM when they don't want to reveal + // specific error codes which would be replaced by Generic failure. + RIL_E_OEM_ERROR_1 = 501, + RIL_E_OEM_ERROR_2 = 502, + RIL_E_OEM_ERROR_3 = 503, + RIL_E_OEM_ERROR_4 = 504, + RIL_E_OEM_ERROR_5 = 505, + RIL_E_OEM_ERROR_6 = 506, + RIL_E_OEM_ERROR_7 = 507, + RIL_E_OEM_ERROR_8 = 508, + RIL_E_OEM_ERROR_9 = 509, + RIL_E_OEM_ERROR_10 = 510, + RIL_E_OEM_ERROR_11 = 511, + RIL_E_OEM_ERROR_12 = 512, + RIL_E_OEM_ERROR_13 = 513, + RIL_E_OEM_ERROR_14 = 514, + RIL_E_OEM_ERROR_15 = 515, + RIL_E_OEM_ERROR_16 = 516, + RIL_E_OEM_ERROR_17 = 517, + RIL_E_OEM_ERROR_18 = 518, + RIL_E_OEM_ERROR_19 = 519, + RIL_E_OEM_ERROR_20 = 520, + RIL_E_OEM_ERROR_21 = 521, + RIL_E_OEM_ERROR_22 = 522, + RIL_E_OEM_ERROR_23 = 523, + RIL_E_OEM_ERROR_24 = 524, + RIL_E_OEM_ERROR_25 = 525 +} RIL_Errno; + +typedef enum { + RIL_CALL_ACTIVE = 0, + RIL_CALL_HOLDING = 1, + RIL_CALL_DIALING = 2, /* MO call only */ + RIL_CALL_ALERTING = 3, /* MO call only */ + RIL_CALL_INCOMING = 4, /* MT call only */ + RIL_CALL_WAITING = 5 /* MT call only */ +} RIL_CallState; + +typedef enum { + RADIO_STATE_OFF = 0, /* Radio explictly powered off (eg CFUN=0) */ + RADIO_STATE_UNAVAILABLE = 1, /* Radio unavailable (eg, resetting or not booted) */ + RADIO_STATE_ON = 10 /* Radio is on */ +} RIL_RadioState; + +typedef enum { + RADIO_TECH_UNKNOWN = 0, + RADIO_TECH_GPRS = 1, + RADIO_TECH_EDGE = 2, + RADIO_TECH_UMTS = 3, + RADIO_TECH_IS95A = 4, + RADIO_TECH_IS95B = 5, + RADIO_TECH_1xRTT = 6, + RADIO_TECH_EVDO_0 = 7, + RADIO_TECH_EVDO_A = 8, + RADIO_TECH_HSDPA = 9, + RADIO_TECH_HSUPA = 10, + RADIO_TECH_HSPA = 11, + RADIO_TECH_EVDO_B = 12, + RADIO_TECH_EHRPD = 13, + RADIO_TECH_LTE = 14, + RADIO_TECH_HSPAP = 15, // HSPA+ + RADIO_TECH_GSM = 16, // Only supports voice + RADIO_TECH_TD_SCDMA = 17, + RADIO_TECH_IWLAN = 18, + RADIO_TECH_LTE_CA = 19 +} RIL_RadioTechnology; + +typedef enum { + RAF_UNKNOWN = (1 << RADIO_TECH_UNKNOWN), + RAF_GPRS = (1 << RADIO_TECH_GPRS), + RAF_EDGE = (1 << RADIO_TECH_EDGE), + RAF_UMTS = (1 << RADIO_TECH_UMTS), + RAF_IS95A = (1 << RADIO_TECH_IS95A), + RAF_IS95B = (1 << RADIO_TECH_IS95B), + RAF_1xRTT = (1 << RADIO_TECH_1xRTT), + RAF_EVDO_0 = (1 << RADIO_TECH_EVDO_0), + RAF_EVDO_A = (1 << RADIO_TECH_EVDO_A), + RAF_HSDPA = (1 << RADIO_TECH_HSDPA), + RAF_HSUPA = (1 << RADIO_TECH_HSUPA), + RAF_HSPA = (1 << RADIO_TECH_HSPA), + RAF_EVDO_B = (1 << RADIO_TECH_EVDO_B), + RAF_EHRPD = (1 << RADIO_TECH_EHRPD), + RAF_LTE = (1 << RADIO_TECH_LTE), + RAF_HSPAP = (1 << RADIO_TECH_HSPAP), + RAF_GSM = (1 << RADIO_TECH_GSM), + RAF_TD_SCDMA = (1 << RADIO_TECH_TD_SCDMA), + RAF_LTE_CA = (1 << RADIO_TECH_LTE_CA) +} RIL_RadioAccessFamily; + +typedef enum { + BAND_MODE_UNSPECIFIED = 0, //"unspecified" (selected by baseband automatically) + BAND_MODE_EURO = 1, //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000) + BAND_MODE_USA = 2, //"US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900) + BAND_MODE_JPN = 3, //"JPN band" (WCDMA-800 / WCDMA-IMT-2000) + BAND_MODE_AUS = 4, //"AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000) + BAND_MODE_AUS_2 = 5, //"AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850) + BAND_MODE_CELL_800 = 6, //"Cellular" (800-MHz Band) + BAND_MODE_PCS = 7, //"PCS" (1900-MHz Band) + BAND_MODE_JTACS = 8, //"Band Class 3" (JTACS Band) + BAND_MODE_KOREA_PCS = 9, //"Band Class 4" (Korean PCS Band) + BAND_MODE_5_450M = 10, //"Band Class 5" (450-MHz Band) + BAND_MODE_IMT2000 = 11, //"Band Class 6" (2-GMHz IMT2000 Band) + BAND_MODE_7_700M_2 = 12, //"Band Class 7" (Upper 700-MHz Band) + BAND_MODE_8_1800M = 13, //"Band Class 8" (1800-MHz Band) + BAND_MODE_9_900M = 14, //"Band Class 9" (900-MHz Band) + BAND_MODE_10_800M_2 = 15, //"Band Class 10" (Secondary 800-MHz Band) + BAND_MODE_EURO_PAMR_400M = 16, //"Band Class 11" (400-MHz European PAMR Band) + BAND_MODE_AWS = 17, //"Band Class 15" (AWS Band) + BAND_MODE_USA_2500M = 18 //"Band Class 16" (US 2.5-GHz Band) +} RIL_RadioBandMode; + +typedef enum { + RC_PHASE_CONFIGURED = 0, // LM is configured is initial value and value after FINISH completes + RC_PHASE_START = 1, // START is sent before Apply and indicates that an APPLY will be + // forthcoming with these same parameters + RC_PHASE_APPLY = 2, // APPLY is sent after all LM's receive START and returned + // RIL_RadioCapability.status = 0, if any START's fail no + // APPLY will be sent + RC_PHASE_UNSOL_RSP = 3, // UNSOL_RSP is sent with RIL_UNSOL_RADIO_CAPABILITY + RC_PHASE_FINISH = 4 // FINISH is sent after all commands have completed. If an error + // occurs in any previous command the RIL_RadioAccessesFamily and + // logicalModemUuid fields will be the prior configuration thus + // restoring the configuration to the previous value. An error + // returned by this command will generally be ignored or may + // cause that logical modem to be removed from service. +} RadioCapabilityPhase; + +typedef enum { + RC_STATUS_NONE = 0, // This parameter has no meaning with RC_PHASE_START, + // RC_PHASE_APPLY + RC_STATUS_SUCCESS = 1, // Tell modem the action transaction of set radio + // capability was success with RC_PHASE_FINISH + RC_STATUS_FAIL = 2, // Tell modem the action transaction of set radio + // capability is fail with RC_PHASE_FINISH. +} RadioCapabilityStatus; + +#define RIL_RADIO_CAPABILITY_VERSION 1 +typedef struct { + int version; // Version of structure, RIL_RADIO_CAPABILITY_VERSION + int session; // Unique session value defined by framework returned in all "responses/unsol" + int phase; // CONFIGURED, START, APPLY, FINISH + int rat; // RIL_RadioAccessFamily for the radio + char logicalModemUuid[MAX_UUID_LENGTH]; // A UUID typically "com.xxxx.lmX where X is the logical modem. + int status; // Return status and an input parameter for RC_PHASE_FINISH +} RIL_RadioCapability; + +// Do we want to split Data from Voice and the use +// RIL_RadioTechnology for get/setPreferredVoice/Data ? +typedef enum { + PREF_NET_TYPE_GSM_WCDMA = 0, /* GSM/WCDMA (WCDMA preferred) */ + PREF_NET_TYPE_GSM_ONLY = 1, /* GSM only */ + PREF_NET_TYPE_WCDMA = 2, /* WCDMA */ + PREF_NET_TYPE_GSM_WCDMA_AUTO = 3, /* GSM/WCDMA (auto mode, according to PRL) */ + PREF_NET_TYPE_CDMA_EVDO_AUTO = 4, /* CDMA and EvDo (auto mode, according to PRL) */ + PREF_NET_TYPE_CDMA_ONLY = 5, /* CDMA only */ + PREF_NET_TYPE_EVDO_ONLY = 6, /* EvDo only */ + PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7, /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) */ + PREF_NET_TYPE_LTE_CDMA_EVDO = 8, /* LTE, CDMA and EvDo */ + PREF_NET_TYPE_LTE_GSM_WCDMA = 9, /* LTE, GSM/WCDMA */ + PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */ + PREF_NET_TYPE_LTE_ONLY = 11, /* LTE only */ + PREF_NET_TYPE_LTE_WCDMA = 12, /* LTE/WCDMA */ + PREF_NET_TYPE_TD_SCDMA_ONLY = 13, /* TD-SCDMA only */ + PREF_NET_TYPE_TD_SCDMA_WCDMA = 14, /* TD-SCDMA and WCDMA */ + PREF_NET_TYPE_TD_SCDMA_LTE = 15, /* TD-SCDMA and LTE */ + PREF_NET_TYPE_TD_SCDMA_GSM = 16, /* TD-SCDMA and GSM */ + PREF_NET_TYPE_TD_SCDMA_GSM_LTE = 17, /* TD-SCDMA,GSM and LTE */ + PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA = 18, /* TD-SCDMA, GSM/WCDMA */ + PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE = 19, /* TD-SCDMA, WCDMA and LTE */ + PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE = 20, /* TD-SCDMA, GSM/WCDMA and LTE */ + PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO = 21, /* TD-SCDMA, GSM/WCDMA, CDMA and EvDo */ + PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA = 22 /* TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA */ +} RIL_PreferredNetworkType; + +/* Source for cdma subscription */ +typedef enum { + CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM = 0, + CDMA_SUBSCRIPTION_SOURCE_NV = 1 +} RIL_CdmaSubscriptionSource; + +/* User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 */ +typedef enum { + RIL_UUS_TYPE1_IMPLICIT = 0, + RIL_UUS_TYPE1_REQUIRED = 1, + RIL_UUS_TYPE1_NOT_REQUIRED = 2, + RIL_UUS_TYPE2_REQUIRED = 3, + RIL_UUS_TYPE2_NOT_REQUIRED = 4, + RIL_UUS_TYPE3_REQUIRED = 5, + RIL_UUS_TYPE3_NOT_REQUIRED = 6 +} RIL_UUS_Type; + +/* User-to-User Signaling Information data coding schemes. Possible values for + * Octet 3 (Protocol Discriminator field) in the UUIE. The values have been + * specified in section 10.5.4.25 of 3GPP TS 24.008 */ +typedef enum { + RIL_UUS_DCS_USP = 0, /* User specified protocol */ + RIL_UUS_DCS_OSIHLP = 1, /* OSI higher layer protocol */ + RIL_UUS_DCS_X244 = 2, /* X.244 */ + RIL_UUS_DCS_RMCF = 3, /* Reserved for system mangement + convergence function */ + RIL_UUS_DCS_IA5c = 4 /* IA5 characters */ +} RIL_UUS_DCS; + +/* User-to-User Signaling Information defined in 3GPP 23.087 v8.0 + * This data is passed in RIL_ExtensionRecord and rec contains this + * structure when type is RIL_UUS_INFO_EXT_REC */ +typedef struct { + RIL_UUS_Type uusType; /* UUS Type */ + RIL_UUS_DCS uusDcs; /* UUS Data Coding Scheme */ + int uusLength; /* Length of UUS Data */ + char * uusData; /* UUS Data */ +} RIL_UUS_Info; + +/* CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 */ +typedef struct { + char isPresent; /* non-zero if signal information record is present */ + char signalType; /* as defined 3.7.5.5-1 */ + char alertPitch; /* as defined 3.7.5.5-2 */ + char signal; /* as defined 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 */ +} RIL_CDMA_SignalInfoRecord; + +typedef struct { + RIL_CallState state; + int index; /* Connection Index for use with, eg, AT+CHLD */ + int toa; /* type of address, eg 145 = intl */ + char isMpty; /* nonzero if is mpty call */ + char isMT; /* nonzero if call is mobile terminated */ + char als; /* ALS line indicator if available + (0 = line 1) */ + char isVoice; /* nonzero if this is is a voice call */ + char isVoicePrivacy; /* nonzero if CDMA voice privacy mode is active */ + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ + char * name; /* Remote party name */ + int namePresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */ + RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ +} RIL_Call; + +/* Deprecated, use RIL_Data_Call_Response_v6 */ +typedef struct { + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". */ + char * apn; /* ignored */ + char * address; /* An address, e.g., "192.0.1.3" or "2001:db8::1". */ +} RIL_Data_Call_Response_v4; + +/* + * Returned by RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_DATA_CALL_LIST + * and RIL_UNSOL_DATA_CALL_LIST_CHANGED, on error status != 0. + */ +typedef struct { + int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ + int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry + back-off timer value RIL wants to override the one + pre-configured in FW. + The unit is miliseconds. + The value < 0 means no value is suggested. + The value 0 means retry should be done ASAP. + The value of INT_MAX(0x7fffffff) means no retry. */ + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported + such as "IP" or "IPV6" */ + char * ifname; /* The network interface name */ + char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, + e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". + May not be empty, typically 1 IPv4 or 1 IPv6 or + one of each. If the prefix length is absent the addresses + are assumed to be point to point with IPv4 having a prefix + length of 32 and IPv6 128. */ + char * dnses; /* A space-delimited list of DNS server addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty. */ + char * gateways; /* A space-delimited list of default gateway addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty in which case the addresses represent point + to point connections. */ +} RIL_Data_Call_Response_v6; + +typedef struct { + int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ + int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry + back-off timer value RIL wants to override the one + pre-configured in FW. + The unit is miliseconds. + The value < 0 means no value is suggested. + The value 0 means retry should be done ASAP. + The value of INT_MAX(0x7fffffff) means no retry. */ + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported + such as "IP" or "IPV6" */ + char * ifname; /* The network interface name */ + char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, + e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". + May not be empty, typically 1 IPv4 or 1 IPv6 or + one of each. If the prefix length is absent the addresses + are assumed to be point to point with IPv4 having a prefix + length of 32 and IPv6 128. */ + char * dnses; /* A space-delimited list of DNS server addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty. */ + char * gateways; /* A space-delimited list of default gateway addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty in which case the addresses represent point + to point connections. */ + char * pcscf; /* the Proxy Call State Control Function address + via PCO(Protocol Configuration Option) for IMS client. */ +} RIL_Data_Call_Response_v9; + +typedef struct { + int status; /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */ + int suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry + back-off timer value RIL wants to override the one + pre-configured in FW. + The unit is miliseconds. + The value < 0 means no value is suggested. + The value 0 means retry should be done ASAP. + The value of INT_MAX(0x7fffffff) means no retry. */ + int cid; /* Context ID, uniquely identifies this call */ + int active; /* 0=inactive, 1=active/physical link down, 2=active/physical link up */ + char * type; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported + such as "IP" or "IPV6" */ + char * ifname; /* The network interface name */ + char * addresses; /* A space-delimited list of addresses with optional "/" prefix length, + e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64". + May not be empty, typically 1 IPv4 or 1 IPv6 or + one of each. If the prefix length is absent the addresses + are assumed to be point to point with IPv4 having a prefix + length of 32 and IPv6 128. */ + char * dnses; /* A space-delimited list of DNS server addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty. */ + char * gateways; /* A space-delimited list of default gateway addresses, + e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1". + May be empty in which case the addresses represent point + to point connections. */ + char * pcscf; /* the Proxy Call State Control Function address + via PCO(Protocol Configuration Option) for IMS client. */ + int mtu; /* MTU received from network + Value <= 0 means network has either not sent a value or + sent an invalid value */ +} RIL_Data_Call_Response_v11; + +typedef enum { + RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */ + RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */ +} RIL_RadioTechnologyFamily; + +typedef struct { + RIL_RadioTechnologyFamily tech; + unsigned char retry; /* 0 == not retry, nonzero == retry */ + int messageRef; /* Valid field if retry is set to nonzero. + Contains messageRef from RIL_SMS_Response + corresponding to failed MO SMS. + */ + + union { + /* Valid field if tech is RADIO_TECH_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */ + RIL_CDMA_SMS_Message* cdmaMessage; + + /* Valid field if tech is RADIO_TECH_3GPP. See RIL_REQUEST_SEND_SMS */ + char** gsmMessage; /* This is an array of pointers where pointers + are contiguous but elements pointed by those pointers + are not contiguous + */ + } message; +} RIL_IMS_SMS_Message; + +typedef struct { + int messageRef; /* TP-Message-Reference for GSM, + and BearerData MessageId for CDMA + (See 3GPP2 C.S0015-B, v2.0, table 4.5-1). */ + char *ackPDU; /* or NULL if n/a */ + int errorCode; /* See 3GPP 27.005, 3.2.5 for GSM/UMTS, + 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, + -1 if unknown or not applicable*/ +} RIL_SMS_Response; + +/** Used by RIL_REQUEST_WRITE_SMS_TO_SIM */ +typedef struct { + int status; /* Status of message. See TS 27.005 3.1, "": */ + /* 0 = "REC UNREAD" */ + /* 1 = "REC READ" */ + /* 2 = "STO UNSENT" */ + /* 3 = "STO SENT" */ + char * pdu; /* PDU of message to write, as an ASCII hex string less the SMSC address, + the TP-layer length is "strlen(pdu)/2". */ + char * smsc; /* SMSC address in GSM BCD format prefixed by a length byte + (as expected by TS 27.005) or NULL for default SMSC */ +} RIL_SMS_WriteArgs; + +/** Used by RIL_REQUEST_DIAL */ +typedef struct { + char * address; + int clir; + /* (same as 'n' paremeter in TS 27.007 7.7 "+CLIR" + * clir == 0 on "use subscription default value" + * clir == 1 on "CLIR invocation" (restrict CLI presentation) + * clir == 2 on "CLIR suppression" (allow CLI presentation) + */ + RIL_UUS_Info * uusInfo; /* NULL or Pointer to User-User Signaling Information */ +} RIL_Dial; + +typedef struct { + int command; /* one of the commands listed for TS 27.007 +CRSM*/ + int fileid; /* EF id */ + char *path; /* "pathid" from TS 27.007 +CRSM command. + Path is in hex asciii format eg "7f205f70" + Path must always be provided. + */ + int p1; + int p2; + int p3; + char *data; /* May be NULL*/ + char *pin2; /* May be NULL*/ +} RIL_SIM_IO_v5; + +typedef struct { + int command; /* one of the commands listed for TS 27.007 +CRSM*/ + int fileid; /* EF id */ + char *path; /* "pathid" from TS 27.007 +CRSM command. + Path is in hex asciii format eg "7f205f70" + Path must always be provided. + */ + int p1; + int p2; + int p3; + char *data; /* May be NULL*/ + char *pin2; /* May be NULL*/ + char *aidPtr; /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */ +} RIL_SIM_IO_v6; + +/* Used by RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL and + * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC. */ +typedef struct { + int sessionid; /* "sessionid" from TS 27.007 +CGLA command. Should be + ignored for +CSIM command. */ + + /* Following fields are used to derive the APDU ("command" and "length" + values in TS 27.007 +CSIM and +CGLA commands). */ + int cla; + int instruction; + int p1; + int p2; + int p3; /* A negative P3 implies a 4 byte APDU. */ + char *data; /* May be NULL. In hex string format. */ +} RIL_SIM_APDU; + +typedef struct { + int sw1; + int sw2; + char *simResponse; /* In hex string format ([a-fA-F0-9]*), except for SIM_AUTHENTICATION + response for which it is in Base64 format, see 3GPP TS 31.102 7.1.2 */ +} RIL_SIM_IO_Response; + +/* See also com.android.internal.telephony.gsm.CallForwardInfo */ + +typedef struct { + int status; /* + * For RIL_REQUEST_QUERY_CALL_FORWARD_STATUS + * status 1 = active, 0 = not active + * + * For RIL_REQUEST_SET_CALL_FORWARD: + * status is: + * 0 = disable + * 1 = enable + * 2 = interrogate + * 3 = registeration + * 4 = erasure + */ + + int reason; /* from TS 27.007 7.11 "reason" */ + int serviceClass;/* From 27.007 +CCFC/+CLCK "class" + See table for Android mapping from + MMI service code + 0 means user doesn't input class */ + int toa; /* "type" from TS 27.007 7.11 */ + char * number; /* "number" from TS 27.007 7.11. May be NULL */ + int timeSeconds; /* for CF no reply only */ +}RIL_CallForwardInfo; + +typedef struct { + char * cid; /* Combination of LAC and Cell Id in 32 bits in GSM. + * Upper 16 bits is LAC and lower 16 bits + * is CID (as described in TS 27.005) + * Primary Scrambling Code (as described in TS 25.331) + * in 9 bits in UMTS + * Valid values are hexadecimal 0x0000 - 0xffffffff. + */ + int rssi; /* Received RSSI in GSM, + * Level index of CPICH Received Signal Code Power in UMTS + */ +} RIL_NeighboringCell; + +typedef struct { + char lce_status; /* LCE service status: + * -1 = not supported; + * 0 = stopped; + * 1 = active. + */ + unsigned int actual_interval_ms; /* actual LCE reporting interval, + * meaningful only if LCEStatus = 1. + */ +} RIL_LceStatusInfo; + +typedef struct { + unsigned int last_hop_capacity_kbps; /* last-hop cellular capacity: kilobits/second. */ + unsigned char confidence_level; /* capacity estimate confidence: 0-100 */ + unsigned char lce_suspended; /* LCE report going to be suspended? (e.g., radio + * moves to inactive state or network type change) + * 1 = suspended; + * 0 = not suspended. + */ +} RIL_LceDataInfo; + +typedef enum { + RIL_MATCH_ALL = 0, /* Apply to all carriers with the same mcc/mnc */ + RIL_MATCH_SPN = 1, /* Use SPN and mcc/mnc to identify the carrier */ + RIL_MATCH_IMSI_PREFIX = 2, /* Use IMSI prefix and mcc/mnc to identify the carrier */ + RIL_MATCH_GID1 = 3, /* Use GID1 and mcc/mnc to identify the carrier */ + RIL_MATCH_GID2 = 4, /* Use GID2 and mcc/mnc to identify the carrier */ +} RIL_CarrierMatchType; + +typedef struct { + const char * mcc; + const char * mnc; + RIL_CarrierMatchType match_type; /* Specify match type for the carrier. + * If it’s RIL_MATCH_ALL, match_data is null; + * otherwise, match_data is the value for the match type. + */ + const char * match_data; +} RIL_Carrier; + +typedef struct { + int32_t len_allowed_carriers; /* length of array allowed_carriers */ + int32_t len_excluded_carriers; /* length of array excluded_carriers */ + RIL_Carrier * allowed_carriers; /* whitelist for allowed carriers */ + RIL_Carrier * excluded_carriers; /* blacklist for explicitly excluded carriers + * which match allowed_carriers. Eg. allowed_carriers match + * mcc/mnc, excluded_carriers has same mcc/mnc and gid1 + * is ABCD. It means except the carrier whose gid1 is ABCD, + * all carriers with the same mcc/mnc are allowed. + */ +} RIL_CarrierRestrictions; + +typedef struct { + char * mcc; /* MCC of the Carrier. */ + char * mnc ; /* MNC of the Carrier. */ + uint8_t * carrierKey; /* Public Key from the Carrier used to encrypt the + * IMSI/IMPI. + */ + char * keyIdentifier; /* The keyIdentifier Attribute value pair that helps + * a server locate the private key to decrypt the + * permanent identity. + */ + int64_t expirationTime; /* Date-Time (in UTC) when the key will expire. */ + +} RIL_CarrierInfoForImsiEncryption; + +/* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */ +typedef enum { + CALL_FAIL_UNOBTAINABLE_NUMBER = 1, + CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3, + CALL_FAIL_CHANNEL_UNACCEPTABLE = 6, + CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8, + CALL_FAIL_NORMAL = 16, + CALL_FAIL_BUSY = 17, + CALL_FAIL_NO_USER_RESPONDING = 18, + CALL_FAIL_NO_ANSWER_FROM_USER = 19, + CALL_FAIL_CALL_REJECTED = 21, + CALL_FAIL_NUMBER_CHANGED = 22, + CALL_FAIL_PREEMPTION = 25, + CALL_FAIL_DESTINATION_OUT_OF_ORDER = 27, + CALL_FAIL_INVALID_NUMBER_FORMAT = 28, + CALL_FAIL_FACILITY_REJECTED = 29, + CALL_FAIL_RESP_TO_STATUS_ENQUIRY = 30, + CALL_FAIL_NORMAL_UNSPECIFIED = 31, + CALL_FAIL_CONGESTION = 34, + CALL_FAIL_NETWORK_OUT_OF_ORDER = 38, + CALL_FAIL_TEMPORARY_FAILURE = 41, + CALL_FAIL_SWITCHING_EQUIPMENT_CONGESTION = 42, + CALL_FAIL_ACCESS_INFORMATION_DISCARDED = 43, + CALL_FAIL_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44, + CALL_FAIL_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47, + CALL_FAIL_QOS_UNAVAILABLE = 49, + CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50, + CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55, + CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57, + CALL_FAIL_BEARER_CAPABILITY_UNAVAILABLE = 58, + CALL_FAIL_SERVICE_OPTION_NOT_AVAILABLE = 63, + CALL_FAIL_BEARER_SERVICE_NOT_IMPLEMENTED = 65, + CALL_FAIL_ACM_LIMIT_EXCEEDED = 68, + CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69, + CALL_FAIL_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70, + CALL_FAIL_SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79, + CALL_FAIL_INVALID_TRANSACTION_IDENTIFIER = 81, + CALL_FAIL_USER_NOT_MEMBER_OF_CUG = 87, + CALL_FAIL_INCOMPATIBLE_DESTINATION = 88, + CALL_FAIL_INVALID_TRANSIT_NW_SELECTION = 91, + CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95, + CALL_FAIL_INVALID_MANDATORY_INFORMATION = 96, + CALL_FAIL_MESSAGE_TYPE_NON_IMPLEMENTED = 97, + CALL_FAIL_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98, + CALL_FAIL_INFORMATION_ELEMENT_NON_EXISTENT = 99, + CALL_FAIL_CONDITIONAL_IE_ERROR = 100, + CALL_FAIL_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101, + CALL_FAIL_RECOVERY_ON_TIMER_EXPIRED = 102, + CALL_FAIL_PROTOCOL_ERROR_UNSPECIFIED = 111, + CALL_FAIL_INTERWORKING_UNSPECIFIED = 127, + CALL_FAIL_CALL_BARRED = 240, + CALL_FAIL_FDN_BLOCKED = 241, + CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242, + CALL_FAIL_IMEI_NOT_ACCEPTED = 243, + CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244, /* STK Call Control */ + CALL_FAIL_DIAL_MODIFIED_TO_SS = 245, + CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246, + CALL_FAIL_RADIO_OFF = 247, /* Radio is OFF */ + CALL_FAIL_OUT_OF_SERVICE = 248, /* No cellular coverage */ + CALL_FAIL_NO_VALID_SIM = 249, /* No valid SIM is present */ + CALL_FAIL_RADIO_INTERNAL_ERROR = 250, /* Internal error at Modem */ + CALL_FAIL_NETWORK_RESP_TIMEOUT = 251, /* No response from network */ + CALL_FAIL_NETWORK_REJECT = 252, /* Explicit network reject */ + CALL_FAIL_RADIO_ACCESS_FAILURE = 253, /* RRC connection failure. Eg.RACH */ + CALL_FAIL_RADIO_LINK_FAILURE = 254, /* Radio Link Failure */ + CALL_FAIL_RADIO_LINK_LOST = 255, /* Radio link lost due to poor coverage */ + CALL_FAIL_RADIO_UPLINK_FAILURE = 256, /* Radio uplink failure */ + CALL_FAIL_RADIO_SETUP_FAILURE = 257, /* RRC connection setup failure */ + CALL_FAIL_RADIO_RELEASE_NORMAL = 258, /* RRC connection release, normal */ + CALL_FAIL_RADIO_RELEASE_ABNORMAL = 259, /* RRC connection release, abnormal */ + CALL_FAIL_ACCESS_CLASS_BLOCKED = 260, /* Access class barring */ + CALL_FAIL_NETWORK_DETACH = 261, /* Explicit network detach */ + CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000, + CALL_FAIL_CDMA_DROP = 1001, + CALL_FAIL_CDMA_INTERCEPT = 1002, + CALL_FAIL_CDMA_REORDER = 1003, + CALL_FAIL_CDMA_SO_REJECT = 1004, + CALL_FAIL_CDMA_RETRY_ORDER = 1005, + CALL_FAIL_CDMA_ACCESS_FAILURE = 1006, + CALL_FAIL_CDMA_PREEMPTED = 1007, + CALL_FAIL_CDMA_NOT_EMERGENCY = 1008, /* For non-emergency number dialed + during emergency callback mode */ + CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009, /* CDMA network access probes blocked */ + + /* OEM specific error codes. Used to distinguish error from + * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging */ + CALL_FAIL_OEM_CAUSE_1 = 0xf001, + CALL_FAIL_OEM_CAUSE_2 = 0xf002, + CALL_FAIL_OEM_CAUSE_3 = 0xf003, + CALL_FAIL_OEM_CAUSE_4 = 0xf004, + CALL_FAIL_OEM_CAUSE_5 = 0xf005, + CALL_FAIL_OEM_CAUSE_6 = 0xf006, + CALL_FAIL_OEM_CAUSE_7 = 0xf007, + CALL_FAIL_OEM_CAUSE_8 = 0xf008, + CALL_FAIL_OEM_CAUSE_9 = 0xf009, + CALL_FAIL_OEM_CAUSE_10 = 0xf00a, + CALL_FAIL_OEM_CAUSE_11 = 0xf00b, + CALL_FAIL_OEM_CAUSE_12 = 0xf00c, + CALL_FAIL_OEM_CAUSE_13 = 0xf00d, + CALL_FAIL_OEM_CAUSE_14 = 0xf00e, + CALL_FAIL_OEM_CAUSE_15 = 0xf00f, + + CALL_FAIL_ERROR_UNSPECIFIED = 0xffff /* This error will be deprecated soon, + vendor code should make sure to map error + code to specific error */ +} RIL_LastCallFailCause; + +typedef struct { + RIL_LastCallFailCause cause_code; + char * vendor_cause; +} RIL_LastCallFailCauseInfo; + +/* See RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */ +typedef enum { + PDP_FAIL_NONE = 0, /* No error, connection ok */ + + /* an integer cause code defined in TS 24.008 + section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B. + If the implementation does not have access to the exact cause codes, + then it should return one of the following values, + as the UI layer needs to distinguish these + cases for error notification and potential retries. */ + PDP_FAIL_OPERATOR_BARRED = 0x08, /* no retry */ + PDP_FAIL_NAS_SIGNALLING = 0x0E, + PDP_FAIL_LLC_SNDCP = 0x19, + PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A, + PDP_FAIL_MISSING_UKNOWN_APN = 0x1B, /* no retry */ + PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C, /* no retry */ + PDP_FAIL_USER_AUTHENTICATION = 0x1D, /* no retry */ + PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E, /* no retry */ + PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F, + PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20, /* no retry */ + PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */ + PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22, + PDP_FAIL_NSAPI_IN_USE = 0x23, /* no retry */ + PDP_FAIL_REGULAR_DEACTIVATION = 0x24, /* possibly restart radio, + based on framework config */ + PDP_FAIL_QOS_NOT_ACCEPTED = 0x25, + PDP_FAIL_NETWORK_FAILURE = 0x26, + PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27, + PDP_FAIL_FEATURE_NOT_SUPP = 0x28, + PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29, + PDP_FAIL_TFT_SYTAX_ERROR = 0x2A, + PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B, + PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C, + PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D, + PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E, + PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32, /* no retry */ + PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33, /* no retry */ + PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34, + PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35, + PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36, + PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37, + PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41, + PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42, + PDP_FAIL_INVALID_TRANSACTION_ID = 0x51, + PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F, + PDP_FAIL_INVALID_MANDATORY_INFO = 0x60, + PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61, + PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62, + PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63, + PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64, + PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65, + PDP_FAIL_PROTOCOL_ERRORS = 0x6F, /* no retry */ + PDP_FAIL_APN_TYPE_CONFLICT = 0x70, + PDP_FAIL_INVALID_PCSCF_ADDR = 0x71, + PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72, + PDP_FAIL_EMM_ACCESS_BARRED = 0x73, + PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74, + PDP_FAIL_IFACE_MISMATCH = 0x75, + PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76, + PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77, + PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78, + PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79, + PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A, + + // OEM specific error codes. To be used by OEMs when they don't want to + // reveal error code which would be replaced by PDP_FAIL_ERROR_UNSPECIFIED + PDP_FAIL_OEM_DCFAILCAUSE_1 = 0x1001, + PDP_FAIL_OEM_DCFAILCAUSE_2 = 0x1002, + PDP_FAIL_OEM_DCFAILCAUSE_3 = 0x1003, + PDP_FAIL_OEM_DCFAILCAUSE_4 = 0x1004, + PDP_FAIL_OEM_DCFAILCAUSE_5 = 0x1005, + PDP_FAIL_OEM_DCFAILCAUSE_6 = 0x1006, + PDP_FAIL_OEM_DCFAILCAUSE_7 = 0x1007, + PDP_FAIL_OEM_DCFAILCAUSE_8 = 0x1008, + PDP_FAIL_OEM_DCFAILCAUSE_9 = 0x1009, + PDP_FAIL_OEM_DCFAILCAUSE_10 = 0x100A, + PDP_FAIL_OEM_DCFAILCAUSE_11 = 0x100B, + PDP_FAIL_OEM_DCFAILCAUSE_12 = 0x100C, + PDP_FAIL_OEM_DCFAILCAUSE_13 = 0x100D, + PDP_FAIL_OEM_DCFAILCAUSE_14 = 0x100E, + PDP_FAIL_OEM_DCFAILCAUSE_15 = 0x100F, + + /* Not mentioned in the specification */ + PDP_FAIL_VOICE_REGISTRATION_FAIL = -1, + PDP_FAIL_DATA_REGISTRATION_FAIL = -2, + + /* reasons for data call drop - network/modem disconnect */ + PDP_FAIL_SIGNAL_LOST = -3, + PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry + with parameters appropriate for new technology */ + PDP_FAIL_RADIO_POWER_OFF = -5, /* data call was disconnected because radio was resetting, + powered off - no retry */ + PDP_FAIL_TETHERED_CALL_ACTIVE = -6, /* data call was disconnected by modem because tethered + mode was up on same APN/data profile - no retry until + tethered call is off */ + + PDP_FAIL_ERROR_UNSPECIFIED = 0xffff, /* retry silently. Will be deprecated soon as + new error codes are added making this unnecessary */ +} RIL_DataCallFailCause; + +/* See RIL_REQUEST_SETUP_DATA_CALL */ +typedef enum { + RIL_DATA_PROFILE_DEFAULT = 0, + RIL_DATA_PROFILE_TETHERED = 1, + RIL_DATA_PROFILE_IMS = 2, + RIL_DATA_PROFILE_FOTA = 3, + RIL_DATA_PROFILE_CBS = 4, + RIL_DATA_PROFILE_OEM_BASE = 1000, /* Start of OEM-specific profiles */ + RIL_DATA_PROFILE_INVALID = 0xFFFFFFFF +} RIL_DataProfile; + +/* Used by RIL_UNSOL_SUPP_SVC_NOTIFICATION */ +typedef struct { + int notificationType; /* + * 0 = MO intermediate result code + * 1 = MT unsolicited result code + */ + int code; /* See 27.007 7.17 + "code1" for MO + "code2" for MT. */ + int index; /* CUG index. See 27.007 7.17. */ + int type; /* "type" from 27.007 7.17 (MT only). */ + char * number; /* "number" from 27.007 7.17 + (MT only, may be NULL). */ +} RIL_SuppSvcNotification; + +#define RIL_CARD_MAX_APPS 8 + +typedef enum { + RIL_CARDSTATE_ABSENT = 0, + RIL_CARDSTATE_PRESENT = 1, + RIL_CARDSTATE_ERROR = 2, + RIL_CARDSTATE_RESTRICTED = 3 /* card is present but not usable due to carrier restrictions.*/ +} RIL_CardState; + +typedef enum { + RIL_PERSOSUBSTATE_UNKNOWN = 0, /* initial state */ + RIL_PERSOSUBSTATE_IN_PROGRESS = 1, /* in between each lock transition */ + RIL_PERSOSUBSTATE_READY = 2, /* when either SIM or RUIM Perso is finished + since each app can only have 1 active perso + involved */ + RIL_PERSOSUBSTATE_SIM_NETWORK = 3, + RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET = 4, + RIL_PERSOSUBSTATE_SIM_CORPORATE = 5, + RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER = 6, + RIL_PERSOSUBSTATE_SIM_SIM = 7, + RIL_PERSOSUBSTATE_SIM_NETWORK_PUK = 8, /* The corresponding perso lock is blocked */ + RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK = 9, + RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK = 10, + RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK = 11, + RIL_PERSOSUBSTATE_SIM_SIM_PUK = 12, + RIL_PERSOSUBSTATE_RUIM_NETWORK1 = 13, + RIL_PERSOSUBSTATE_RUIM_NETWORK2 = 14, + RIL_PERSOSUBSTATE_RUIM_HRPD = 15, + RIL_PERSOSUBSTATE_RUIM_CORPORATE = 16, + RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER = 17, + RIL_PERSOSUBSTATE_RUIM_RUIM = 18, + RIL_PERSOSUBSTATE_RUIM_NETWORK1_PUK = 19, /* The corresponding perso lock is blocked */ + RIL_PERSOSUBSTATE_RUIM_NETWORK2_PUK = 20, + RIL_PERSOSUBSTATE_RUIM_HRPD_PUK = 21, + RIL_PERSOSUBSTATE_RUIM_CORPORATE_PUK = 22, + RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23, + RIL_PERSOSUBSTATE_RUIM_RUIM_PUK = 24 +} RIL_PersoSubstate; + +typedef enum { + RIL_APPSTATE_UNKNOWN = 0, + RIL_APPSTATE_DETECTED = 1, + RIL_APPSTATE_PIN = 2, /* If PIN1 or UPin is required */ + RIL_APPSTATE_PUK = 3, /* If PUK1 or Puk for UPin is required */ + RIL_APPSTATE_SUBSCRIPTION_PERSO = 4, /* perso_substate should be look at + when app_state is assigned to this value */ + RIL_APPSTATE_READY = 5 +} RIL_AppState; + +typedef enum { + RIL_PINSTATE_UNKNOWN = 0, + RIL_PINSTATE_ENABLED_NOT_VERIFIED = 1, + RIL_PINSTATE_ENABLED_VERIFIED = 2, + RIL_PINSTATE_DISABLED = 3, + RIL_PINSTATE_ENABLED_BLOCKED = 4, + RIL_PINSTATE_ENABLED_PERM_BLOCKED = 5 +} RIL_PinState; + +typedef enum { + RIL_APPTYPE_UNKNOWN = 0, + RIL_APPTYPE_SIM = 1, + RIL_APPTYPE_USIM = 2, + RIL_APPTYPE_RUIM = 3, + RIL_APPTYPE_CSIM = 4, + RIL_APPTYPE_ISIM = 5 +} RIL_AppType; + +/* + * Please note that registration state UNKNOWN is + * treated as "out of service" in the Android telephony. + * Registration state REG_DENIED must be returned if Location Update + * Reject (with cause 17 - Network Failure) is received + * repeatedly from the network, to facilitate + * "managed roaming" + */ +typedef enum { + RIL_NOT_REG_AND_NOT_SEARCHING = 0, // Not registered, MT is not currently searching + // a new operator to register + RIL_REG_HOME = 1, // Registered, home network + RIL_NOT_REG_AND_SEARCHING = 2, // Not registered, but MT is currently searching + // a new operator to register + RIL_REG_DENIED = 3, // Registration denied + RIL_UNKNOWN = 4, // Unknown + RIL_REG_ROAMING = 5, // Registered, roaming + RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_NOT_SEARCHING = 10, // Same as + // RIL_NOT_REG_AND_NOT_SEARCHING but indicates that + // emergency calls are enabled. + RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_SEARCHING = 12, // Same as RIL_NOT_REG_AND_SEARCHING + // but indicates that + // emergency calls are enabled. + RIL_REG_DENIED_AND_EMERGENCY_AVAILABLE = 13, // Same as REG_DENIED but indicates that + // emergency calls are enabled. + RIL_UNKNOWN_AND_EMERGENCY_AVAILABLE = 14, // Same as UNKNOWN but indicates that + // emergency calls are enabled. +} RIL_RegState; + +typedef struct +{ + RIL_AppType app_type; + RIL_AppState app_state; + RIL_PersoSubstate perso_substate; /* applicable only if app_state == + RIL_APPSTATE_SUBSCRIPTION_PERSO */ + char *aid_ptr; /* null terminated string, e.g., from 0xA0, 0x00 -> 0x41, + 0x30, 0x30, 0x30 */ + char *app_label_ptr; /* null terminated string */ + int pin1_replaced; /* applicable to USIM, CSIM & ISIM */ + RIL_PinState pin1; + RIL_PinState pin2; +} RIL_AppStatus; + +/* Deprecated, use RIL_CardStatus_v6 */ +typedef struct +{ + RIL_CardState card_state; + RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ + int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int num_applications; /* value <= RIL_CARD_MAX_APPS */ + RIL_AppStatus applications[RIL_CARD_MAX_APPS]; +} RIL_CardStatus_v5; + +typedef struct +{ + RIL_CardState card_state; + RIL_PinState universal_pin_state; /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */ + int gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int cdma_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int ims_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */ + int num_applications; /* value <= RIL_CARD_MAX_APPS */ + RIL_AppStatus applications[RIL_CARD_MAX_APPS]; +} RIL_CardStatus_v6; + +/** The result of a SIM refresh, returned in data[0] of RIL_UNSOL_SIM_REFRESH + * or as part of RIL_SimRefreshResponse_v7 + */ +typedef enum { + /* A file on SIM has been updated. data[1] contains the EFID. */ + SIM_FILE_UPDATE = 0, + /* SIM initialized. All files should be re-read. */ + SIM_INIT = 1, + /* SIM reset. SIM power required, SIM may be locked and all files should be re-read. */ + SIM_RESET = 2 +} RIL_SimRefreshResult; + +typedef struct { + RIL_SimRefreshResult result; + int ef_id; /* is the EFID of the updated file if the result is */ + /* SIM_FILE_UPDATE or 0 for any other result. */ + char * aid; /* is AID(application ID) of the card application */ + /* See ETSI 102.221 8.1 and 101.220 4 */ + /* For SIM_FILE_UPDATE result it can be set to AID of */ + /* application in which updated EF resides or it can be */ + /* NULL if EF is outside of an application. */ + /* For SIM_INIT result this field is set to AID of */ + /* application that caused REFRESH */ + /* For SIM_RESET result it is NULL. */ +} RIL_SimRefreshResponse_v7; + +/* Deprecated, use RIL_CDMA_CallWaiting_v6 */ +typedef struct { + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ + char * name; /* Remote party name */ + RIL_CDMA_SignalInfoRecord signalInfoRecord; +} RIL_CDMA_CallWaiting_v5; + +typedef struct { + char * number; /* Remote party number */ + int numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */ + char * name; /* Remote party name */ + RIL_CDMA_SignalInfoRecord signalInfoRecord; + /* Number type/Number plan required to support International Call Waiting */ + int number_type; /* 0=Unknown, 1=International, 2=National, + 3=Network specific, 4=subscriber */ + int number_plan; /* 0=Unknown, 1=ISDN, 3=Data, 4=Telex, 8=Nat'l, 9=Private */ +} RIL_CDMA_CallWaiting_v6; + +/** + * Which types of Cell Broadcast Message (CBM) are to be received by the ME + * + * uFromServiceID - uToServiceID defines a range of CBM message identifiers + * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS + * and 9.4.4.2.2 for UMTS. All other values can be treated as empty + * CBM message ID. + * + * uFromCodeScheme - uToCodeScheme defines a range of CBM data coding schemes + * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS + * and 9.4.4.2.3 for UMTS. + * All other values can be treated as empty CBM data coding scheme. + * + * selected 0 means message types specified in + * and are not accepted, while 1 means accepted. + * + * Used by RIL_REQUEST_GSM_GET_BROADCAST_CONFIG and + * RIL_REQUEST_GSM_SET_BROADCAST_CONFIG. + */ +typedef struct { + int fromServiceId; + int toServiceId; + int fromCodeScheme; + int toCodeScheme; + unsigned char selected; +} RIL_GSM_BroadcastSmsConfigInfo; + +/* No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. */ +#define RIL_RESTRICTED_STATE_NONE 0x00 +/* Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. */ +#define RIL_RESTRICTED_STATE_CS_EMERGENCY 0x01 +/* Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. */ +#define RIL_RESTRICTED_STATE_CS_NORMAL 0x02 +/* Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction.*/ +#define RIL_RESTRICTED_STATE_CS_ALL 0x04 +/* Block packet data access due to restriction. */ +#define RIL_RESTRICTED_STATE_PS_ALL 0x10 + +/* The status for an OTASP/OTAPA session */ +typedef enum { + CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED, + CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED, + CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED, + CDMA_OTA_PROVISION_STATUS_SSD_UPDATED, + CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED, + CDMA_OTA_PROVISION_STATUS_COMMITTED, + CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED, + CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED, + CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED +} RIL_CDMA_OTA_ProvisionStatus; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ +} RIL_GW_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ + int timingAdvance; /* Timing Advance in bit periods. 1 bit period = 48/13 us. + * INT_MAX denotes invalid value */ +} RIL_GSM_SignalStrength_v12; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int bitErrorRate; /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */ +} RIL_SignalStrengthWcdma; + +typedef struct { + int dbm; /* Valid values are positive integers. This value is the actual RSSI value + * multiplied by -1. Example: If the actual RSSI is -75, then this response + * value will be 75. + */ + int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied + * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value + * will be 125. + */ +} RIL_CDMA_SignalStrength; + + +typedef struct { + int dbm; /* Valid values are positive integers. This value is the actual RSSI value + * multiplied by -1. Example: If the actual RSSI is -75, then this response + * value will be 75. + */ + int ecio; /* Valid values are positive integers. This value is the actual Ec/Io multiplied + * by -10. Example: If the actual Ec/Io is -12.5 dB, then this response value + * will be 125. + */ + int signalNoiseRatio; /* Valid values are 0-8. 8 is the highest signal to noise ratio. */ +} RIL_EVDO_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. + * Range: 44 to 140 dBm + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.4 */ + int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. + * Range: 20 to 3 dB. + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.7 */ + int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. + * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 8.1.1 */ + int cqi; /* The current Channel Quality Indicator. + * Range: 0 to 15. + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ +} RIL_LTE_SignalStrength; + +typedef struct { + int signalStrength; /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */ + int rsrp; /* The current Reference Signal Receive Power in dBm multipled by -1. + * Range: 44 to 140 dBm + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.4 */ + int rsrq; /* The current Reference Signal Receive Quality in dB multiplied by -1. + * Range: 20 to 3 dB. + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.133 9.1.7 */ + int rssnr; /* The current reference signal signal-to-noise ratio in 0.1 dB units. + * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB). + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 8.1.1 */ + int cqi; /* The current Channel Quality Indicator. + * Range: 0 to 15. + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */ + int timingAdvance; /* timing advance in micro seconds for a one way trip from cell to device. + * Approximate distance can be calculated using 300m/us * timingAdvance. + * Range: 0 to 0x7FFFFFFE + * INT_MAX : 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP 36.321 section 6.1.3.5 + * also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html */ +} RIL_LTE_SignalStrength_v8; + +typedef struct { + int rscp; /* The Received Signal Code Power in dBm multipled by -1. + * Range : 25 to 120 + * INT_MAX: 0x7FFFFFFF denotes invalid value. + * Reference: 3GPP TS 25.123, section 9.1.1.1 */ +} RIL_TD_SCDMA_SignalStrength; + +/* Deprecated, use RIL_SignalStrength_v6 */ +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; +} RIL_SignalStrength_v5; + +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; + RIL_LTE_SignalStrength LTE_SignalStrength; +} RIL_SignalStrength_v6; + +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; + RIL_LTE_SignalStrength_v8 LTE_SignalStrength; +} RIL_SignalStrength_v8; + +typedef struct { + RIL_GW_SignalStrength GW_SignalStrength; + RIL_CDMA_SignalStrength CDMA_SignalStrength; + RIL_EVDO_SignalStrength EVDO_SignalStrength; + RIL_LTE_SignalStrength_v8 LTE_SignalStrength; + RIL_TD_SCDMA_SignalStrength TD_SCDMA_SignalStrength; +} RIL_SignalStrength_v10; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ +} RIL_CellIdentityGsm; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown */ + int arfcn; /* 16-bit GSM Absolute RF channel number; this value must be reported */ + uint8_t bsic; /* 6-bit Base Station Identity Code; 0xFF if unknown */ +} RIL_CellIdentityGsm_v12; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ + int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */ +} RIL_CellIdentityWcdma; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ + int psc; /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511; this value must be reported */ + int uarfcn; /* 16-bit UMTS Absolute RF Channel Number; this value must be reported */ +} RIL_CellIdentityWcdma_v12; + +typedef struct { + int networkId; /* Network Id 0..65535, INT_MAX if unknown */ + int systemId; /* CDMA System Id 0..32767, INT_MAX if unknown */ + int basestationId; /* Base Station Id 0..65535, INT_MAX if unknown */ + int longitude; /* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * It is represented in units of 0.25 seconds and ranges from -2592000 + * to 2592000, both values inclusive (corresponding to a range of -180 + * to +180 degrees). INT_MAX if unknown */ + + int latitude; /* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0. + * It is represented in units of 0.25 seconds and ranges from -1296000 + * to 1296000, both values inclusive (corresponding to a range of -90 + * to +90 degrees). INT_MAX if unknown */ +} RIL_CellIdentityCdma; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ + int pci; /* physical cell id 0..503, INT_MAX if unknown */ + int tac; /* 16-bit tracking area code, INT_MAX if unknown */ +} RIL_CellIdentityLte; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int ci; /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */ + int pci; /* physical cell id 0..503; this value must be reported */ + int tac; /* 16-bit tracking area code, INT_MAX if unknown */ + int earfcn; /* 18-bit LTE Absolute RF Channel Number; this value must be reported */ +} RIL_CellIdentityLte_v12; + +typedef struct { + int mcc; /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */ + int mnc; /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */ + int lac; /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown */ + int cid; /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown */ + int cpid; /* 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown */ +} RIL_CellIdentityTdscdma; + +typedef struct { + RIL_CellIdentityGsm cellIdentityGsm; + RIL_GW_SignalStrength signalStrengthGsm; +} RIL_CellInfoGsm; + +typedef struct { + RIL_CellIdentityGsm_v12 cellIdentityGsm; + RIL_GSM_SignalStrength_v12 signalStrengthGsm; +} RIL_CellInfoGsm_v12; + +typedef struct { + RIL_CellIdentityWcdma cellIdentityWcdma; + RIL_SignalStrengthWcdma signalStrengthWcdma; +} RIL_CellInfoWcdma; + +typedef struct { + RIL_CellIdentityWcdma_v12 cellIdentityWcdma; + RIL_SignalStrengthWcdma signalStrengthWcdma; +} RIL_CellInfoWcdma_v12; + +typedef struct { + RIL_CellIdentityCdma cellIdentityCdma; + RIL_CDMA_SignalStrength signalStrengthCdma; + RIL_EVDO_SignalStrength signalStrengthEvdo; +} RIL_CellInfoCdma; + +typedef struct { + RIL_CellIdentityLte cellIdentityLte; + RIL_LTE_SignalStrength_v8 signalStrengthLte; +} RIL_CellInfoLte; + +typedef struct { + RIL_CellIdentityLte_v12 cellIdentityLte; + RIL_LTE_SignalStrength_v8 signalStrengthLte; +} RIL_CellInfoLte_v12; + +typedef struct { + RIL_CellIdentityTdscdma cellIdentityTdscdma; + RIL_TD_SCDMA_SignalStrength signalStrengthTdscdma; +} RIL_CellInfoTdscdma; + +// Must be the same as CellInfo.TYPE_XXX +typedef enum { + RIL_CELL_INFO_TYPE_NONE = 0, /* indicates no cell information */ + RIL_CELL_INFO_TYPE_GSM = 1, + RIL_CELL_INFO_TYPE_CDMA = 2, + RIL_CELL_INFO_TYPE_LTE = 3, + RIL_CELL_INFO_TYPE_WCDMA = 4, + RIL_CELL_INFO_TYPE_TD_SCDMA = 5 +} RIL_CellInfoType; + +// Must be the same as CellInfo.TIMESTAMP_TYPE_XXX +typedef enum { + RIL_TIMESTAMP_TYPE_UNKNOWN = 0, + RIL_TIMESTAMP_TYPE_ANTENNA = 1, + RIL_TIMESTAMP_TYPE_MODEM = 2, + RIL_TIMESTAMP_TYPE_OEM_RIL = 3, + RIL_TIMESTAMP_TYPE_JAVA_RIL = 4, +} RIL_TimeStampType; + +typedef struct { + RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ + int registered; /* !0 if this cell is registered 0 if not registered */ + RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ + uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ + union { + RIL_CellInfoGsm gsm; + RIL_CellInfoCdma cdma; + RIL_CellInfoLte lte; + RIL_CellInfoWcdma wcdma; + RIL_CellInfoTdscdma tdscdma; + } CellInfo; +} RIL_CellInfo; + +typedef struct { + RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ + int registered; /* !0 if this cell is registered 0 if not registered */ + RIL_TimeStampType timeStampType; /* type of time stamp represented by timeStamp */ + uint64_t timeStamp; /* Time in nanos as returned by ril_nano_time */ + union { + RIL_CellInfoGsm_v12 gsm; + RIL_CellInfoCdma cdma; + RIL_CellInfoLte_v12 lte; + RIL_CellInfoWcdma_v12 wcdma; + RIL_CellInfoTdscdma tdscdma; + } CellInfo; +} RIL_CellInfo_v12; + +typedef struct { + RIL_CellInfoType cellInfoType; /* cell type for selecting from union CellInfo */ + union { + RIL_CellIdentityGsm_v12 cellIdentityGsm; + RIL_CellIdentityWcdma_v12 cellIdentityWcdma; + RIL_CellIdentityLte_v12 cellIdentityLte; + RIL_CellIdentityTdscdma cellIdentityTdscdma; + RIL_CellIdentityCdma cellIdentityCdma; + }; +}RIL_CellIdentity_v16; + +typedef struct { + RIL_RegState regState; // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING, + // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED, + // UNKNOWN, REG_ROAMING defined in RegState + RIL_RadioTechnology rat; // indicates the available voice radio technology, + // valid values as defined by RadioTechnology. + int32_t cssSupported; // concurrent services support indicator. if + // registered on a CDMA system. + // 0 - Concurrent services not supported, + // 1 - Concurrent services supported + int32_t roamingIndicator; // TSB-58 Roaming Indicator if registered + // on a CDMA or EVDO system or -1 if not. + // Valid values are 0-255. + int32_t systemIsInPrl; // indicates whether the current system is in the + // PRL if registered on a CDMA or EVDO system or -1 if + // not. 0=not in the PRL, 1=in the PRL + int32_t defaultRoamingIndicator; // default Roaming Indicator from the PRL, + // if registered on a CDMA or EVDO system or -1 if not. + // Valid values are 0-255. + int32_t reasonForDenial; // reasonForDenial if registration state is 3 + // (Registration denied) this is an enumerated reason why + // registration was denied. See 3GPP TS 24.008, + // 10.5.3.6 and Annex G. + // 0 - General + // 1 - Authentication Failure + // 2 - IMSI unknown in HLR + // 3 - Illegal MS + // 4 - Illegal ME + // 5 - PLMN not allowed + // 6 - Location area not allowed + // 7 - Roaming not allowed + // 8 - No Suitable Cells in this Location Area + // 9 - Network failure + // 10 - Persistent location update reject + // 11 - PLMN not allowed + // 12 - Location area not allowed + // 13 - Roaming not allowed in this Location Area + // 15 - No Suitable Cells in this Location Area + // 17 - Network Failure + // 20 - MAC Failure + // 21 - Sync Failure + // 22 - Congestion + // 23 - GSM Authentication unacceptable + // 25 - Not Authorized for this CSG + // 32 - Service option not supported + // 33 - Requested service option not subscribed + // 34 - Service option temporarily out of order + // 38 - Call cannot be identified + // 48-63 - Retry upon entry into a new cell + // 95 - Semantically incorrect message + // 96 - Invalid mandatory information + // 97 - Message type non-existent or not implemented + // 98 - Message type not compatible with protocol state + // 99 - Information element non-existent or + // not implemented + // 100 - Conditional IE error + // 101 - Message not compatible with protocol state; + RIL_CellIdentity_v16 cellIdentity; // current cell information +}RIL_VoiceRegistrationStateResponse; + + +typedef struct { + RIL_RegState regState; // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING, + // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED, + // UNKNOWN, REG_ROAMING defined in RegState + RIL_RadioTechnology rat; // indicates the available data radio technology, + // valid values as defined by RadioTechnology. + int32_t reasonDataDenied; // if registration state is 3 (Registration + // denied) this is an enumerated reason why + // registration was denied. See 3GPP TS 24.008, + // Annex G.6 "Additional cause codes for GMM". + // 7 == GPRS services not allowed + // 8 == GPRS services and non-GPRS services not allowed + // 9 == MS identity cannot be derived by the network + // 10 == Implicitly detached + // 14 == GPRS services not allowed in this PLMN + // 16 == MSC temporarily not reachable + // 40 == No PDP context activated + int32_t maxDataCalls; // The maximum number of simultaneous Data Calls that + // must be established using setupDataCall(). + RIL_CellIdentity_v16 cellIdentity; // Current cell information +}RIL_DataRegistrationStateResponse; + +/* Names of the CDMA info records (C.S0005 section 3.7.5) */ +typedef enum { + RIL_CDMA_DISPLAY_INFO_REC, + RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC, + RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC, + RIL_CDMA_CONNECTED_NUMBER_INFO_REC, + RIL_CDMA_SIGNAL_INFO_REC, + RIL_CDMA_REDIRECTING_NUMBER_INFO_REC, + RIL_CDMA_LINE_CONTROL_INFO_REC, + RIL_CDMA_EXTENDED_DISPLAY_INFO_REC, + RIL_CDMA_T53_CLIR_INFO_REC, + RIL_CDMA_T53_RELEASE_INFO_REC, + RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC +} RIL_CDMA_InfoRecName; + +/* Display Info Rec as defined in C.S0005 section 3.7.5.1 + Extended Display Info Rec as defined in C.S0005 section 3.7.5.16 + Note: the Extended Display info rec contains multiple records of the + form: display_tag, display_len, and display_len occurrences of the + chari field if the display_tag is not 10000000 or 10000001. + To save space, the records are stored consecutively in a byte buffer. + The display_tag, display_len and chari fields are all 1 byte. +*/ + +typedef struct { + char alpha_len; + char alpha_buf[CDMA_ALPHA_INFO_BUFFER_LENGTH]; +} RIL_CDMA_DisplayInfoRecord; + +/* Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2 + Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3 + Connected Number Info Rec as defined in C.S0005 section 3.7.5.4 +*/ + +typedef struct { + char len; + char buf[CDMA_NUMBER_INFO_BUFFER_LENGTH]; + char number_type; + char number_plan; + char pi; + char si; +} RIL_CDMA_NumberInfoRecord; + +/* Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 */ +typedef enum { + RIL_REDIRECTING_REASON_UNKNOWN = 0, + RIL_REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1, + RIL_REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2, + RIL_REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9, + RIL_REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10, + RIL_REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15, + RIL_REDIRECTING_REASON_RESERVED +} RIL_CDMA_RedirectingReason; + +typedef struct { + RIL_CDMA_NumberInfoRecord redirectingNumber; + /* redirectingReason is set to RIL_REDIRECTING_REASON_UNKNOWN if not included */ + RIL_CDMA_RedirectingReason redirectingReason; +} RIL_CDMA_RedirectingNumberInfoRecord; + +/* Line Control Information Record as defined in C.S0005 section 3.7.5.15 */ +typedef struct { + char lineCtrlPolarityIncluded; + char lineCtrlToggle; + char lineCtrlReverse; + char lineCtrlPowerDenial; +} RIL_CDMA_LineControlInfoRecord; + +/* T53 CLIR Information Record */ +typedef struct { + char cause; +} RIL_CDMA_T53_CLIRInfoRecord; + +/* T53 Audio Control Information Record */ +typedef struct { + char upLink; + char downLink; +} RIL_CDMA_T53_AudioControlInfoRecord; + +typedef struct { + + RIL_CDMA_InfoRecName name; + + union { + /* Display and Extended Display Info Rec */ + RIL_CDMA_DisplayInfoRecord display; + + /* Called Party Number, Calling Party Number, Connected Number Info Rec */ + RIL_CDMA_NumberInfoRecord number; + + /* Signal Info Rec */ + RIL_CDMA_SignalInfoRecord signal; + + /* Redirecting Number Info Rec */ + RIL_CDMA_RedirectingNumberInfoRecord redir; + + /* Line Control Info Rec */ + RIL_CDMA_LineControlInfoRecord lineCtrl; + + /* T53 CLIR Info Rec */ + RIL_CDMA_T53_CLIRInfoRecord clir; + + /* T53 Audio Control Info Rec */ + RIL_CDMA_T53_AudioControlInfoRecord audioCtrl; + } rec; +} RIL_CDMA_InformationRecord; + +#define RIL_CDMA_MAX_NUMBER_OF_INFO_RECS 10 + +typedef struct { + char numberOfInfoRecs; + RIL_CDMA_InformationRecord infoRec[RIL_CDMA_MAX_NUMBER_OF_INFO_RECS]; +} RIL_CDMA_InformationRecords; + +/* See RIL_REQUEST_NV_READ_ITEM */ +typedef struct { + RIL_NV_Item itemID; +} RIL_NV_ReadItem; + +/* See RIL_REQUEST_NV_WRITE_ITEM */ +typedef struct { + RIL_NV_Item itemID; + char * value; +} RIL_NV_WriteItem; + +typedef enum { + HANDOVER_STARTED = 0, + HANDOVER_COMPLETED = 1, + HANDOVER_FAILED = 2, + HANDOVER_CANCELED = 3 +} RIL_SrvccState; + +/* hardware configuration reported to RILJ. */ +typedef enum { + RIL_HARDWARE_CONFIG_MODEM = 0, + RIL_HARDWARE_CONFIG_SIM = 1, +} RIL_HardwareConfig_Type; + +typedef enum { + RIL_HARDWARE_CONFIG_STATE_ENABLED = 0, + RIL_HARDWARE_CONFIG_STATE_STANDBY = 1, + RIL_HARDWARE_CONFIG_STATE_DISABLED = 2, +} RIL_HardwareConfig_State; + +typedef struct { + int rilModel; + uint32_t rat; /* bitset - ref. RIL_RadioTechnology. */ + int maxVoice; + int maxData; + int maxStandby; +} RIL_HardwareConfig_Modem; + +typedef struct { + char modemUuid[MAX_UUID_LENGTH]; +} RIL_HardwareConfig_Sim; + +typedef struct { + RIL_HardwareConfig_Type type; + char uuid[MAX_UUID_LENGTH]; + RIL_HardwareConfig_State state; + union { + RIL_HardwareConfig_Modem modem; + RIL_HardwareConfig_Sim sim; + } cfg; +} RIL_HardwareConfig; + +typedef enum { + SS_CFU, + SS_CF_BUSY, + SS_CF_NO_REPLY, + SS_CF_NOT_REACHABLE, + SS_CF_ALL, + SS_CF_ALL_CONDITIONAL, + SS_CLIP, + SS_CLIR, + SS_COLP, + SS_COLR, + SS_WAIT, + SS_BAOC, + SS_BAOIC, + SS_BAOIC_EXC_HOME, + SS_BAIC, + SS_BAIC_ROAMING, + SS_ALL_BARRING, + SS_OUTGOING_BARRING, + SS_INCOMING_BARRING +} RIL_SsServiceType; + +typedef enum { + SS_ACTIVATION, + SS_DEACTIVATION, + SS_INTERROGATION, + SS_REGISTRATION, + SS_ERASURE +} RIL_SsRequestType; + +typedef enum { + SS_ALL_TELE_AND_BEARER_SERVICES, + SS_ALL_TELESEVICES, + SS_TELEPHONY, + SS_ALL_DATA_TELESERVICES, + SS_SMS_SERVICES, + SS_ALL_TELESERVICES_EXCEPT_SMS +} RIL_SsTeleserviceType; + +#define SS_INFO_MAX 4 +#define NUM_SERVICE_CLASSES 7 + +typedef struct { + int numValidIndexes; /* This gives the number of valid values in cfInfo. + For example if voice is forwarded to one number and data + is forwarded to a different one then numValidIndexes will be + 2 indicating total number of valid values in cfInfo. + Similarly if all the services are forwarded to the same + number then the value of numValidIndexes will be 1. */ + + RIL_CallForwardInfo cfInfo[NUM_SERVICE_CLASSES]; /* This is the response data + for SS request to query call + forward status. see + RIL_REQUEST_QUERY_CALL_FORWARD_STATUS */ +} RIL_CfData; + +typedef struct { + RIL_SsServiceType serviceType; + RIL_SsRequestType requestType; + RIL_SsTeleserviceType teleserviceType; + int serviceClass; + RIL_Errno result; + + union { + int ssInfo[SS_INFO_MAX]; /* This is the response data for most of the SS GET/SET + RIL requests. E.g. RIL_REQUSET_GET_CLIR returns + two ints, so first two values of ssInfo[] will be + used for response if serviceType is SS_CLIR and + requestType is SS_INTERROGATION */ + + RIL_CfData cfData; + }; +} RIL_StkCcUnsolSsResponse; + +/** + * Data connection power state + */ +typedef enum { + RIL_DC_POWER_STATE_LOW = 1, // Low power state + RIL_DC_POWER_STATE_MEDIUM = 2, // Medium power state + RIL_DC_POWER_STATE_HIGH = 3, // High power state + RIL_DC_POWER_STATE_UNKNOWN = INT32_MAX // Unknown state +} RIL_DcPowerStates; + +/** + * Data connection real time info + */ +typedef struct { + uint64_t time; // Time in nanos as returned by ril_nano_time + RIL_DcPowerStates powerState; // Current power state +} RIL_DcRtInfo; + +/** + * Data profile to modem + */ +typedef struct { + /* id of the data profile */ + int profileId; + /* the APN to connect to */ + char* apn; + /** one of the PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + */ + char* protocol; + /** authentication protocol used for this PDP context + * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) + */ + int authType; + /* the username for APN, or NULL */ + char* user; + /* the password for APN, or NULL */ + char* password; + /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */ + int type; + /* the period in seconds to limit the maximum connections */ + int maxConnsTime; + /* the maximum connections during maxConnsTime */ + int maxConns; + /** the required wait time in seconds after a successful UE initiated + * disconnect of a given PDN connection before the device can send + * a new PDN connection request for that given PDN + */ + int waitTime; + /* true to enable the profile, 0 to disable, 1 to enable */ + int enabled; +} RIL_DataProfileInfo; + +typedef struct { + /* id of the data profile */ + int profileId; + /* the APN to connect to */ + char* apn; + /** one of the PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + */ + char* protocol; + /** one of the PDP_type values in TS 27.007 section 10.1.1 used on roaming network. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + */ + char *roamingProtocol; + /** authentication protocol used for this PDP context + * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) + */ + int authType; + /* the username for APN, or NULL */ + char* user; + /* the password for APN, or NULL */ + char* password; + /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */ + int type; + /* the period in seconds to limit the maximum connections */ + int maxConnsTime; + /* the maximum connections during maxConnsTime */ + int maxConns; + /** the required wait time in seconds after a successful UE initiated + * disconnect of a given PDN connection before the device can send + * a new PDN connection request for that given PDN + */ + int waitTime; + /* true to enable the profile, 0 to disable, 1 to enable */ + int enabled; + /* supported APN types bitmask. See RIL_ApnTypes for the value of each bit. */ + int supportedTypesBitmask; + /** the bearer bitmask. See RIL_RadioAccessFamily for the value of each bit. */ + int bearerBitmask; + /** maximum transmission unit (MTU) size in bytes */ + int mtu; + /** the MVNO type: possible values are "imsi", "gid", "spn" */ + char *mvnoType; + /** MVNO match data. Can be anything defined by the carrier. For example, + * SPN like: "A MOBILE", "BEN NL", etc... + * IMSI like: "302720x94", "2060188", etc... + * GID like: "4E", "33", etc... + */ + char *mvnoMatchData; +} RIL_DataProfileInfo_v15; + +/* Tx Power Levels */ +#define RIL_NUM_TX_POWER_LEVELS 5 + +/** + * Aggregate modem activity information + */ +typedef struct { + + /* total time (in ms) when modem is in a low power or + * sleep state + */ + uint32_t sleep_mode_time_ms; + + /* total time (in ms) when modem is awake but neither + * the transmitter nor receiver are active/awake */ + uint32_t idle_mode_time_ms; + + /* total time (in ms) during which the transmitter is active/awake, + * subdivided by manufacturer-defined device-specific + * contiguous increasing ranges of transmit power between + * 0 and the transmitter's maximum transmit power. + */ + uint32_t tx_mode_time_ms[RIL_NUM_TX_POWER_LEVELS]; + + /* total time (in ms) for which receiver is active/awake and + * the transmitter is inactive */ + uint32_t rx_mode_time_ms; +} RIL_ActivityStatsInfo; + +typedef enum { + RIL_APN_TYPE_UNKNOWN = 0x0, // Unknown + RIL_APN_TYPE_DEFAULT = 0x1, // APN type for default data traffic + RIL_APN_TYPE_MMS = 0x2, // APN type for MMS traffic + RIL_APN_TYPE_SUPL = 0x4, // APN type for SUPL assisted GPS + RIL_APN_TYPE_DUN = 0x8, // APN type for DUN traffic + RIL_APN_TYPE_HIPRI = 0x10, // APN type for HiPri traffic + RIL_APN_TYPE_FOTA = 0x20, // APN type for FOTA + RIL_APN_TYPE_IMS = 0x40, // APN type for IMS + RIL_APN_TYPE_CBS = 0x80, // APN type for CBS + RIL_APN_TYPE_IA = 0x100, // APN type for IA Initial Attach APN + RIL_APN_TYPE_EMERGENCY = 0x200, // APN type for Emergency PDN. This is not an IA apn, + // but is used for access to carrier services in an + // emergency call situation. + RIL_APN_TYPE_ALL = 0xFFFFFFFF // All APN types +} RIL_ApnTypes; + +typedef enum { + RIL_DST_POWER_SAVE_MODE, // Device power save mode (provided by PowerManager) + // True indicates the device is in power save mode. + RIL_DST_CHARGING_STATE, // Device charging state (provided by BatteryManager) + // True indicates the device is charging. + RIL_DST_LOW_DATA_EXPECTED // Low data expected mode. True indicates low data traffic + // is expected, for example, when the device is idle + // (e.g. not doing tethering in the background). Note + // this doesn't mean no data is expected. +} RIL_DeviceStateType; + +typedef enum { + RIL_UR_SIGNAL_STRENGTH = 0x01, // When this bit is set, modem should always send the + // signal strength update through + // RIL_UNSOL_SIGNAL_STRENGTH, otherwise suppress it. + RIL_UR_FULL_NETWORK_STATE = 0x02, // When this bit is set, modem should always send + // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED + // when any field in + // RIL_REQUEST_VOICE_REGISTRATION_STATE or + // RIL_REQUEST_DATA_REGISTRATION_STATE changes. When + // this bit is not set, modem should suppress + // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED + // only when insignificant fields change + // (e.g. cell info). + // Modem should continue sending + // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED + // when significant fields are updated even when this + // bit is not set. The following fields are + // considered significant, registration state and + // radio technology. + RIL_UR_DATA_CALL_DORMANCY_CHANGED = 0x04 // When this bit is set, modem should send the data + // call list changed unsolicited response + // RIL_UNSOL_DATA_CALL_LIST_CHANGED whenever any + // field in RIL_Data_Call_Response changes. + // Otherwise modem should suppress the unsolicited + // response when the only changed field is 'active' + // (for data dormancy). For all other fields change, + // modem should continue sending + // RIL_UNSOL_DATA_CALL_LIST_CHANGED regardless this + // bit is set or not. +} RIL_UnsolicitedResponseFilter; + +typedef struct { + char * aidPtr; /* AID value, See ETSI 102.221 and 101.220*/ + int p2; /* P2 parameter (described in ISO 7816-4) + P2Constants:NO_P2 if to be ignored */ +} RIL_OpenChannelParams; + +typedef enum { + RIL_ONE_SHOT = 0x01, // Performs the scan only once + RIL_PERIODIC = 0x02 // Performs the scan periodically until cancelled +} RIL_ScanType; + +typedef enum { + GERAN = 0x01, // GSM EDGE Radio Access Network + UTRAN = 0x02, // Universal Terrestrial Radio Access Network + EUTRAN = 0x03, // Evolved Universal Terrestrial Radio Access Network +} RIL_RadioAccessNetworks; + +typedef enum { + GERAN_BAND_T380 = 1, + GERAN_BAND_T410 = 2, + GERAN_BAND_450 = 3, + GERAN_BAND_480 = 4, + GERAN_BAND_710 = 5, + GERAN_BAND_750 = 6, + GERAN_BAND_T810 = 7, + GERAN_BAND_850 = 8, + GERAN_BAND_P900 = 9, + GERAN_BAND_E900 = 10, + GERAN_BAND_R900 = 11, + GERAN_BAND_DCS1800 = 12, + GERAN_BAND_PCS1900 = 13, + GERAN_BAND_ER900 = 14, +} RIL_GeranBands; + +typedef enum { + UTRAN_BAND_1 = 1, + UTRAN_BAND_2 = 2, + UTRAN_BAND_3 = 3, + UTRAN_BAND_4 = 4, + UTRAN_BAND_5 = 5, + UTRAN_BAND_6 = 6, + UTRAN_BAND_7 = 7, + UTRAN_BAND_8 = 8, + UTRAN_BAND_9 = 9, + UTRAN_BAND_10 = 10, + UTRAN_BAND_11 = 11, + UTRAN_BAND_12 = 12, + UTRAN_BAND_13 = 13, + UTRAN_BAND_14 = 14, + UTRAN_BAND_19 = 19, + UTRAN_BAND_20 = 20, + UTRAN_BAND_21 = 21, + UTRAN_BAND_22 = 22, + UTRAN_BAND_25 = 25, + UTRAN_BAND_26 = 26, +} RIL_UtranBands; + +typedef enum { + EUTRAN_BAND_1 = 1, + EUTRAN_BAND_2 = 2, + EUTRAN_BAND_3 = 3, + EUTRAN_BAND_4 = 4, + EUTRAN_BAND_5 = 5, + EUTRAN_BAND_6 = 6, + EUTRAN_BAND_7 = 7, + EUTRAN_BAND_8 = 8, + EUTRAN_BAND_9 = 9, + EUTRAN_BAND_10 = 10, + EUTRAN_BAND_11 = 11, + EUTRAN_BAND_12 = 12, + EUTRAN_BAND_13 = 13, + EUTRAN_BAND_14 = 14, + EUTRAN_BAND_17 = 17, + EUTRAN_BAND_18 = 18, + EUTRAN_BAND_19 = 19, + EUTRAN_BAND_20 = 20, + EUTRAN_BAND_21 = 21, + EUTRAN_BAND_22 = 22, + EUTRAN_BAND_23 = 23, + EUTRAN_BAND_24 = 24, + EUTRAN_BAND_25 = 25, + EUTRAN_BAND_26 = 26, + EUTRAN_BAND_27 = 27, + EUTRAN_BAND_28 = 28, + EUTRAN_BAND_30 = 30, + EUTRAN_BAND_31 = 31, + EUTRAN_BAND_33 = 33, + EUTRAN_BAND_34 = 34, + EUTRAN_BAND_35 = 35, + EUTRAN_BAND_36 = 36, + EUTRAN_BAND_37 = 37, + EUTRAN_BAND_38 = 38, + EUTRAN_BAND_39 = 39, + EUTRAN_BAND_40 = 40, + EUTRAN_BAND_41 = 41, + EUTRAN_BAND_42 = 42, + EUTRAN_BAND_43 = 43, + EUTRAN_BAND_44 = 44, + EUTRAN_BAND_45 = 45, + EUTRAN_BAND_46 = 46, + EUTRAN_BAND_47 = 47, + EUTRAN_BAND_48 = 48, + EUTRAN_BAND_65 = 65, + EUTRAN_BAND_66 = 66, + EUTRAN_BAND_68 = 68, + EUTRAN_BAND_70 = 70, +} RIL_EutranBands; + +typedef struct { + RIL_RadioAccessNetworks radio_access_network; // The type of network to scan. + uint32_t bands_length; // Length of bands + union { + RIL_GeranBands geran_bands[MAX_BANDS]; + RIL_UtranBands utran_bands[MAX_BANDS]; + RIL_EutranBands eutran_bands[MAX_BANDS]; + } bands; + uint32_t channels_length; // Length of channels + uint32_t channels[MAX_CHANNELS]; // Frequency channels to scan +} RIL_RadioAccessSpecifier; + +typedef struct { + RIL_ScanType type; // Type of the scan + int32_t interval; // Time interval in seconds + // between periodic scans, only + // valid when type=RIL_PERIODIC + uint32_t specifiers_length; // Length of specifiers + RIL_RadioAccessSpecifier specifiers[MAX_RADIO_ACCESS_NETWORKS]; // Radio access networks + // with bands/channels. +} RIL_NetworkScanRequest; + +typedef enum { + PARTIAL = 0x01, // The result contains a part of the scan results + COMPLETE = 0x02, // The result contains the last part of the scan results +} RIL_ScanStatus; + +typedef struct { + RIL_ScanStatus status; // The status of the scan + uint32_t network_infos_length; // Total length of RIL_CellInfo + RIL_CellInfo_v12* network_infos; // List of network information +} RIL_NetworkScanResult; + +/** + * RIL_REQUEST_GET_SIM_STATUS + * + * Requests status of the SIM interface and the SIM card + * + * "data" is NULL + * + * "response" is const RIL_CardStatus_v6 * + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_GET_SIM_STATUS 1 + +/** + * RIL_REQUEST_ENTER_SIM_PIN + * + * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state + * + * "data" is const char ** + * ((const char **)data)[0] is PIN value + * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ENTER_SIM_PIN 2 + +/** + * RIL_REQUEST_ENTER_SIM_PUK + * + * Supplies SIM PUK and new PIN. + * + * "data" is const char ** + * ((const char **)data)[0] is PUK value + * ((const char **)data)[1] is new PIN value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * (PUK is invalid) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ENTER_SIM_PUK 3 + +/** + * RIL_REQUEST_ENTER_SIM_PIN2 + * + * Supplies SIM PIN2. Only called following operation where SIM_PIN2 was + * returned as a a failure from a previous operation. + * + * "data" is const char ** + * ((const char **)data)[0] is PIN2 value + * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ENTER_SIM_PIN2 4 + +/** + * RIL_REQUEST_ENTER_SIM_PUK2 + * + * Supplies SIM PUK2 and new PIN2. + * + * "data" is const char ** + * ((const char **)data)[0] is PUK2 value + * ((const char **)data)[1] is new PIN2 value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * (PUK2 is invalid) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ENTER_SIM_PUK2 5 + +/** + * RIL_REQUEST_CHANGE_SIM_PIN + * + * Supplies old SIM PIN and new PIN. + * + * "data" is const char ** + * ((const char **)data)[0] is old PIN value + * ((const char **)data)[1] is new PIN value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * (old PIN is invalid) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_CHANGE_SIM_PIN 6 + + +/** + * RIL_REQUEST_CHANGE_SIM_PIN2 + * + * Supplies old SIM PIN2 and new PIN2. + * + * "data" is const char ** + * ((const char **)data)[0] is old PIN2 value + * ((const char **)data)[1] is new PIN2 value + * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * (old PIN2 is invalid) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + * + */ + +#define RIL_REQUEST_CHANGE_SIM_PIN2 7 + +/** + * RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION + * + * Requests that network personlization be deactivated + * + * "data" is const char ** + * ((const char **)(data))[0]] is network depersonlization code + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * PASSWORD_INCORRECT + * (code is invalid) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8 + +/** + * RIL_REQUEST_GET_CURRENT_CALLS + * + * Requests current call list + * + * "data" is NULL + * + * "response" must be a "const RIL_Call **" + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * (request will be made again in a few hundred msec) + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_GET_CURRENT_CALLS 9 + + +/** + * RIL_REQUEST_DIAL + * + * Initiate voice call + * + * "data" is const RIL_Dial * + * "response" is NULL + * + * This method is never used for supplementary service codes + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * DIAL_MODIFIED_TO_USSD + * DIAL_MODIFIED_TO_SS + * DIAL_MODIFIED_TO_DIAL + * INVALID_ARGUMENTS + * NO_MEMORY + * INVALID_STATE + * NO_RESOURCES + * INTERNAL_ERR + * FDN_CHECK_FAILURE + * MODEM_ERR + * NO_SUBSCRIPTION + * NO_NETWORK_FOUND + * INVALID_CALL_ID + * DEVICE_IN_USE + * OPERATION_NOT_ALLOWED + * ABORTED + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_DIAL 10 + +/** + * RIL_REQUEST_GET_IMSI + * + * Get the SIM IMSI + * + * Only valid when radio state is "RADIO_STATE_ON" + * + * "data" is const char ** + * ((const char **)data)[0] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * "response" is a const char * containing the IMSI + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_SIM_STATE + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_GET_IMSI 11 + +/** + * RIL_REQUEST_HANGUP + * + * Hang up a specific line (like AT+CHLD=1x) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is an int * + * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_ARGUMENTS + * NO_MEMORY + * INVALID_STATE + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_CALL_ID + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_HANGUP 12 + +/** + * RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND + * + * Hang up waiting or held (like AT+CHLD=0) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_CALL_ID + * NO_RESOURCES + * OPERATION_NOT_ALLOWED + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13 + +/** + * RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND + * + * Hang up waiting or held (like AT+CHLD=1) + * + * After this HANGUP request returns, RIL should show the connection is NOT + * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * OPERATION_NOT_ALLOWED + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14 + +/** + * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE + * + * Switch waiting or holding call and active call (like AT+CHLD=2) + * + * State transitions should be is follows: + * + * If call 1 is waiting and call 2 is active, then if this re + * + * BEFORE AFTER + * Call 1 Call 2 Call 1 Call 2 + * ACTIVE HOLDING HOLDING ACTIVE + * ACTIVE WAITING HOLDING ACTIVE + * HOLDING WAITING HOLDING ACTIVE + * ACTIVE IDLE HOLDING IDLE + * IDLE IDLE IDLE IDLE + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_STATE + * INVALID_ARGUMENTS + * INVALID_CALL_ID + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15 +#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15 + +/** + * RIL_REQUEST_CONFERENCE + * + * Conference holding and active (like AT+CHLD=3) + + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_STATE + * INVALID_CALL_ID + * INVALID_ARGUMENTS + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_CONFERENCE 16 + +/** + * RIL_REQUEST_UDUB + * + * Send UDUB (user determined used busy) to ringing or + * waiting call answer)(RIL_BasicRequest r); + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_RESOURCES + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * OPERATION_NOT_ALLOWED + * INVALID_ARGUMENTS + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_UDUB 17 + +/** + * RIL_REQUEST_LAST_CALL_FAIL_CAUSE + * + * Requests the failure cause code for the most recently terminated call + * + * "data" is NULL + * "response" is a const RIL_LastCallFailCauseInfo * + * RIL_LastCallFailCauseInfo contains LastCallFailCause and vendor cause. + * The vendor cause code must be used for debugging purpose only. + * The implementation must return one of the values of LastCallFailCause + * as mentioned below. + * + * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H + * where possible. + * CDMA failure reasons codes for the possible call failure scenarios + * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard. + * Any of the following reason codes if the call is failed or dropped due to reason + * mentioned with in the braces. + * + * CALL_FAIL_RADIO_OFF (Radio is OFF) + * CALL_FAIL_OUT_OF_SERVICE (No cell coverage) + * CALL_FAIL_NO_VALID_SIM (No valid SIM) + * CALL_FAIL_RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario) + * CALL_FAIL_NETWORK_RESP_TIMEOUT (No response from network) + * CALL_FAIL_NETWORK_REJECT (Explicit network reject) + * CALL_FAIL_RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH) + * CALL_FAIL_RADIO_LINK_FAILURE (Radio Link Failure) + * CALL_FAIL_RADIO_LINK_LOST (Radio link lost due to poor coverage) + * CALL_FAIL_RADIO_UPLINK_FAILURE (Radio uplink failure) + * CALL_FAIL_RADIO_SETUP_FAILURE (RRC connection setup failure) + * CALL_FAIL_RADIO_RELEASE_NORMAL (RRC connection release, normal) + * CALL_FAIL_RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal) + * CALL_FAIL_ACCESS_CLASS_BLOCKED (Access class barring) + * CALL_FAIL_NETWORK_DETACH (Explicit network detach) + * + * OEM causes (CALL_FAIL_OEM_CAUSE_XX) must be used for debug purpose only + * + * If the implementation does not have access to the exact cause codes, + * then it should return one of the values listed in RIL_LastCallFailCause, + * as the UI layer needs to distinguish these cases for tone generation or + * error notification. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE + */ +#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18 + +/** + * RIL_REQUEST_SIGNAL_STRENGTH + * + * Requests current signal strength and associated information + * + * Must succeed if radio is on. + * + * "data" is NULL + * + * "response" is a const RIL_SignalStrength * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SIGNAL_STRENGTH 19 + +/** + * RIL_REQUEST_VOICE_REGISTRATION_STATE + * + * Request current registration state + * + * "data" is NULL + * "response" is a const RIL_VoiceRegistrationStateResponse * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20 + +/** + * RIL_REQUEST_DATA_REGISTRATION_STATE + * + * Request current DATA registration state + * + * "data" is NULL + * "response" is a const RIL_DataRegistrationStateResponse * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_DATA_REGISTRATION_STATE 21 + +/** + * RIL_REQUEST_OPERATOR + * + * Request current operator ONS or EONS + * + * "data" is NULL + * "response" is a "const char **" + * ((const char **)response)[0] is long alpha ONS or EONS + * or NULL if unregistered + * + * ((const char **)response)[1] is short alpha ONS or EONS + * or NULL if unregistered + * ((const char **)response)[2] is 5 or 6 digit numeric code (MCC + MNC) + * or NULL if unregistered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_OPERATOR 22 + +/** + * RIL_REQUEST_RADIO_POWER + * + * Toggle radio on and off (for "airplane" mode) + * If the radio is is turned off/on the radio modem subsystem + * is expected return to an initialized state. For instance, + * any voice and data calls will be terminated and all associated + * lists emptied. + * + * "data" is int * + * ((int *)data)[0] is > 0 for "Radio On" + * ((int *)data)[0] is == 0 for "Radio Off" + * + * "response" is NULL + * + * Turn radio on if "on" > 0 + * Turn radio off if "on" == 0 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * INVALID_STATE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * DEVICE_IN_USE + * OPERATION_NOT_ALLOWED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_RADIO_POWER 23 + +/** + * RIL_REQUEST_DTMF + * + * Send a DTMF tone + * + * If the implementation is currently playing a tone requested via + * RIL_REQUEST_DTMF_START, that tone should be cancelled and the new tone + * should be played instead + * + * "data" is a char * containing a single character with one of 12 values: 0-9,*,# + * "response" is NULL + * + * FIXME should this block/mute microphone? + * How does this interact with local DTMF feedback? + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_RESOURCES + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_DTMF_STOP, RIL_REQUEST_DTMF_START + * + */ +#define RIL_REQUEST_DTMF 24 + +/** + * RIL_REQUEST_SEND_SMS + * + * Send an SMS message + * + * "data" is const char ** + * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed + * by a length byte (as expected by TS 27.005) or NULL for default SMSC + * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string + * less the SMSC address + * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * FDN_CHECK_FAILURE + * NETWORK_REJECT + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * INVALID_SMS_FORMAT + * SYSTEM_ERR + * ENCODING_ERR + * INVALID_SMSC_ADDRESS + * MODEM_ERR + * NETWORK_ERR + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * FIXME how do we specify TP-Message-Reference if we need to resend? + */ +#define RIL_REQUEST_SEND_SMS 25 + + +/** + * RIL_REQUEST_SEND_SMS_EXPECT_MORE + * + * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS, + * except that more messages are expected to be sent soon. If possible, + * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command) + * + * "data" is const char ** + * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed + * by a length byte (as expected by TS 27.005) or NULL for default SMSC + * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string + * less the SMSC address + * TP-Layer-Length is be "strlen(((const char **)data)[1])/2" + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * NETWORK_REJECT + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * INVALID_SMS_FORMAT + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * FDN_CHECK_FAILURE + * MODEM_ERR + * NETWORK_ERR + * ENCODING_ERR + * INVALID_SMSC_ADDRESS + * OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26 + + +/** + * RIL_REQUEST_SETUP_DATA_CALL + * + * Setup a packet data connection. If RIL_Data_Call_Response_v6.status + * return success it is added to the list of data calls and a + * RIL_UNSOL_DATA_CALL_LIST_CHANGED is sent. The call remains in the + * list until RIL_REQUEST_DEACTIVATE_DATA_CALL is issued or the + * radio is powered off/on. This list is returned by RIL_REQUEST_DATA_CALL_LIST + * and RIL_UNSOL_DATA_CALL_LIST_CHANGED. + * + * The RIL is expected to: + * - Create one data call context. + * - Create and configure a dedicated interface for the context + * - The interface must be point to point. + * - The interface is configured with one or more addresses and + * is capable of sending and receiving packets. The prefix length + * of the addresses must be /32 for IPv4 and /128 for IPv6. + * - Must NOT change the linux routing table. + * - Support up to RIL_REQUEST_DATA_REGISTRATION_STATE response[5] + * number of simultaneous data call contexts. + * + * "data" is a const char ** + * ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2... + * for values above 2 this is RIL_RadioTechnology + 2. + * ((const char **)data)[1] is a RIL_DataProfile (support is optional) + * ((const char **)data)[2] is the APN to connect to if radio technology is GSM/UMTS. This APN will + * override the one in the profile. NULL indicates no APN overrride. + * ((const char **)data)[3] is the username for APN, or NULL + * ((const char **)data)[4] is the password for APN, or NULL + * ((const char **)data)[5] is the PAP / CHAP auth type. Values: + * 0 => PAP and CHAP is never performed. + * 1 => PAP may be performed; CHAP is never performed. + * 2 => CHAP may be performed; PAP is never performed. + * 3 => PAP / CHAP may be performed - baseband dependent. + * ((const char **)data)[6] is the non-roaming/home connection type to request. Must be one of the + * PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + * ((const char **)data)[7] is the roaming connection type to request. Must be one of the + * PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + * ((const char **)data)[8] is the bitmask of APN type in decimal string format. The + * bitmask will encapsulate the following values: + * ia,mms,agps,supl,hipri,fota,dun,ims,default. + * ((const char **)data)[9] is the bearer bitmask in decimal string format. Each bit is a + * RIL_RadioAccessFamily. "0" or NULL indicates all RATs. + * ((const char **)data)[10] is the boolean in string format indicating the APN setting was + * sent to the modem through RIL_REQUEST_SET_DATA_PROFILE earlier. + * ((const char **)data)[11] is the mtu size in bytes of the mobile interface to which + * the apn is connected. + * ((const char **)data)[12] is the MVNO type: + * possible values are "imsi", "gid", "spn". + * ((const char **)data)[13] is MVNO match data in string. Can be anything defined by the carrier. + * For example, + * SPN like: "A MOBILE", "BEN NL", etc... + * IMSI like: "302720x94", "2060188", etc... + * GID like: "4E", "33", etc... + * ((const char **)data)[14] is the boolean string indicating data roaming is allowed or not. "1" + * indicates data roaming is enabled by the user, "0" indicates disabled. + * + * "response" is a RIL_Data_Call_Response_v11 + * + * FIXME may need way to configure QoS settings + * + * Valid errors: + * SUCCESS should be returned on both success and failure of setup with + * the RIL_Data_Call_Response_v6.status containing the actual status. + * For all other errors the RIL_Data_Call_Resonse_v6 is ignored. + * + * Other errors could include: + * RADIO_NOT_AVAILABLE, OP_NOT_ALLOWED_BEFORE_REG_TO_NW, + * OP_NOT_ALLOWED_DURING_VOICE_CALL, REQUEST_NOT_SUPPORTED, + * INVALID_ARGUMENTS, INTERNAL_ERR, NO_MEMORY, NO_RESOURCES + * and CANCELLED + * + * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL + */ +#define RIL_REQUEST_SETUP_DATA_CALL 27 + + +/** + * RIL_REQUEST_SIM_IO + * + * Request SIM I/O operation. + * This is similar to the TS 27.007 "restricted SIM" operation + * where it assumes all of the EF selection will be done by the + * callee. + * + * "data" is a const RIL_SIM_IO_v6 * + * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL, + * or may specify a PIN2 for operations that require a PIN2 (eg + * updating FDN records) + * + * "response" is a const RIL_SIM_IO_Response * + * + * Arguments and responses that are unused for certain + * values of "command" should be ignored or set to NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SIM_PIN2 + * SIM_PUK2 + * INVALID_SIM_STATE + * SIM_ERR + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_IO 28 + +/** + * RIL_REQUEST_SEND_USSD + * + * Send a USSD message + * + * If a USSD session already exists, the message should be sent in the + * context of that session. Otherwise, a new session should be created. + * + * The network reply should be reported via RIL_UNSOL_ON_USSD + * + * Only one USSD session may exist at a time, and the session is assumed + * to exist until: + * a) The android system invokes RIL_REQUEST_CANCEL_USSD + * b) The implementation sends a RIL_UNSOL_ON_USSD with a type code + * of "0" (USSD-Notify/no further action) or "2" (session terminated) + * + * "data" is a const char * containing the USSD request in UTF-8 format + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * FDN_CHECK_FAILURE + * USSD_MODIFIED_TO_DIAL + * USSD_MODIFIED_TO_SS + * USSD_MODIFIED_TO_USSD + * SIM_BUSY + * OPERATION_NOT_ALLOWED + * INVALID_ARGUMENTS + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * ABORTED + * SYSTEM_ERR + * INVALID_STATE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_CANCEL_USSD, RIL_UNSOL_ON_USSD + */ + +#define RIL_REQUEST_SEND_USSD 29 + +/** + * RIL_REQUEST_CANCEL_USSD + * + * Cancel the current USSD session if one exists + * + * "data" is null + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SIM_BUSY + * OPERATION_NOT_ALLOWED + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_STATE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_CANCEL_USSD 30 + +/** + * RIL_REQUEST_GET_CLIR + * + * Gets current CLIR status + * "data" is NULL + * "response" is int * + * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 + * ((int *)data)[1] is "m" parameter from TS 27.007 7.7 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * FDN_CHECK_FAILURE + * SYSTEM_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_GET_CLIR 31 + +/** + * RIL_REQUEST_SET_CLIR + * + * "data" is int * + * ((int *)data)[0] is "n" parameter from TS 27.007 7.7 + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * SYSTEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_CLIR 32 + +/** + * RIL_REQUEST_QUERY_CALL_FORWARD_STATUS + * + * "data" is const RIL_CallForwardInfo * + * + * "response" is const RIL_CallForwardInfo ** + * "response" points to an array of RIL_CallForwardInfo *'s, one for + * each distinct registered phone number. + * + * For example, if data is forwarded to +18005551212 and voice is forwarded + * to +18005559999, then two separate RIL_CallForwardInfo's should be returned + * + * If, however, both data and voice are forwarded to +18005551212, then + * a single RIL_CallForwardInfo can be returned with the service class + * set to "data + voice = 3") + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33 + + +/** + * RIL_REQUEST_SET_CALL_FORWARD + * + * Configure call forward rule + * + * "data" is const RIL_CallForwardInfo * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_STATE + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_CALL_FORWARD 34 + + +/** + * RIL_REQUEST_QUERY_CALL_WAITING + * + * Query current call waiting state + * + * "data" is const int * + * ((const int *)data)[0] is the TS 27.007 service class to query. + * "response" is a const int * + * ((const int *)response)[0] is 0 for "disabled" and 1 for "enabled" + * + * If ((const int *)response)[0] is = 1, then ((const int *)response)[1] + * must follow, with the TS 27.007 service class bit vector of services + * for which call waiting is enabled. + * + * For example, if ((const int *)response)[0] is 1 and + * ((const int *)response)[1] is 3, then call waiting is enabled for data + * and voice and disabled for everything else + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * FDN_CHECK_FAILURE + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_QUERY_CALL_WAITING 35 + + +/** + * RIL_REQUEST_SET_CALL_WAITING + * + * Configure current call waiting state + * + * "data" is const int * + * ((const int *)data)[0] is 0 for "disabled" and 1 for "enabled" + * ((const int *)data)[1] is the TS 27.007 service class bit vector of + * services to modify + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * INVALID_STATE + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_CALL_WAITING 36 + +/** + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * Acknowledge successful or failed receipt of SMS previously indicated + * via RIL_UNSOL_RESPONSE_NEW_SMS + * + * "data" is int * + * ((int *)data)[0] is 1 on successful receipt + * (basically, AT+CNMA=1 from TS 27.005 + * is 0 on failed receipt + * (basically, AT+CNMA=2 from TS 27.005) + * ((int *)data)[1] if data[0] is 0, this contains the failure cause as defined + * in TS 23.040, 9.2.3.22. Currently only 0xD3 (memory + * capacity exceeded) and 0xFF (unspecified error) are + * reported. + * + * "response" is NULL + * + * FIXME would like request that specified RP-ACK/RP-ERROR PDU + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SMS_ACKNOWLEDGE 37 + +/** + * RIL_REQUEST_GET_IMEI - DEPRECATED + * + * Get the device IMEI, including check digit + * + * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY + * Valid when RadioState is not RADIO_STATE_UNAVAILABLE + * + * "data" is NULL + * "response" is a const char * containing the IMEI + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ + +#define RIL_REQUEST_GET_IMEI 38 + +/** + * RIL_REQUEST_GET_IMEISV - DEPRECATED + * + * Get the device IMEISV, which should be two decimal digits + * + * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY + * Valid when RadioState is not RADIO_STATE_UNAVAILABLE + * + * "data" is NULL + * "response" is a const char * containing the IMEISV + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ + +#define RIL_REQUEST_GET_IMEISV 39 + + +/** + * RIL_REQUEST_ANSWER + * + * Answer incoming call + * + * Will not be called for WAITING calls. + * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE will be used in this case + * instead + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_ANSWER 40 + +/** + * RIL_REQUEST_DEACTIVATE_DATA_CALL + * + * Deactivate packet data connection and remove from the + * data call list if SUCCESS is returned. Any other return + * values should also try to remove the call from the list, + * but that may not be possible. In any event a + * RIL_REQUEST_RADIO_POWER off/on must clear the list. An + * RIL_UNSOL_DATA_CALL_LIST_CHANGED is not expected to be + * issued because of an RIL_REQUEST_DEACTIVATE_DATA_CALL. + * + * "data" is const char ** + * ((char**)data)[0] indicating CID + * ((char**)data)[1] indicating Disconnect Reason + * 0 => No specific reason specified + * 1 => Radio shutdown requested + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_CALL_ID + * INVALID_STATE + * INVALID_ARGUMENTS + * REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_REQUEST_SETUP_DATA_CALL + */ +#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41 + +/** + * RIL_REQUEST_QUERY_FACILITY_LOCK + * + * Query the status of a facility lock state + * + * "data" is const char ** + * ((const char **)data)[0] is the facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC, "SC" for SIM lock) + * ((const char **)data)[1] is the password, or "" if not required + * ((const char **)data)[2] is the TS 27.007 service class bit vector of + * services to query + * ((const char **)data)[3] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * This is only applicable in the case of Fixed Dialing Numbers + * (FDN) requests. + * + * "response" is an int * + * ((const int *)response) 0 is the TS 27.007 service class bit vector of + * services for which the specified barring facility + * is active. "0" means "disabled for all" + * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_QUERY_FACILITY_LOCK 42 + +/** + * RIL_REQUEST_SET_FACILITY_LOCK + * + * Enable/disable one facility lock + * + * "data" is const char ** + * + * ((const char **)data)[0] = facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC) + * ((const char **)data)[1] = "0" for "unlock" and "1" for "lock" + * ((const char **)data)[2] = password + * ((const char **)data)[3] = string representation of decimal TS 27.007 + * service class bit vector. Eg, the string + * "1" means "set this facility for voice services" + * ((const char **)data)[4] = AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. + * This is only applicable in the case of Fixed Dialing Numbers + * (FDN) requests. + * + * "response" is int * + * ((int *)response)[0] is the number of retries remaining, or -1 if unknown + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * INTERNAL_ERR + * NO_MEMORY + * MODEM_ERR + * INVALID_STATE + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_SET_FACILITY_LOCK 43 + +/** + * RIL_REQUEST_CHANGE_BARRING_PASSWORD + * + * Change call barring facility password + * + * "data" is const char ** + * + * ((const char **)data)[0] = facility string code from TS 27.007 7.4 + * (eg "AO" for BAOC) + * ((const char **)data)[1] = old password + * ((const char **)data)[2] = new password + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * INVALID_ARGUMENTS + * NO_MEMORY + * MODEM_ERR + * INTERNAL_ERR + * SYSTEM_ERR + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44 + +/** + * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE + * + * Query current network selectin mode + * + * "data" is NULL + * + * "response" is int * + * ((const int *)response)[0] is + * 0 for automatic selection + * 1 for manual selection + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45 + +/** + * RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC + * + * Specify that the network should be selected automatically + * + * "data" is NULL + * "response" is NULL + * + * This request must not respond until the new operator is selected + * and registered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * ILLEGAL_SIM_OR_ME + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + * + */ +#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46 + +/** + * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL + * + * Manually select a specified network. + * + * "data" is const char * specifying MCCMNC of network to select (eg "310170") + * "response" is NULL + * + * This request must not respond until the new operator is selected + * and registered + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * ILLEGAL_SIM_OR_ME + * OPERATION_NOT_ALLOWED + * INVALID_STATE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and + * no retries needed, such as illegal SIM or ME. + * + */ +#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47 + +/** + * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS + * + * Scans for available networks + * + * "data" is NULL + * "response" is const char ** that should be an array of n*4 strings, where + * n is the number of available networks + * For each available network: + * + * ((const char **)response)[n+0] is long alpha ONS or EONS + * ((const char **)response)[n+1] is short alpha ONS or EONS + * ((const char **)response)[n+2] is 5 or 6 digit numeric code (MCC + MNC) + * ((const char **)response)[n+3] is a string value of the status: + * "unknown" + * "available" + * "current" + * "forbidden" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * ABORTED + * DEVICE_IN_USE + * INTERNAL_ERR + * NO_MEMORY + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * CANCELLED + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48 + +/** + * RIL_REQUEST_DTMF_START + * + * Start playing a DTMF tone. Continue playing DTMF tone until + * RIL_REQUEST_DTMF_STOP is received + * + * If a RIL_REQUEST_DTMF_START is received while a tone is currently playing, + * it should cancel the previous tone and play the new one. + * + * "data" is a char * + * ((char *)data)[0] is a single character with one of 12 values: 0-9,*,# + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_RESOURCES + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_STOP + */ +#define RIL_REQUEST_DTMF_START 49 + +/** + * RIL_REQUEST_DTMF_STOP + * + * Stop playing a currently playing DTMF tone. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * NO_MEMORY + * INVALID_ARGUMENTS + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_START + */ +#define RIL_REQUEST_DTMF_STOP 50 + +/** + * RIL_REQUEST_BASEBAND_VERSION + * + * Return string value indicating baseband version, eg + * response from AT+CGMR + * + * "data" is NULL + * "response" is const char * containing version string for log reporting + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * EMPTY_RECORD + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_BASEBAND_VERSION 51 + +/** + * RIL_REQUEST_SEPARATE_CONNECTION + * + * Separate a party from a multiparty call placing the multiparty call + * (less the specified party) on hold and leaving the specified party + * as the only other member of the current (active) call + * + * Like AT+CHLD=2x + * + * See TS 22.084 1.3.8.2 (iii) + * TS 22.030 6.5.5 "Entering "2X followed by send" + * TS 27.007 "AT+CHLD=2x" + * + * "data" is an int * + * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) "response" is NULL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_ARGUMENTS + * INVALID_STATE + * NO_RESOURCES + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * INVALID_STATE + * OPERATION_NOT_ALLOWED + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SEPARATE_CONNECTION 52 + + +/** + * RIL_REQUEST_SET_MUTE + * + * Turn on or off uplink (microphone) mute. + * + * Will only be sent while voice call is active. + * Will always be reset to "disable mute" when a new voice call is initiated + * + * "data" is an int * + * (int *)data)[0] is 1 for "enable mute" and 0 for "disable mute" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_ARGUMENTS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_SET_MUTE 53 + +/** + * RIL_REQUEST_GET_MUTE + * + * Queries the current state of the uplink mute setting + * + * "data" is NULL + * "response" is an int * + * (int *)response)[0] is 1 for "mute enabled" and 0 for "mute disabled" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * SS_MODIFIED_TO_DIAL + * SS_MODIFIED_TO_USSD + * SS_MODIFIED_TO_SS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_GET_MUTE 54 + +/** + * RIL_REQUEST_QUERY_CLIP + * + * Queries the status of the CLIP supplementary service + * + * (for MMI code "*#30#") + * + * "data" is NULL + * "response" is an int * + * (int *)response)[0] is 1 for "CLIP provisioned" + * and 0 for "CLIP not provisioned" + * and 2 for "unknown, e.g. no network etc" + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * FDN_CHECK_FAILURE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_QUERY_CLIP 55 + +/** + * RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - Deprecated use the status + * field in RIL_Data_Call_Response_v6. + * + * Requests the failure cause code for the most recently failed PDP + * context or CDMA data connection active + * replaces RIL_REQUEST_LAST_PDP_FAIL_CAUSE + * + * "data" is NULL + * + * "response" is a "int *" + * ((int *)response)[0] is an integer cause code defined in TS 24.008 + * section 6.1.3.1.3 or close approximation + * + * If the implementation does not have access to the exact cause codes, + * then it should return one of the values listed in + * RIL_DataCallFailCause, as the UI layer needs to distinguish these + * cases for error notification + * and potential retries. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_LAST_CALL_FAIL_CAUSE + * + * Deprecated use the status field in RIL_Data_Call_Response_v6. + */ + +#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56 + +/** + * RIL_REQUEST_DATA_CALL_LIST + * + * Returns the data call list. An entry is added when a + * RIL_REQUEST_SETUP_DATA_CALL is issued and removed on a + * RIL_REQUEST_DEACTIVATE_DATA_CALL. The list is emptied + * when RIL_REQUEST_RADIO_POWER off/on is issued. + * + * "data" is NULL + * "response" is an array of RIL_Data_Call_Response_v6 + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_UNSOL_DATA_CALL_LIST_CHANGED + */ + +#define RIL_REQUEST_DATA_CALL_LIST 57 + +/** + * RIL_REQUEST_RESET_RADIO - DEPRECATED + * + * Request a radio reset. The RIL implementation may postpone + * the reset until after this request is responded to if the baseband + * is presently busy. + * + * The request is DEPRECATED, use RIL_REQUEST_RADIO_POWER + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * REQUEST_NOT_SUPPORTED + */ + +#define RIL_REQUEST_RESET_RADIO 58 + +/** + * RIL_REQUEST_OEM_HOOK_RAW + * + * This request reserved for OEM-specific uses. It passes raw byte arrays + * back and forth. + * + * It can be invoked on the Java side from + * com.android.internal.telephony.Phone.invokeOemRilRequestRaw() + * + * "data" is a char * of bytes copied from the byte[] data argument in java + * "response" is a char * of bytes that will returned via the + * caller's "response" Message here: + * (byte[])(((AsyncResult)response.obj).result) + * + * An error response here will result in + * (((AsyncResult)response.obj).result) == null and + * (((AsyncResult)response.obj).exception) being an instance of + * com.android.internal.telephony.gsm.CommandException + * + * Valid errors: + * All + */ + +#define RIL_REQUEST_OEM_HOOK_RAW 59 + +/** + * RIL_REQUEST_OEM_HOOK_STRINGS + * + * This request reserved for OEM-specific uses. It passes strings + * back and forth. + * + * It can be invoked on the Java side from + * com.android.internal.telephony.Phone.invokeOemRilRequestStrings() + * + * "data" is a const char **, representing an array of null-terminated UTF-8 + * strings copied from the "String[] strings" argument to + * invokeOemRilRequestStrings() + * + * "response" is a const char **, representing an array of null-terminated UTF-8 + * stings that will be returned via the caller's response message here: + * + * (String[])(((AsyncResult)response.obj).result) + * + * An error response here will result in + * (((AsyncResult)response.obj).result) == null and + * (((AsyncResult)response.obj).exception) being an instance of + * com.android.internal.telephony.gsm.CommandException + * + * Valid errors: + * All + */ + +#define RIL_REQUEST_OEM_HOOK_STRINGS 60 + +/** + * RIL_REQUEST_SCREEN_STATE - DEPRECATED + * + * Indicates the current state of the screen. When the screen is off, the + * RIL should notify the baseband to suppress certain notifications (eg, + * signal strength and changes in LAC/CID or BID/SID/NID/latitude/longitude) + * in an effort to conserve power. These notifications should resume when the + * screen is on. + * + * Note this request is deprecated. Use RIL_REQUEST_SEND_DEVICE_STATE to report the device state + * to the modem and use RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER to turn on/off unsolicited + * response from the modem in different scenarios. + * + * "data" is int * + * ((int *)data)[0] is == 1 for "Screen On" + * ((int *)data)[0] is == 0 for "Screen Off" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SCREEN_STATE 61 + + +/** + * RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION + * + * Enables/disables supplementary service related notifications + * from the network. + * + * Notifications are reported via RIL_UNSOL_SUPP_SVC_NOTIFICATION. + * + * "data" is int * + * ((int *)data)[0] is == 1 for notifications enabled + * ((int *)data)[0] is == 0 for notifications disabled + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SIM_BUSY + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_UNSOL_SUPP_SVC_NOTIFICATION. + */ +#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62 + +/** + * RIL_REQUEST_WRITE_SMS_TO_SIM + * + * Stores a SMS message to SIM memory. + * + * "data" is RIL_SMS_WriteArgs * + * + * "response" is int * + * ((const int *)response)[0] is the record index where the message is stored. + * + * Valid errors: + * SUCCESS + * SIM_FULL + * INVALID_ARGUMENTS + * INVALID_SMS_FORMAT + * INTERNAL_ERR + * MODEM_ERR + * ENCODING_ERR + * NO_MEMORY + * NO_RESOURCES + * INVALID_MODEM_STATE + * OPERATION_NOT_ALLOWED + * INVALID_SMSC_ADDRESS + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_WRITE_SMS_TO_SIM 63 + +/** + * RIL_REQUEST_DELETE_SMS_ON_SIM + * + * Deletes a SMS message from SIM memory. + * + * "data" is int * + * ((int *)data)[0] is the record index of the message to delete. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * SIM_FULL + * INVALID_ARGUMENTS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * MODEM_ERR + * NO_SUCH_ENTRY + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_DELETE_SMS_ON_SIM 64 + +/** + * RIL_REQUEST_SET_BAND_MODE + * + * Assign a specified band for RF configuration. + * + * "data" is int * + * ((int *)data)[0] is a RIL_RadioBandMode + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE + */ +#define RIL_REQUEST_SET_BAND_MODE 65 + +/** + * RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE + * + * Query the list of band mode supported by RF. + * + * "data" is NULL + * + * "response" is int * + * "response" points to an array of int's, the int[0] is the size of array; + * subsequent values are a list of RIL_RadioBandMode listing supported modes. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_REQUEST_SET_BAND_MODE + */ +#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66 + +/** + * RIL_REQUEST_STK_GET_PROFILE + * + * Requests the profile of SIM tool kit. + * The profile indicates the SAT/USAT features supported by ME. + * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * "data" is NULL + * + * "response" is a const char * containing SAT/USAT profile + * in hexadecimal format string starting with first byte of terminal profile + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_GET_PROFILE 67 + +/** + * RIL_REQUEST_STK_SET_PROFILE + * + * Download the STK terminal profile as part of SIM initialization + * procedure + * + * "data" is a const char * containing SAT/USAT profile + * in hexadecimal format string starting with first byte of terminal profile + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_SET_PROFILE 68 + +/** + * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND + * + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111 + * + * "data" is a const char * containing SAT/USAT command + * in hexadecimal format string starting with command tag + * + * "response" is a const char * containing SAT/USAT response + * in hexadecimal format string starting with first byte of response + * (May be NULL) + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * SIM_BUSY + * OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69 + +/** + * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE + * + * Requests to send a terminal response to SIM for a received + * proactive command + * + * "data" is a const char * containing SAT/USAT response + * in hexadecimal format string starting with first byte of response data + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70 + +/** + * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM + * + * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has + * been initialized by ME already. (We could see the call has been in the 'call + * list') So, STK application needs to accept/reject the call according as user + * operations. + * + * "data" is int * + * ((int *)data)[0] is > 0 for "accept" the call setup + * ((int *)data)[0] is == 0 for "reject" the call setup + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * RIL_E_OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71 + +/** + * RIL_REQUEST_EXPLICIT_CALL_TRANSFER + * + * Connects the two calls and disconnects the subscriber from both calls. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * INVALID_STATE + * NO_RESOURCES + * NO_MEMORY + * INVALID_ARGUMENTS + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * INVALID_STATE + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72 + +/** + * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE + * + * Requests to set the preferred network type for searching and registering + * (CS/PS domain, RAT, and operation mode) + * + * "data" is int * which is RIL_PreferredNetworkType + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * OPERATION_NOT_ALLOWED + * MODE_NOT_SUPPORTED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73 + +/** + * RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE + * + * Query the preferred network type (CS/PS domain, RAT, and operation mode) + * for searching and registering + * + * "data" is NULL + * + * "response" is int * + * ((int *)reponse)[0] is == RIL_PreferredNetworkType + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE + */ +#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74 + +/** + * RIL_REQUEST_NEIGHBORING_CELL_IDS + * + * Request neighboring cell id in GSM network + * + * "data" is NULL + * "response" must be a " const RIL_NeighboringCell** " + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NO_NETWORK_FOUND + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75 + +/** + * RIL_REQUEST_SET_LOCATION_UPDATES + * + * Enables/disables network state change notifications due to changes in + * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA). + * Basically +CREG=2 vs. +CREG=1 (TS 27.007). + * + * Note: The RIL implementation should default to "updates enabled" + * when the screen is on and "updates disabled" when the screen is off. + * + * "data" is int * + * ((int *)data)[0] is == 1 for updates enabled (+CREG=2) + * ((int *)data)[0] is == 0 for updates disabled (+CREG=1) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED + */ +#define RIL_REQUEST_SET_LOCATION_UPDATES 76 + +/** + * RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE + * + * Request to set the location where the CDMA subscription shall + * be retrieved + * + * "data" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SIM_ABSENT + * SUBSCRIPTION_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE + */ +#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77 + +/** + * RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE + * + * Request to set the roaming preferences in CDMA + * + * "data" is int * + * ((int *)data)[0] is == 0 for Home Networks only, as defined in PRL + * ((int *)data)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL + * ((int *)data)[0] is == 2 for Roaming on Any Network, as defined in the PRL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78 + +/** + * RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE + * + * Request the actual setting of the roaming preferences in CDMA in the modem + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for Home Networks only, as defined in PRL + * ((int *)response)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL + * ((int *)response)[0] is == 2 for Roaming on Any Network, as defined in the PRL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79 + +/** + * RIL_REQUEST_SET_TTY_MODE + * + * Request to set the TTY mode + * + * "data" is int * + * ((int *)data)[0] is == 0 for TTY off + * ((int *)data)[0] is == 1 for TTY Full + * ((int *)data)[0] is == 2 for TTY HCO (hearing carryover) + * ((int *)data)[0] is == 3 for TTY VCO (voice carryover) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_ARGUMENTS + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_TTY_MODE 80 + +/** + * RIL_REQUEST_QUERY_TTY_MODE + * + * Request the setting of TTY mode + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for TTY off + * ((int *)response)[0] is == 1 for TTY Full + * ((int *)response)[0] is == 2 for TTY HCO (hearing carryover) + * ((int *)response)[0] is == 3 for TTY VCO (voice carryover) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_QUERY_TTY_MODE 81 + +/** + * RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE + * + * Request to set the preferred voice privacy mode used in voice + * scrambling + * + * "data" is int * + * ((int *)data)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) + * ((int *)data)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_CALL_ID + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82 + +/** + * RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE + * + * Request the setting of preferred voice privacy mode + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask) + * ((int *)response)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * MODEM_ERR + * INTERNAL_ERR + * NO_MEMORY + * INVALID_ARGUMENTS + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83 + +/** + * RIL_REQUEST_CDMA_FLASH + * + * Send FLASH + * + * "data" is const char * + * ((const char *)data)[0] is a FLASH string + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * INVALID_STATE + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_FLASH 84 + +/** + * RIL_REQUEST_CDMA_BURST_DTMF + * + * Send DTMF string + * + * "data" is const char ** + * ((const char **)data)[0] is a DTMF string + * ((const char **)data)[1] is the DTMF ON length in milliseconds, or 0 to use + * default + * ((const char **)data)[2] is the DTMF OFF length in milliseconds, or 0 to use + * default + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * MODEM_ERR + * INTERNAL_ERR + * INVALID_CALL_ID + * NO_RESOURCES + * CANCELLED + * OPERATION_NOT_ALLOWED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_BURST_DTMF 85 + +/** + * RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY + * + * Takes a 26 digit string (20 digit AKEY + 6 digit checksum). + * If the checksum is valid the 20 digit AKEY is written to NV, + * replacing the existing AKEY no matter what it was before. + * + * "data" is const char * + * ((const char *)data)[0] is a 26 digit string (ASCII digits '0'-'9') + * where the last 6 digits are a checksum of the + * first 20, as specified in TR45.AHAG + * "Common Cryptographic Algorithms, Revision D.1 + * Section 2.2" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86 + +/** + * RIL_REQUEST_CDMA_SEND_SMS + * + * Send a CDMA SMS message + * + * "data" is const RIL_CDMA_SMS_Message * + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. The CDMA error class is derived as follows, + * SUCCESS is error class 0 (no error) + * SMS_SEND_FAIL_RETRY is error class 2 (temporary failure) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * NETWORK_REJECT + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * INVALID_SMS_FORMAT + * SYSTEM_ERR + * FDN_CHECK_FAILURE + * MODEM_ERR + * NETWORK_ERR + * ENCODING_ERR + * INVALID_SMSC_ADDRESS + * OPERATION_NOT_ALLOWED + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_SEND_SMS 87 + +/** + * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE + * + * Acknowledge the success or failure in the receipt of SMS + * previously indicated via RIL_UNSOL_RESPONSE_CDMA_NEW_SMS + * + * "data" is const RIL_CDMA_SMS_Ack * + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_SMS_TO_ACK + * INVALID_STATE + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * MODEM_ERR + * INVALID_STATE + * OPERATION_NOT_ALLOWED + * NETWORK_NOT_READY + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88 + +/** + * RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG + * + * Request the setting of GSM/WCDMA Cell Broadcast SMS config. + * + * "data" is NULL + * + * "response" is a const RIL_GSM_BroadcastSmsConfigInfo ** + * "responselen" is count * sizeof (RIL_GSM_BroadcastSmsConfigInfo *) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * NO_RESOURCES + * MODEM_ERR + * SYSTEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89 + +/** + * RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG + * + * Set GSM/WCDMA Cell Broadcast SMS config + * + * "data" is a const RIL_GSM_BroadcastSmsConfigInfo ** + * "datalen" is count * sizeof(RIL_GSM_BroadcastSmsConfigInfo *) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * SYSTEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90 + +/** + * RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION + * +* Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS + * + * "data" is const int * + * (const int *)data[0] indicates to activate or turn off the + * reception of GSM/WCDMA Cell Broadcast SMS, 0-1, + * 0 - Activate, 1 - Turn off + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * REQUEST_RATE_LIMITED +* MODEM_ERR +* INTERNAL_ERR +* NO_RESOURCES +* CANCELLED +* INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91 + +/** + * RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG + * + * Request the setting of CDMA Broadcast SMS config + * + * "data" is NULL + * + * "response" is a const RIL_CDMA_BroadcastSmsConfigInfo ** + * "responselen" is count * sizeof (RIL_CDMA_BroadcastSmsConfigInfo *) + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * NO_RESOURCES + * MODEM_ERR + * SYSTEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92 + +/** + * RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG + * + * Set CDMA Broadcast SMS config + * + * "data" is a const RIL_CDMA_BroadcastSmsConfigInfo ** + * "datalen" is count * sizeof(const RIL_CDMA_BroadcastSmsConfigInfo *) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * SYSTEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93 + +/** + * RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION + * + * Enable or disable the reception of CDMA Broadcast SMS + * + * "data" is const int * + * (const int *)data[0] indicates to activate or turn off the + * reception of CDMA Broadcast SMS, 0-1, + * 0 - Activate, 1 - Turn off + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_STATE + * INVALID_ARGUMENTS + * NO_MEMORY + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94 + +/** + * RIL_REQUEST_CDMA_SUBSCRIPTION + * + * Request the device MDN / H_SID / H_NID. + * + * The request is only allowed when CDMA subscription is available. When CDMA + * subscription is changed, application layer should re-issue the request to + * update the subscription information. + * + * If a NULL value is returned for any of the device id, it means that error + * accessing the device. + * + * "response" is const char ** + * ((const char **)response)[0] is MDN if CDMA subscription is available + * ((const char **)response)[1] is a comma separated list of H_SID (Home SID) if + * CDMA subscription is available, in decimal format + * ((const char **)response)[2] is a comma separated list of H_NID (Home NID) if + * CDMA subscription is available, in decimal format + * ((const char **)response)[3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available + * ((const char **)response)[4] is PRL version if CDMA subscription is available + * + * Valid errors: + * SUCCESS + * RIL_E_SUBSCRIPTION_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * + */ + +#define RIL_REQUEST_CDMA_SUBSCRIPTION 95 + +/** + * RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM + * + * Stores a CDMA SMS message to RUIM memory. + * + * "data" is RIL_CDMA_SMS_WriteArgs * + * + * "response" is int * + * ((const int *)response)[0] is the record index where the message is stored. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SIM_FULL + * INVALID_ARGUMENTS + * INVALID_SMS_FORMAT + * INTERNAL_ERR + * MODEM_ERR + * ENCODING_ERR + * NO_MEMORY + * NO_RESOURCES + * INVALID_MODEM_STATE + * OPERATION_NOT_ALLOWED + * INVALID_SMSC_ADDRESS + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96 + +/** + * RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM + * + * Deletes a CDMA SMS message from RUIM memory. + * + * "data" is int * + * ((int *)data)[0] is the record index of the message to delete. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * MODEM_ERR + * NO_SUCH_ENTRY + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97 + +/** + * RIL_REQUEST_DEVICE_IDENTITY + * + * Request the device ESN / MEID / IMEI / IMEISV. + * + * The request is always allowed and contains GSM and CDMA device identity; + * it substitutes the deprecated requests RIL_REQUEST_GET_IMEI and + * RIL_REQUEST_GET_IMEISV. + * + * If a NULL value is returned for any of the device id, it means that error + * accessing the device. + * + * When CDMA subscription is changed the ESN/MEID may change. The application + * layer should re-issue the request to update the device identity in this case. + * + * "response" is const char ** + * ((const char **)response)[0] is IMEI if GSM subscription is available + * ((const char **)response)[1] is IMEISV if GSM subscription is available + * ((const char **)response)[2] is ESN if CDMA subscription is available + * ((const char **)response)[3] is MEID if CDMA subscription is available + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_DEVICE_IDENTITY 98 + +/** + * RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE + * + * Request the radio's system selection module to exit emergency + * callback mode. RIL will not respond with SUCCESS until the modem has + * completely exited from Emergency Callback Mode. + * + * "data" is NULL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99 + +/** + * RIL_REQUEST_GET_SMSC_ADDRESS + * + * Queries the default Short Message Service Center address on the device. + * + * "data" is NULL + * + * "response" is const char * containing the SMSC address. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * REQUEST_RATE_LIMITED + * SYSTEM_ERR + * INTERNAL_ERR + * MODEM_ERR + * INVALID_ARGUMENTS + * INVALID_MODEM_STATE + * NOT_PROVISIONED + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_GET_SMSC_ADDRESS 100 + +/** + * RIL_REQUEST_SET_SMSC_ADDRESS + * + * Sets the default Short Message Service Center address on the device. + * + * "data" is const char * containing the SMSC address. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * INVALID_SMS_FORMAT + * NO_MEMORY + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * NO_RESOURCES + * INTERNAL_ERR + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_SET_SMSC_ADDRESS 101 + +/** + * RIL_REQUEST_REPORT_SMS_MEMORY_STATUS + * + * Indicates whether there is storage available for new SMS messages. + * + * "data" is int * + * ((int *)data)[0] is 1 if memory is available for storing new messages + * is 0 if memory capacity is exceeded + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INVALID_ARGUMENTS + * NO_MEMORY + * INVALID_STATE + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102 + +/** + * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING + * + * Indicates that the StkSerivce is running and is + * ready to receive RIL_UNSOL_STK_XXXXX commands. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103 + +/** + * RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE + * + * Request to query the location where the CDMA subscription shall + * be retrieved + * + * "data" is NULL + * + * "response" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SUBSCRIPTION_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + * See also: RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE + */ +#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104 + +/** + * RIL_REQUEST_ISIM_AUTHENTICATION + * + * Request the ISIM application on the UICC to perform AKA + * challenge/response algorithm for IMS authentication + * + * "data" is a const char * containing the challenge string in Base64 format + * "response" is a const char * containing the response in Base64 format + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_ISIM_AUTHENTICATION 105 + +/** + * RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU + * + * Acknowledge successful or failed receipt of SMS previously indicated + * via RIL_UNSOL_RESPONSE_NEW_SMS, including acknowledgement TPDU to send + * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU. + * + * "data" is const char ** + * ((const char **)data)[0] is "1" on successful receipt (send RP-ACK) + * is "0" on failed receipt (send RP-ERROR) + * ((const char **)data)[1] is the acknowledgement TPDU in hexadecimal format + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106 + +/** + * RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS + * + * Requests to send a SAT/USAT envelope command to SIM. + * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111. + * + * This request has one difference from RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: + * the SW1 and SW2 status bytes from the UICC response are returned along with + * the response data, using the same structure as RIL_REQUEST_SIM_IO. + * + * The RIL implementation shall perform the normal processing of a '91XX' + * response in SW1/SW2 to retrieve the pending proactive command and send it + * as an unsolicited response, as RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND does. + * + * "data" is a const char * containing the SAT/USAT command + * in hexadecimal format starting with command tag + * + * "response" is a const RIL_SIM_IO_Response * + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE (radio resetting) + * SIM_BUSY + * OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107 + +/** + * RIL_REQUEST_VOICE_RADIO_TECH + * + * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only + * when radio state is not RADIO_STATE_UNAVAILABLE + * + * "data" is NULL + * "response" is int * + * ((int *) response)[0] is of type const RIL_RadioTechnology + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_VOICE_RADIO_TECH 108 + +/** + * RIL_REQUEST_GET_CELL_INFO_LIST + * + * Request all of the current cell information known to the radio. The radio + * must a list of all current cells, including the neighboring cells. If for a particular + * cell information isn't known then the appropriate unknown value will be returned. + * This does not cause or change the rate of RIL_UNSOL_CELL_INFO_LIST. + * + * "data" is NULL + * + * "response" is an array of RIL_CellInfo_v12. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NO_NETWORK_FOUND + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_GET_CELL_INFO_LIST 109 + +/** + * RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE + * + * Sets the minimum time between when RIL_UNSOL_CELL_INFO_LIST should be invoked. + * A value of 0, means invoke RIL_UNSOL_CELL_INFO_LIST when any of the reported + * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue + * a RIL_UNSOL_CELL_INFO_LIST. + * + * "data" is int * + * ((int *)data)[0] is minimum time in milliseconds + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 + +/** + * RIL_REQUEST_SET_INITIAL_ATTACH_APN + * + * Set an apn to initial attach network + * + * "data" is a const char ** + * ((const char **)data)[0] is the APN to connect if radio technology is LTE + * ((const char **)data)[1] is the connection type to request must be one of the + * PDP_type values in TS 27.007 section 10.1.1. + * For example, "IP", "IPV6", "IPV4V6", or "PPP". + * ((const char **)data)[2] is the PAP / CHAP auth type. Values: + * 0 => PAP and CHAP is never performed. + * 1 => PAP may be performed; CHAP is never performed. + * 2 => CHAP may be performed; PAP is never performed. + * 3 => PAP / CHAP may be performed - baseband dependent. + * ((const char **)data)[3] is the username for APN, or NULL + * ((const char **)data)[4] is the password for APN, or NULL + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * SUBSCRIPTION_NOT_AVAILABLE + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111 + +/** + * RIL_REQUEST_IMS_REGISTRATION_STATE + * + * This message is DEPRECATED and shall be removed in a future release (target: 2018); + * instead, provide IMS registration status via an IMS Service. + * + * Request current IMS registration state + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is registration state: + * 0 - Not registered + * 1 - Registered + * + * If ((int*)response)[0] is = 1, then ((int *) response)[1] + * must follow with IMS SMS format: + * + * ((int *) response)[1] is of type RIL_RadioTechnologyFamily + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_IMS_REGISTRATION_STATE 112 + +/** + * RIL_REQUEST_IMS_SEND_SMS + * + * Send a SMS message over IMS + * + * "data" is const RIL_IMS_SMS_Message * + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. + * In case of retry, data is encoded based on Voice Technology available. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * FDN_CHECK_FAILURE + * NETWORK_REJECT + * INVALID_ARGUMENTS + * INVALID_STATE + * NO_MEMORY + * INVALID_SMS_FORMAT + * SYSTEM_ERR + * REQUEST_RATE_LIMITED + * MODEM_ERR + * NETWORK_ERR + * ENCODING_ERR + * INVALID_SMSC_ADDRESS + * OPERATION_NOT_ALLOWED + * INTERNAL_ERR + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_IMS_SEND_SMS 113 + +/** + * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC + * + * Request APDU exchange on the basic channel. This command reflects TS 27.007 + * "generic SIM access" operation (+CSIM). The modem must ensure proper function + * of GSM/CDMA, and filter commands appropriately. It should filter + * channel management and SELECT by DF name commands. + * + * "data" is a const RIL_SIM_APDU * + * "sessionid" field should be ignored. + * + * "response" is a const RIL_SIM_IO_Response * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114 + +/** + * RIL_REQUEST_SIM_OPEN_CHANNEL + * + * Open a new logical channel and select the given application. This command + * reflects TS 27.007 "open logical channel" operation (+CCHO). This request + * also specifies the P2 parameter (described in ISO 7816-4). + * + * "data" is a const RIL_OpenChannelParam * + * + * "response" is int * + * ((int *)data)[0] contains the session id of the logical channel. + * ((int *)data)[1] onwards may optionally contain the select response for the + * open channel command with one byte per integer. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * MISSING_RESOURCE + * NO_SUCH_ELEMENT + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * SIM_ERR + * INVALID_SIM_STATE + * MISSING_RESOURCE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_OPEN_CHANNEL 115 + +/** + * RIL_REQUEST_SIM_CLOSE_CHANNEL + * + * Close a previously opened logical channel. This command reflects TS 27.007 + * "close logical channel" operation (+CCHC). + * + * "data" is int * + * ((int *)data)[0] is the session id of logical the channel to close. + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116 + +/** + * RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL + * + * Exchange APDUs with a UICC over a previously opened logical channel. This + * command reflects TS 27.007 "generic logical channel access" operation + * (+CGLA). The modem should filter channel management and SELECT by DF name + * commands. + * + * "data" is a const RIL_SIM_APDU* + * + * "response" is a const RIL_SIM_IO_Response * + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117 + +/** + * RIL_REQUEST_NV_READ_ITEM + * + * Read one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. + * This is used for device configuration by some CDMA operators. + * + * "data" is a const RIL_NV_ReadItem * + * + * "response" is const char * containing the contents of the NV item + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_NV_READ_ITEM 118 + +/** + * RIL_REQUEST_NV_WRITE_ITEM + * + * Write one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h. + * This is used for device configuration by some CDMA operators. + * + * "data" is a const RIL_NV_WriteItem * + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_NV_WRITE_ITEM 119 + +/** + * RIL_REQUEST_NV_WRITE_CDMA_PRL + * + * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. + * This is used for device configuration by some CDMA operators. + * + * "data" is a const char * containing the PRL as a byte array + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120 + +/** + * RIL_REQUEST_NV_RESET_CONFIG + * + * Reset the radio NV configuration to the factory state. + * This is used for device configuration by some CDMA operators. + * + * "data" is int * + * ((int *)data)[0] is 1 to reload all NV items + * ((int *)data)[0] is 2 for erase NV reset (SCRTN) + * ((int *)data)[0] is 3 for factory reset (RTN) + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_NV_RESET_CONFIG 121 + + /** RIL_REQUEST_SET_UICC_SUBSCRIPTION + * FIXME This API needs to have more documentation. + * + * Selection/de-selection of a subscription from a SIM card + * "data" is const RIL_SelectUiccSub* + + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * SUBSCRIPTION_NOT_SUPPORTED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_SET_UICC_SUBSCRIPTION 122 + +/** + * RIL_REQUEST_ALLOW_DATA + * + * Tells the modem whether data calls are allowed or not + * + * "data" is int * + * FIXME slotId and aid will be added. + * ((int *)data)[0] is == 0 to allow data calls + * ((int *)data)[0] is == 1 to disallow data calls + * + * "response" is NULL + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * INVALID_ARGUMENTS + * DEVICE_IN_USE + * INVALID_MODEM_STATE + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_ALLOW_DATA 123 + +/** + * RIL_REQUEST_GET_HARDWARE_CONFIG + * + * Request all of the current hardware (modem and sim) associated + * with the RIL. + * + * "data" is NULL + * + * "response" is an array of RIL_HardwareConfig. + * + * Valid errors: + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_GET_HARDWARE_CONFIG 124 + +/** + * RIL_REQUEST_SIM_AUTHENTICATION + * + * Returns the response of SIM Authentication through RIL to a + * challenge request. + * + * "data" Base64 encoded string containing challenge: + * int authContext; P2 value of authentication command, see P2 parameter in + * 3GPP TS 31.102 7.1.2 + * char *authData; the challenge string in Base64 format, see 3GPP + * TS 31.102 7.1.2 + * char *aid; AID value, See ETSI 102.221 8.1 and 101.220 4, + * NULL if no value + * + * "response" Base64 encoded strings containing response: + * int sw1; Status bytes per 3GPP TS 31.102 section 7.3 + * int sw2; + * char *simResponse; Response in Base64 format, see 3GPP TS 31.102 7.1.2 + * + * Valid errors: + * RADIO_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * INVALID_MODEM_STATE + * INVALID_ARGUMENTS + * SIM_ERR + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SIM_AUTHENTICATION 125 + +/** + * RIL_REQUEST_GET_DC_RT_INFO + * + * The request is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO + * Requests the Data Connection Real Time Info + * + * "data" is NULL + * + * "response" is the most recent RIL_DcRtInfo + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * + * See also: RIL_UNSOL_DC_RT_INFO_CHANGED + */ +#define RIL_REQUEST_GET_DC_RT_INFO 126 + +/** + * RIL_REQUEST_SET_DC_RT_INFO_RATE + * + * The request is DEPRECATED + * This is the minimum number of milliseconds between successive + * RIL_UNSOL_DC_RT_INFO_CHANGED messages and defines the highest rate + * at which RIL_UNSOL_DC_RT_INFO_CHANGED's will be sent. A value of + * 0 means send as fast as possible. + * + * "data" The number of milliseconds as an int + * + * "response" is null + * + * Valid errors: + * SUCCESS must not fail + */ +#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127 + +/** + * RIL_REQUEST_SET_DATA_PROFILE + * + * Set data profile in modem + * Modem should erase existed profiles from framework, and apply new profiles + * "data" is a const RIL_DataProfileInfo ** + * "datalen" is count * sizeof(const RIL_DataProfileInfo *) + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * SUBSCRIPTION_NOT_AVAILABLE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_SET_DATA_PROFILE 128 + +/** + * RIL_REQUEST_SHUTDOWN + * + * Device is shutting down. All further commands are ignored + * and RADIO_NOT_AVAILABLE must be returned. + * + * "data" is null + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SHUTDOWN 129 + +/** + * RIL_REQUEST_GET_RADIO_CAPABILITY + * + * Used to get phone radio capablility. + * + * "data" is the RIL_RadioCapability structure + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * INVALID_STATE + * REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_GET_RADIO_CAPABILITY 130 + +/** + * RIL_REQUEST_SET_RADIO_CAPABILITY + * + * Used to set the phones radio capability. Be VERY careful + * using this request as it may cause some vendor modems to reset. Because + * of the possible modem reset any RIL commands after this one may not be + * processed. + * + * "data" is the RIL_RadioCapability structure + * + * "response" is the RIL_RadioCapability structure, used to feedback return status + * + * Valid errors: + * SUCCESS means a RIL_UNSOL_RADIO_CAPABILITY will be sent within 30 seconds. + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * MODEM_ERR + * INVALID_STATE + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_RADIO_CAPABILITY 131 + +/** + * RIL_REQUEST_START_LCE + * + * Start Link Capacity Estimate (LCE) service if supported by the radio. + * + * "data" is const int * + * ((const int*)data)[0] specifies the desired reporting interval (ms). + * ((const int*)data)[1] specifies the LCE service mode. 1: PULL; 0: PUSH. + * + * "response" is the RIL_LceStatusInfo. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * LCE_NOT_SUPPORTED + * INTERNAL_ERR + * REQUEST_NOT_SUPPORTED + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_START_LCE 132 + +/** + * RIL_REQUEST_STOP_LCE + * + * Stop Link Capacity Estimate (LCE) service, the STOP operation should be + * idempotent for the radio modem. + * + * "response" is the RIL_LceStatusInfo. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * LCE_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_STOP_LCE 133 + +/** + * RIL_REQUEST_PULL_LCEDATA + * + * Pull LCE service for capacity information. + * + * "response" is the RIL_LceDataInfo. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * LCE_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + */ +#define RIL_REQUEST_PULL_LCEDATA 134 + +/** + * RIL_REQUEST_GET_ACTIVITY_INFO + * + * Get modem activity information for power consumption estimation. + * + * Request clear-on-read statistics information that is used for + * estimating the per-millisecond power consumption of the cellular + * modem. + * + * "data" is null + * "response" is const RIL_ActivityStatsInfo * + * + * Valid errors: + * + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * MODEM_ERR + * NOT_PROVISIONED + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES CANCELLED + */ +#define RIL_REQUEST_GET_ACTIVITY_INFO 135 + +/** + * RIL_REQUEST_SET_CARRIER_RESTRICTIONS + * + * Set carrier restrictions for this sim slot. Expected modem behavior: + * If never receives this command + * - Must allow all carriers + * Receives this command with data being NULL + * - Must allow all carriers. If a previously allowed SIM is present, modem must not reload + * the SIM. If a previously disallowed SIM is present, reload the SIM and notify Android. + * Receives this command with a list of carriers + * - Only allow specified carriers, persist across power cycles and FDR. If a present SIM + * is in the allowed list, modem must not reload the SIM. If a present SIM is *not* in + * the allowed list, modem must detach from the registered network and only keep emergency + * service, and notify Android SIM refresh reset with new SIM state being + * RIL_CARDSTATE_RESTRICTED. Emergency service must be enabled. + * + * "data" is const RIL_CarrierRestrictions * + * A list of allowed carriers and possibly a list of excluded carriers. + * If data is NULL, means to clear previous carrier restrictions and allow all carriers + * + * "response" is int * + * ((int *)data)[0] contains the number of allowed carriers which have been set correctly. + * On success, it should match the length of list data->allowed_carriers. + * If data is NULL, the value must be 0. + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_INVALID_ARGUMENTS + * RIL_E_RADIO_NOT_AVAILABLE + * RIL_E_REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS 136 + +/** + * RIL_REQUEST_GET_CARRIER_RESTRICTIONS + * + * Get carrier restrictions for this sim slot. Expected modem behavior: + * Return list of allowed carriers, or null if all carriers are allowed. + * + * "data" is NULL + * + * "response" is const RIL_CarrierRestrictions *. + * If response is NULL, it means all carriers are allowed. + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE + * RIL_E_REQUEST_NOT_SUPPORTED + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS 137 + +/** + * RIL_REQUEST_SEND_DEVICE_STATE + * + * Send the updated device state. + * Modem can perform power saving based on the provided device state. + * "data" is const int * + * ((const int*)data)[0] A RIL_DeviceStateType that specifies the device state type. + * ((const int*)data)[1] Specifies the state. See RIL_DeviceStateType for the definition of each + * type. + * + * "datalen" is count * sizeof(const RIL_DeviceState *) + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * INVALID_ARGUMENTS + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SEND_DEVICE_STATE 138 + +/** + * RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER + * + * Set the unsolicited response filter + * This is used to prevent unnecessary application processor + * wake up for power saving purposes by suppressing the + * unsolicited responses in certain scenarios. + * + * "data" is an int * + * + * ((int *)data)[0] is a 32-bit bitmask of RIL_UnsolicitedResponseFilter + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * INVALID_ARGUMENTS (e.g. the requested filter doesn't exist) + * RADIO_NOT_AVAILABLE (radio resetting) + * NO_MEMORY + * INTERNAL_ERR + * SYSTEM_ERR + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER 139 + + /** + * RIL_REQUEST_SET_SIM_CARD_POWER + * + * Set SIM card power up or down + * + * Request is equivalent to inserting and removing the card, with + * an additional effect where the ability to detect card removal/insertion + * is disabled when the SIM card is powered down. + * + * This will generate RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED + * as if the SIM had been inserted or removed. + * + * "data" is int * + * ((int *)data)[0] is 1 for "SIM POWER UP" + * ((int *)data)[0] is 0 for "SIM POWER DOWN" + * + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * REQUEST_NOT_SUPPORTED + * SIM_ABSENT + * INVALID_ARGUMENTS + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_SIM_CARD_POWER 140 + +/** + * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION + * + * Provide Carrier specific information to the modem that will be used to + * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier + * switch and everytime we receive a new certificate. + * + * "data" is the RIL_CarrierInfoForImsiEncryption * structure. + * + * "response" is NULL + * + * Valid errors: + * RIL_E_SUCCESS + * RIL_E_RADIO_NOT_AVAILABLE + * SIM_ABSENT + * RIL_E_REQUEST_NOT_SUPPORTED + * INVALID_ARGUMENTS + * MODEM_INTERNAL_FAILURE + * INTERNAL_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + */ +#define RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION 141 + +/** + * RIL_REQUEST_START_NETWORK_SCAN + * + * Starts a new network scan + * + * Request to start a network scan with specified radio access networks with frequency bands and/or + * channels. + * + * "data" is a const RIL_NetworkScanRequest *. + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * OPERATION_NOT_ALLOWED + * DEVICE_IN_USE + * INTERNAL_ERR + * NO_MEMORY + * MODEM_ERR + * INVALID_ARGUMENTS + * REQUEST_NOT_SUPPORTED + * NO_RESOURCES + * CANCELLED + * + */ +#define RIL_REQUEST_START_NETWORK_SCAN 142 + +/** + * RIL_REQUEST_STOP_NETWORK_SCAN + * + * Stops an ongoing network scan + * + * Request to stop the ongoing network scan. Since the modem can only perform one scan at a time, + * there is no parameter for this request. + * + * "data" is NULL + * "response" is NULL + * + * Valid errors: + * SUCCESS + * INTERNAL_ERR + * MODEM_ERR + * NO_MEMORY + * NO_RESOURCES + * CANCELLED + * REQUEST_NOT_SUPPORTED + * + */ +#define RIL_REQUEST_STOP_NETWORK_SCAN 143 + +/** + * RIL_REQUEST_START_KEEPALIVE + * + * Start a keepalive session + * + * Request that the modem begin sending keepalive packets on a particular + * data call, with a specified source, destination, and format. + * + * "data" is a const RIL_RequestKeepalive + * "response" is RIL_KeepaliveStatus with a valid "handle" + * + * Valid errors: + * SUCCESS + * NO_RESOURCES + * INVALID_ARGUMENTS + * + */ +#define RIL_REQUEST_START_KEEPALIVE 144 + +/** + * RIL_REQUEST_STOP_KEEPALIVE + * + * Stops an ongoing keepalive session + * + * Requests that a keepalive session with the given handle be stopped. + * there is no parameter for this request. + * + * "data" is an integer handle + * "response" is NULL + * + * Valid errors: + * SUCCESS + * INVALID_ARGUMENTS + * + */ +#define RIL_REQUEST_STOP_KEEPALIVE 145 + +/***********************************************************************/ + +/** + * RIL_RESPONSE_ACKNOWLEDGEMENT + * + * This is used by Asynchronous solicited messages and Unsolicited messages + * to acknowledge the receipt of those messages in RIL.java so that the ack + * can be used to let ril.cpp to release wakelock. + * + * Valid errors + * SUCCESS + * RADIO_NOT_AVAILABLE + */ + +#define RIL_RESPONSE_ACKNOWLEDGEMENT 800 + +/***********************************************************************/ + + +#define RIL_UNSOL_RESPONSE_BASE 1000 + +/** + * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED + * + * Indicate when value of RIL_RadioState has changed. + * + * Callee will invoke RIL_RadioStateRequest method on main thread + * + * "data" is NULL + */ + +#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000 + + +/** + * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED + * + * Indicate when call state has changed + * + * Callee will invoke RIL_REQUEST_GET_CURRENT_CALLS on main thread + * + * "data" is NULL + * + * Response should be invoked on, for example, + * "RING", "BUSY", "NO CARRIER", and also call state + * transitions (DIALING->ALERTING ALERTING->ACTIVE) + * + * Redundent or extraneous invocations are tolerated + */ +#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001 + + +/** + * RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED + * + * Called when the voice network state changed + * + * Callee will invoke the following requests on main thread: + * + * RIL_REQUEST_VOICE_REGISTRATION_STATE + * RIL_REQUEST_OPERATOR + * + * "data" is NULL + * + * FIXME should this happen when SIM records are loaded? (eg, for + * EONS) + */ +#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS + * + * Called when new SMS is received. + * + * "data" is const char * + * This is a pointer to a string containing the PDU of an SMS-DELIVER + * as an ascii string of hex digits. The PDU starts with the SMSC address + * per TS 27.005 (+CMT:) + * + * Callee will subsequently confirm the receipt of thei SMS with a + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_NEW_SMS + * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a + * RIL_REQUEST_SMS_ACKNOWLEDGE has been received + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS 1003 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT + * + * Called when new SMS Status Report is received. + * + * "data" is const char * + * This is a pointer to a string containing the PDU of an SMS-STATUS-REPORT + * as an ascii string of hex digits. The PDU starts with the SMSC address + * per TS 27.005 (+CDS:). + * + * Callee will subsequently confirm the receipt of the SMS with a + * RIL_REQUEST_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_NEW_SMS + * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a + * RIL_REQUEST_SMS_ACKNOWLEDGE has been received + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004 + +/** + * RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM + * + * Called when new SMS has been stored on SIM card + * + * "data" is const int * + * ((const int *)data)[0] contains the slot index on the SIM that contains + * the new message + */ + +#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005 + +/** + * RIL_UNSOL_ON_USSD + * + * Called when a new USSD message is received. + * + * "data" is const char ** + * ((const char **)data)[0] points to a type code, which is + * one of these string values: + * "0" USSD-Notify -- text in ((const char **)data)[1] + * "1" USSD-Request -- text in ((const char **)data)[1] + * "2" Session terminated by network + * "3" other local client (eg, SIM Toolkit) has responded + * "4" Operation not supported + * "5" Network timeout + * + * The USSD session is assumed to persist if the type code is "1", otherwise + * the current session (if any) is assumed to have terminated. + * + * ((const char **)data)[1] points to a message string if applicable, which + * should always be in UTF-8. + */ +#define RIL_UNSOL_ON_USSD 1006 +/* Previously #define RIL_UNSOL_ON_USSD_NOTIFY 1006 */ + +/** + * RIL_UNSOL_ON_USSD_REQUEST + * + * Obsolete. Send via RIL_UNSOL_ON_USSD + */ +#define RIL_UNSOL_ON_USSD_REQUEST 1007 + +/** + * RIL_UNSOL_NITZ_TIME_RECEIVED + * + * Called when radio has received a NITZ time message + * + * "data" is const char * pointing to NITZ time string + * in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt" + */ +#define RIL_UNSOL_NITZ_TIME_RECEIVED 1008 + +/** + * RIL_UNSOL_SIGNAL_STRENGTH + * + * Radio may report signal strength rather han have it polled. + * + * "data" is a const RIL_SignalStrength * + */ +#define RIL_UNSOL_SIGNAL_STRENGTH 1009 + + +/** + * RIL_UNSOL_DATA_CALL_LIST_CHANGED + * + * "data" is an array of RIL_Data_Call_Response_v6 identical to that + * returned by RIL_REQUEST_DATA_CALL_LIST. It is the complete list + * of current data contexts including new contexts that have been + * activated. A data call is only removed from this list when the + * framework sends a RIL_REQUEST_DEACTIVATE_DATA_CALL or the radio + * is powered off/on. + * + * See also: RIL_REQUEST_DATA_CALL_LIST + */ + +#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010 + +/** + * RIL_UNSOL_SUPP_SVC_NOTIFICATION + * + * Reports supplementary service related notification from the network. + * + * "data" is a const RIL_SuppSvcNotification * + * + */ + +#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011 + +/** + * RIL_UNSOL_STK_SESSION_END + * + * Indicate when STK session is terminated by SIM. + * + * "data" is NULL + */ +#define RIL_UNSOL_STK_SESSION_END 1012 + +/** + * RIL_UNSOL_STK_PROACTIVE_COMMAND + * + * Indicate when SIM issue a STK proactive command to applications + * + * "data" is a const char * containing SAT/USAT proactive command + * in hexadecimal format string starting with command tag + * + */ +#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013 + +/** + * RIL_UNSOL_STK_EVENT_NOTIFY + * + * Indicate when SIM notifies applcations some event happens. + * Generally, application does not need to have any feedback to + * SIM but shall be able to indicate appropriate messages to users. + * + * "data" is a const char * containing SAT/USAT commands or responses + * sent by ME to SIM or commands handled by ME, in hexadecimal format string + * starting with first byte of response data or command tag + * + */ +#define RIL_UNSOL_STK_EVENT_NOTIFY 1014 + +/** + * RIL_UNSOL_STK_CALL_SETUP + * + * Indicate when SIM wants application to setup a voice call. + * + * "data" is const int * + * ((const int *)data)[0] contains timeout value (in milliseconds) + */ +#define RIL_UNSOL_STK_CALL_SETUP 1015 + +/** + * RIL_UNSOL_SIM_SMS_STORAGE_FULL + * + * Indicates that SMS storage on the SIM is full. Sent when the network + * attempts to deliver a new SMS message. Messages cannot be saved on the + * SIM until space is freed. In particular, incoming Class 2 messages + * cannot be stored. + * + * "data" is null + * + */ +#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016 + +/** + * RIL_UNSOL_SIM_REFRESH + * + * Indicates that file(s) on the SIM have been updated, or the SIM + * has been reinitialized. + * + * In the case where RIL is version 6 or older: + * "data" is an int * + * ((int *)data)[0] is a RIL_SimRefreshResult. + * ((int *)data)[1] is the EFID of the updated file if the result is + * SIM_FILE_UPDATE or NULL for any other result. + * + * In the case where RIL is version 7: + * "data" is a RIL_SimRefreshResponse_v7 * + * + * Note: If the SIM state changes as a result of the SIM refresh (eg, + * SIM_READY -> SIM_LOCKED_OR_ABSENT), RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED + * should be sent. + */ +#define RIL_UNSOL_SIM_REFRESH 1017 + +/** + * RIL_UNSOL_CALL_RING + * + * Ring indication for an incoming call (eg, RING or CRING event). + * There must be at least one RIL_UNSOL_CALL_RING at the beginning + * of a call and sending multiple is optional. If the system property + * ro.telephony.call_ring.multiple is false then the upper layers + * will generate the multiple events internally. Otherwise the vendor + * ril must generate multiple RIL_UNSOL_CALL_RING if + * ro.telephony.call_ring.multiple is true or if it is absent. + * + * The rate of these events is controlled by ro.telephony.call_ring.delay + * and has a default value of 3000 (3 seconds) if absent. + * + * "data" is null for GSM + * "data" is const RIL_CDMA_SignalInfoRecord * if CDMA + */ +#define RIL_UNSOL_CALL_RING 1018 + +/** + * RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED + * + * Indicates that SIM state changes. + * + * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread + + * "data" is null + */ +#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019 + +/** + * RIL_UNSOL_RESPONSE_CDMA_NEW_SMS + * + * Called when new CDMA SMS is received + * + * "data" is const RIL_CDMA_SMS_Message * + * + * Callee will subsequently confirm the receipt of the SMS with + * a RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE + * + * No new RIL_UNSOL_RESPONSE_CDMA_NEW_SMS should be sent until + * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE has been received + * + */ +#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020 + +/** + * RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS + * + * Called when new Broadcast SMS is received + * + * "data" can be one of the following: + * If received from GSM network, "data" is const char of 88 bytes + * which indicates each page of a CBS Message sent to the MS by the + * BTS as coded in 3GPP 23.041 Section 9.4.1.2. + * If received from UMTS network, "data" is const char of 90 up to 1252 + * bytes which contain between 1 and 15 CBS Message pages sent as one + * packet to the MS by the BTS as coded in 3GPP 23.041 Section 9.4.2.2. + * + */ +#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021 + +/** + * RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL + * + * Indicates that SMS storage on the RUIM is full. Messages + * cannot be saved on the RUIM until space is freed. + * + * "data" is null + * + */ +#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022 + +/** + * RIL_UNSOL_RESTRICTED_STATE_CHANGED + * + * Indicates a restricted state change (eg, for Domain Specific Access Control). + * + * Radio need send this msg after radio off/on cycle no matter it is changed or not. + * + * "data" is an int * + * ((int *)data)[0] contains a bitmask of RIL_RESTRICTED_STATE_* values. + */ +#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023 + +/** + * RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE + * + * Indicates that the radio system selection module has + * autonomously entered emergency callback mode. + * + * "data" is null + * + */ +#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024 + +/** + * RIL_UNSOL_CDMA_CALL_WAITING + * + * Called when CDMA radio receives a call waiting indication. + * + * "data" is const RIL_CDMA_CallWaiting * + * + */ +#define RIL_UNSOL_CDMA_CALL_WAITING 1025 + +/** + * RIL_UNSOL_CDMA_OTA_PROVISION_STATUS + * + * Called when CDMA radio receives an update of the progress of an + * OTASP/OTAPA call. + * + * "data" is const int * + * For CDMA this is an integer OTASP/OTAPA status listed in + * RIL_CDMA_OTA_ProvisionStatus. + * + */ +#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026 + +/** + * RIL_UNSOL_CDMA_INFO_REC + * + * Called when CDMA radio receives one or more info recs. + * + * "data" is const RIL_CDMA_InformationRecords * + * + */ +#define RIL_UNSOL_CDMA_INFO_REC 1027 + +/** + * RIL_UNSOL_OEM_HOOK_RAW + * + * This is for OEM specific use. + * + * "data" is a byte[] + */ +#define RIL_UNSOL_OEM_HOOK_RAW 1028 + +/** + * RIL_UNSOL_RINGBACK_TONE + * + * Indicates that nework doesn't have in-band information, need to + * play out-band tone. + * + * "data" is an int * + * ((int *)data)[0] == 0 for stop play ringback tone. + * ((int *)data)[0] == 1 for start play ringback tone. + */ +#define RIL_UNSOL_RINGBACK_TONE 1029 + +/** + * RIL_UNSOL_RESEND_INCALL_MUTE + * + * Indicates that framework/application need reset the uplink mute state. + * + * There may be situations where the mute state becomes out of sync + * between the application and device in some GSM infrastructures. + * + * "data" is null + */ +#define RIL_UNSOL_RESEND_INCALL_MUTE 1030 + +/** + * RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED + * + * Called when CDMA subscription source changed. + * + * "data" is int * + * ((int *)data)[0] is == RIL_CdmaSubscriptionSource + */ +#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031 + +/** + * RIL_UNSOL_CDMA_PRL_CHANGED + * + * Called when PRL (preferred roaming list) changes. + * + * "data" is int * + * ((int *)data)[0] is PRL_VERSION as would be returned by RIL_REQUEST_CDMA_SUBSCRIPTION + */ +#define RIL_UNSOL_CDMA_PRL_CHANGED 1032 + +/** + * RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE + * + * Called when Emergency Callback Mode Ends + * + * Indicates that the radio system selection module has + * proactively exited emergency callback mode. + * + * "data" is NULL + * + */ +#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033 + +/** + * RIL_UNSOL_RIL_CONNECTED + * + * Called the ril connects and returns the version + * + * "data" is int * + * ((int *)data)[0] is RIL_VERSION + */ +#define RIL_UNSOL_RIL_CONNECTED 1034 + +/** + * RIL_UNSOL_VOICE_RADIO_TECH_CHANGED + * + * Indicates that voice technology has changed. Contains new radio technology + * as a data in the message. + * + * "data" is int * + * ((int *)data)[0] is of type const RIL_RadioTechnology + * + */ +#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035 + +/** + * RIL_UNSOL_CELL_INFO_LIST + * + * Same information as returned by RIL_REQUEST_GET_CELL_INFO_LIST, but returned + * at the rate no greater than specified by RIL_REQUEST_SET_UNSOL_CELL_INFO_RATE. + * + * "data" is NULL + * + * "response" is an array of RIL_CellInfo_v12. + */ +#define RIL_UNSOL_CELL_INFO_LIST 1036 + +/** + * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED + * + * This message is DEPRECATED and shall be removed in a future release (target: 2018); + * instead, provide IMS registration status via an IMS Service. + * + * Called when IMS registration state has changed + * + * To get IMS registration state and IMS SMS format, callee needs to invoke the + * following request on main thread: + * + * RIL_REQUEST_IMS_REGISTRATION_STATE + * + * "data" is NULL + * + */ +#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037 + +/** + * RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED + * + * Indicated when there is a change in subscription status. + * This event will be sent in the following scenarios + * - subscription readiness at modem, which was selected by telephony layer + * - when subscription is deactivated by modem due to UICC card removal + * - When network invalidates the subscription i.e. attach reject due to authentication reject + * + * "data" is const int * + * ((const int *)data)[0] == 0 for Subscription Deactivated + * ((const int *)data)[0] == 1 for Subscription Activated + * + */ +#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038 + +/** + * RIL_UNSOL_SRVCC_STATE_NOTIFY + * + * Called when Single Radio Voice Call Continuity(SRVCC) + * progress state has changed + * + * "data" is int * + * ((int *)data)[0] is of type const RIL_SrvccState + * + */ + +#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039 + +/** + * RIL_UNSOL_HARDWARE_CONFIG_CHANGED + * + * Called when the hardware configuration associated with the RILd changes + * + * "data" is an array of RIL_HardwareConfig + * + */ +#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040 + +/** + * RIL_UNSOL_DC_RT_INFO_CHANGED + * + * The message is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO + * Sent when the DC_RT_STATE changes but the time + * between these messages must not be less than the + * value set by RIL_REQUEST_SET_DC_RT_RATE. + * + * "data" is the most recent RIL_DcRtInfo + * + */ +#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041 + +/** + * RIL_UNSOL_RADIO_CAPABILITY + * + * Sent when RIL_REQUEST_SET_RADIO_CAPABILITY completes. + * Returns the phone radio capability exactly as + * RIL_REQUEST_GET_RADIO_CAPABILITY and should be the + * same set as sent by RIL_REQUEST_SET_RADIO_CAPABILITY. + * + * "data" is the RIL_RadioCapability structure + */ +#define RIL_UNSOL_RADIO_CAPABILITY 1042 + +/* + * RIL_UNSOL_ON_SS + * + * Called when SS response is received when DIAL/USSD/SS is changed to SS by + * call control. + * + * "data" is const RIL_StkCcUnsolSsResponse * + * + */ +#define RIL_UNSOL_ON_SS 1043 + +/** + * RIL_UNSOL_STK_CC_ALPHA_NOTIFY + * + * Called when there is an ALPHA from UICC during Call Control. + * + * "data" is const char * containing ALPHA string from UICC in UTF-8 format. + * + */ +#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044 + +/** + * RIL_UNSOL_LCEDATA_RECV + * + * Called when there is an incoming Link Capacity Estimate (LCE) info report. + * + * "data" is the RIL_LceDataInfo structure. + * + */ +#define RIL_UNSOL_LCEDATA_RECV 1045 + + /** + * RIL_UNSOL_PCO_DATA + * + * Called when there is new Carrier PCO data received for a data call. Ideally + * only new data will be forwarded, though this is not required. Multiple + * boxes of carrier PCO data for a given call should result in a series of + * RIL_UNSOL_PCO_DATA calls. + * + * "data" is the RIL_PCO_Data structure. + * + */ +#define RIL_UNSOL_PCO_DATA 1046 + + /** + * RIL_UNSOL_MODEM_RESTART + * + * Called when there is a modem reset. + * + * "reason" is "const char *" containing the reason for the reset. It + * could be a crash signature if the restart was due to a crash or some + * string such as "user-initiated restart" or "AT command initiated + * restart" that explains the cause of the modem restart. + * + * When modem restarts, one of the following radio state transitions will happen + * 1) RADIO_STATE_ON->RADIO_STATE_UNAVAILABLE->RADIO_STATE_ON or + * 2) RADIO_STATE_OFF->RADIO_STATE_UNAVAILABLE->RADIO_STATE_OFF + * This message can be sent either just before the RADIO_STATE changes to RADIO_STATE_UNAVAILABLE + * or just after but should never be sent after the RADIO_STATE changes from UNAVAILABLE to + * AVAILABLE(RADIO_STATE_ON/RADIO_STATE_OFF) again. + * + * It should NOT be sent after the RADIO_STATE changes to AVAILABLE after the + * modem restart as that could be interpreted as a second modem reset by the + * framework. + */ +#define RIL_UNSOL_MODEM_RESTART 1047 + +/** + * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION + * + * Called when the modem needs Carrier specific information that will + * be used to encrypt IMSI and IMPI. + * + * "data" is NULL + * + */ +#define RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION 1048 + +/** + * RIL_UNSOL_NETWORK_SCAN_RESULT + * + * Returns incremental result for the network scan which is started by + * RIL_REQUEST_START_NETWORK_SCAN, sent to report results, status, or errors. + * + * "data" is NULL + * "response" is a const RIL_NetworkScanResult * + */ +#define RIL_UNSOL_NETWORK_SCAN_RESULT 1049 + +/** + * RIL_UNSOL_KEEPALIVE_STATUS + * + * "data" is NULL + * "response" is a const RIL_KeepaliveStatus * + */ +#define RIL_UNSOL_KEEPALIVE_STATUS 1050 + +/***********************************************************************/ + + +#if defined(ANDROID_MULTI_SIM) +/** + * RIL_Request Function pointer + * + * @param request is one of RIL_REQUEST_* + * @param data is pointer to data defined for that RIL_REQUEST_* + * data is owned by caller, and should not be modified or freed by callee + * structures passed as data may contain pointers to non-contiguous memory + * @param t should be used in subsequent call to RIL_onResponse + * @param datalen is the length of "data" which is defined as other argument. It may or may + * not be equal to sizeof(data). Refer to the documentation of individual structures + * to find if pointers listed in the structure are contiguous and counted in the datalen + * length or not. + * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) + * + */ +typedef void (*RIL_RequestFunc) (int request, void *data, + size_t datalen, RIL_Token t, RIL_SOCKET_ID socket_id); + +/** + * This function should return the current radio state synchronously + */ +typedef RIL_RadioState (*RIL_RadioStateRequest)(RIL_SOCKET_ID socket_id); + +#else +/* Backward compatible */ + +/** + * RIL_Request Function pointer + * + * @param request is one of RIL_REQUEST_* + * @param data is pointer to data defined for that RIL_REQUEST_* + * data is owned by caller, and should not be modified or freed by callee + * structures passed as data may contain pointers to non-contiguous memory + * @param t should be used in subsequent call to RIL_onResponse + * @param datalen is the length of "data" which is defined as other argument. It may or may + * not be equal to sizeof(data). Refer to the documentation of individual structures + * to find if pointers listed in the structure are contiguous and counted in the datalen + * length or not. + * (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data)) + * + */ +typedef void (*RIL_RequestFunc) (int request, void *data, + size_t datalen, RIL_Token t); + +/** + * This function should return the current radio state synchronously + */ +typedef RIL_RadioState (*RIL_RadioStateRequest)(); + +#endif + + +/** + * This function returns "1" if the specified RIL_REQUEST code is + * supported and 0 if it is not + * + * @param requestCode is one of RIL_REQUEST codes + */ + +typedef int (*RIL_Supports)(int requestCode); + +/** + * This function is called from a separate thread--not the + * thread that calls RIL_RequestFunc--and indicates that a pending + * request should be cancelled. + * + * On cancel, the callee should do its best to abandon the request and + * call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point. + * + * Subsequent calls to RIL_onRequestComplete for this request with + * other results will be tolerated but ignored. (That is, it is valid + * to ignore the cancellation request) + * + * RIL_Cancel calls should return immediately, and not wait for cancellation + * + * Please see ITU v.250 5.6.1 for how one might implement this on a TS 27.007 + * interface + * + * @param t token wants to be canceled + */ + +typedef void (*RIL_Cancel)(RIL_Token t); + +typedef void (*RIL_TimedCallback) (void *param); + +/** + * Return a version string for your RIL implementation + */ +typedef const char * (*RIL_GetVersion) (void); + +typedef struct { + int version; /* set to RIL_VERSION */ + RIL_RequestFunc onRequest; + RIL_RadioStateRequest onStateRequest; + RIL_Supports supports; + RIL_Cancel onCancel; + RIL_GetVersion getVersion; +} RIL_RadioFunctions; + +typedef struct { + char *apn; /* the APN to connect to */ + char *protocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on + roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/ + int authtype; /* authentication protocol used for this PDP context + (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */ + char *username; /* the username for APN, or NULL */ + char *password; /* the password for APN, or NULL */ +} RIL_InitialAttachApn; + +typedef struct { + char *apn; /* the APN to connect to */ + char *protocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on + home network. For example, "IP", "IPV6", "IPV4V6", or "PPP". */ + char *roamingProtocol; /* one of the PDP_type values in TS 27.007 section 10.1.1 used on + roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/ + int authtype; /* authentication protocol used for this PDP context + (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */ + char *username; /* the username for APN, or NULL */ + char *password; /* the password for APN, or NULL */ + int supportedTypesBitmask; /* supported APN types bitmask. See RIL_ApnTypes for the value of + each bit. */ + int bearerBitmask; /* the bearer bitmask. See RIL_RadioAccessFamily for the value of + each bit. */ + int modemCognitive; /* indicating the APN setting was sent to the modem through + setDataProfile earlier. */ + int mtu; /* maximum transmission unit (MTU) size in bytes */ + char *mvnoType; /* the MVNO type: possible values are "imsi", "gid", "spn" */ + char *mvnoMatchData; /* MVNO match data. Can be anything defined by the carrier. + For example, + SPN like: "A MOBILE", "BEN NL", etc... + IMSI like: "302720x94", "2060188", etc... + GID like: "4E", "33", etc... */ +} RIL_InitialAttachApn_v15; + +typedef struct { + int authContext; /* P2 value of authentication command, see P2 parameter in + 3GPP TS 31.102 7.1.2 */ + char *authData; /* the challenge string in Base64 format, see 3GPP + TS 31.102 7.1.2 */ + char *aid; /* AID value, See ETSI 102.221 8.1 and 101.220 4, + NULL if no value. */ +} RIL_SimAuthentication; + +typedef struct { + int cid; /* Context ID, uniquely identifies this call */ + char *bearer_proto; /* One of the PDP_type values in TS 27.007 section 10.1.1. + For example, "IP", "IPV6", "IPV4V6". */ + int pco_id; /* The protocol ID for this box. Note that only IDs from + FF00H - FFFFH are accepted. If more than one is included + from the network, multiple calls should be made to send all + of them. */ + int contents_length; /* The number of octets in the contents. */ + char *contents; /* Carrier-defined content. It is binary, opaque and + loosely defined in LTE Layer 3 spec 24.008 */ +} RIL_PCO_Data; + +typedef enum { + NATT_IPV4 = 0, /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv4 */ + NATT_IPV6 = 1 /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv6 */ +} RIL_KeepaliveType; + +#define MAX_INADDR_LEN 16 +typedef struct { + RIL_KeepaliveType type; /* Type of keepalive packet */ + char sourceAddress[MAX_INADDR_LEN]; /* Source address in network-byte order */ + int sourcePort; /* Source port if applicable, or 0x7FFFFFFF; + the maximum value is 65535 */ + char destinationAddress[MAX_INADDR_LEN]; /* Destination address in network-byte order */ + int destinationPort; /* Destination port if applicable or 0x7FFFFFFF; + the maximum value is 65535 */ + int maxKeepaliveIntervalMillis; /* Maximum milliseconds between two packets */ + int cid; /* Context ID, uniquely identifies this call */ +} RIL_KeepaliveRequest; + +typedef enum { + KEEPALIVE_ACTIVE, /* Keepalive session is active */ + KEEPALIVE_INACTIVE, /* Keepalive session is inactive */ + KEEPALIVE_PENDING /* Keepalive session status not available */ +} RIL_KeepaliveStatusCode; + +typedef struct { + uint32_t sessionHandle; + RIL_KeepaliveStatusCode code; +} RIL_KeepaliveStatus; + +#ifdef RIL_SHLIB +struct RIL_Env { + /** + * "t" is parameter passed in on previous call to RIL_Notification + * routine. + * + * If "e" != SUCCESS, then response can be null/is ignored + * + * "response" is owned by caller, and should not be modified or + * freed by callee + * + * RIL_onRequestComplete will return as soon as possible + */ + void (*OnRequestComplete)(RIL_Token t, RIL_Errno e, + void *response, size_t responselen); + +#if defined(ANDROID_MULTI_SIM) + /** + * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* + * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * + * "data" is owned by caller, and should not be modified or freed by callee + */ + void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id); +#else + /** + * "unsolResponse" is one of RIL_UNSOL_RESPONSE_* + * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * + * "data" is owned by caller, and should not be modified or freed by callee + */ + void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen); +#endif + /** + * Call user-specifed "callback" function on on the same thread that + * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies + * a relative time value at which the callback is invoked. If relativeTime is + * NULL or points to a 0-filled structure, the callback will be invoked as + * soon as possible + */ + + void (*RequestTimedCallback) (RIL_TimedCallback callback, + void *param, const struct timeval *relativeTime); + /** + * "t" is parameter passed in on previous call RIL_Notification routine + * + * RIL_onRequestAck will be called by vendor when an Async RIL request was received + * by them and an ack needs to be sent back to java ril. + */ + void (*OnRequestAck) (RIL_Token t); +}; + + +/** + * RIL implementations must defined RIL_Init + * argc and argv will be command line arguments intended for the RIL implementation + * Return NULL on error + * + * @param env is environment point defined as RIL_Env + * @param argc number of arguments + * @param argv list fo arguments + * + */ +const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv); + +/** + * If BT SAP(SIM Access Profile) is supported, then RIL implementations must define RIL_SAP_Init + * for initializing RIL_RadioFunctions used for BT SAP communcations. It is called whenever RILD + * starts or modem restarts. Returns handlers for SAP related request that are made on SAP + * sepecific socket, analogous to the RIL_RadioFunctions returned by the call to RIL_Init + * and used on the general RIL socket. + * argc and argv will be command line arguments intended for the RIL implementation + * Return NULL on error. + * + * @param env is environment point defined as RIL_Env + * @param argc number of arguments + * @param argv list fo arguments + * + */ +const RIL_RadioFunctions *RIL_SAP_Init(const struct RIL_Env *env, int argc, char **argv); + +#else /* RIL_SHLIB */ + +/** + * Call this once at startup to register notification routine + * + * @param callbacks user-specifed callback function + */ +void RIL_register (const RIL_RadioFunctions *callbacks); + +void rilc_thread_pool(); + + +/** + * + * RIL_onRequestComplete will return as soon as possible + * + * @param t is parameter passed in on previous call to RIL_Notification + * routine. + * @param e error code + * if "e" != SUCCESS, then response can be null/is ignored + * @param response is owned by caller, and should not be modified or + * freed by callee + * @param responselen the length of response in byte + */ +void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, + void *response, size_t responselen); + +/** + * RIL_onRequestAck will be called by vendor when an Async RIL request was received by them and + * an ack needs to be sent back to java ril. This doesn't mark the end of the command or it's + * results, just that the command was received and will take a while. After sending this Ack + * its vendor's responsibility to make sure that AP is up whenever needed while command is + * being processed. + * + * @param t is parameter passed in on previous call to RIL_Notification + * routine. + */ +void RIL_onRequestAck(RIL_Token t); + +#if defined(ANDROID_MULTI_SIM) +/** + * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* + * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * "data" is owned by caller, and should not be modified or freed by callee + * @param datalen the length of data in byte + */ + +void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen, RIL_SOCKET_ID socket_id); +#else +/** + * @param unsolResponse is one of RIL_UNSOL_RESPONSE_* + * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_* + * "data" is owned by caller, and should not be modified or freed by callee + * @param datalen the length of data in byte + */ + +void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen); +#endif + +/** + * Call user-specifed "callback" function on on the same thread that + * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies + * a relative time value at which the callback is invoked. If relativeTime is + * NULL or points to a 0-filled structure, the callback will be invoked as + * soon as possible + * + * @param callback user-specifed callback function + * @param param parameter list + * @param relativeTime a relative time value at which the callback is invoked + */ + +void RIL_requestTimedCallback (RIL_TimedCallback callback, + void *param, const struct timeval *relativeTime); + +#endif /* RIL_SHLIB */ + +#ifdef __cplusplus +} +#endif + +#endif /*ANDROID_RIL_H*/ diff --git a/include/telephony/ril_cdma_sms.h b/include/telephony/ril_cdma_sms.h new file mode 100644 index 0000000..bcf6b30 --- /dev/null +++ b/include/telephony/ril_cdma_sms.h @@ -0,0 +1,806 @@ +/* + * Copyright (C) 2006 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. + */ + +/* + * ISSUES: + * + */ + +/** + * TODO + * + * + */ + + +#ifndef ANDROID_RIL_CDMA_SMS_H +#define ANDROID_RIL_CDMA_SMS_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used by RIL_REQUEST_CDMA_SEND_SMS and RIL_UNSOL_RESPONSE_CDMA_NEW_SMS */ + +#define RIL_CDMA_SMS_ADDRESS_MAX 36 +#define RIL_CDMA_SMS_SUBADDRESS_MAX 36 +#define RIL_CDMA_SMS_BEARER_DATA_MAX 255 + +typedef enum { + RIL_CDMA_SMS_DIGIT_MODE_4_BIT = 0, /* DTMF digits */ + RIL_CDMA_SMS_DIGIT_MODE_8_BIT = 1, + RIL_CDMA_SMS_DIGIT_MODE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_DigitMode; + +typedef enum { + RIL_CDMA_SMS_NUMBER_MODE_NOT_DATA_NETWORK = 0, + RIL_CDMA_SMS_NUMBER_MODE_DATA_NETWORK = 1, + RIL_CDMA_SMS_NUMBER_MODE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_NumberMode; + +typedef enum { + RIL_CDMA_SMS_NUMBER_TYPE_UNKNOWN = 0, + RIL_CDMA_SMS_NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP = 1, + /* INTERNATIONAL is used when number mode is not data network address. + * DATA_IP is used when the number mode is data network address + */ + RIL_CDMA_SMS_NUMBER_TYPE_NATIONAL_OR_INTERNET_MAIL = 2, + /* NATIONAL is used when the number mode is not data network address. + * INTERNET_MAIL is used when the number mode is data network address. + * For INTERNET_MAIL, in the address data "digits", each byte contains + * an ASCII character. Examples are "x@y.com,a@b.com - ref TIA/EIA-637A 3.4.3.3 + */ + RIL_CDMA_SMS_NUMBER_TYPE_NETWORK = 3, + RIL_CDMA_SMS_NUMBER_TYPE_SUBSCRIBER = 4, + RIL_CDMA_SMS_NUMBER_TYPE_ALPHANUMERIC = 5, + /* GSM SMS: address value is GSM 7-bit chars */ + RIL_CDMA_SMS_NUMBER_TYPE_ABBREVIATED = 6, + RIL_CDMA_SMS_NUMBER_TYPE_RESERVED_7 = 7, + RIL_CDMA_SMS_NUMBER_TYPE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_NumberType; + +typedef enum { + RIL_CDMA_SMS_NUMBER_PLAN_UNKNOWN = 0, + RIL_CDMA_SMS_NUMBER_PLAN_TELEPHONY = 1, /* CCITT E.164 and E.163, including ISDN plan */ + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_2 = 2, + RIL_CDMA_SMS_NUMBER_PLAN_DATA = 3, /* CCITT X.121 */ + RIL_CDMA_SMS_NUMBER_PLAN_TELEX = 4, /* CCITT F.69 */ + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_5 = 5, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_6 = 6, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_7 = 7, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_8 = 8, + RIL_CDMA_SMS_NUMBER_PLAN_PRIVATE = 9, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_10 = 10, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_11 = 11, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_12 = 12, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_13 = 13, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_14 = 14, + RIL_CDMA_SMS_NUMBER_PLAN_RESERVED_15 = 15, + RIL_CDMA_SMS_NUMBER_PLAN_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_NumberPlan; + +typedef struct { + RIL_CDMA_SMS_DigitMode digit_mode; + /* Indicates 4-bit or 8-bit */ + RIL_CDMA_SMS_NumberMode number_mode; + /* Used only when digitMode is 8-bit */ + RIL_CDMA_SMS_NumberType number_type; + /* Used only when digitMode is 8-bit. + * To specify an international address, use the following: + * digitMode = RIL_CDMA_SMS_DIGIT_MODE_8_BIT + * numberMode = RIL_CDMA_SMS_NOT_DATA_NETWORK + * numberType = RIL_CDMA_SMS_NUMBER_TYPE_INTERNATIONAL_OR_DATA_IP + * numberPlan = RIL_CDMA_SMS_NUMBER_PLAN_TELEPHONY + * numberOfDigits = number of digits + * digits = ASCII digits, e.g. '1', '2', '3'3, '4', and '5' + */ + RIL_CDMA_SMS_NumberPlan number_plan; + /* Used only when digitMode is 8-bit */ + unsigned char number_of_digits; + unsigned char digits[ RIL_CDMA_SMS_ADDRESS_MAX ]; + /* Each byte in this array represnts a 40bit or 8-bit digit of address data */ +} RIL_CDMA_SMS_Address; + +typedef enum { + RIL_CDMA_SMS_SUBADDRESS_TYPE_NSAP = 0, /* CCITT X.213 or ISO 8348 AD2 */ + RIL_CDMA_SMS_SUBADDRESS_TYPE_USER_SPECIFIED = 1, /* e.g. X.25 */ + RIL_CDMA_SMS_SUBADDRESS_TYPE_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_SubaddressType; + +typedef struct { + RIL_CDMA_SMS_SubaddressType subaddressType; + /* 1 means the last byte's lower 4 bits should be ignored */ + unsigned char odd; + unsigned char number_of_digits; + /* Each byte respresents a 8-bit digit of subaddress data */ + unsigned char digits[ RIL_CDMA_SMS_SUBADDRESS_MAX ]; +} RIL_CDMA_SMS_Subaddress; + +typedef struct { + int uTeleserviceID; + unsigned char bIsServicePresent; + int uServicecategory; + RIL_CDMA_SMS_Address sAddress; + RIL_CDMA_SMS_Subaddress sSubAddress; + int uBearerDataLen; + unsigned char aBearerData[ RIL_CDMA_SMS_BEARER_DATA_MAX ]; +} RIL_CDMA_SMS_Message; + +/* Used by RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE */ + +typedef enum { + RIL_CDMA_SMS_NO_ERROR = 0, + RIL_CDMA_SMS_ERROR = 1, + RIL_CDMA_SMS_ERROR_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_ErrorClass; + +typedef struct { + RIL_CDMA_SMS_ErrorClass uErrorClass; + int uSMSCauseCode; /* As defined in N.S00005, 6.5.2.125. + Currently, only 35 (resource shortage) and + 39 (other terminal problem) are reported. */ +} RIL_CDMA_SMS_Ack; + +/* Used by RIL_REQUEST_CDMA_SMS_GET_BROADCAST_CONFIG and + RIL_REQUEST_CDMA_SMS_SET_BROADCAST_CONFIG */ + +typedef struct { + int service_category; + int language; + unsigned char selected; +} RIL_CDMA_BroadcastSmsConfigInfo; + +/* Used by RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM */ + +typedef struct { + int status; /* Status of message. See TS 27.005 3.1, "": */ + /* 0 = "REC UNREAD" */ + /* 1 = "REC READ" */ + /* 2 = "STO UNSENT" */ + /* 3 = "STO SENT" */ + + RIL_CDMA_SMS_Message message; +} RIL_CDMA_SMS_WriteArgs; + + +/* Used by RIL_REQUEST_ENCODE_CDMA_SMS and RIL_REQUEST_DECODE_CDMA_SMS*/ + +#define RIL_CDMA_SMS_UDH_MAX_SND_SIZE 128 +#define RIL_CDMA_SMS_UDH_EO_DATA_SEGMENT_MAX 131 /* 140 - 3 - 6 */ +#define RIL_CDMA_SMS_MAX_UD_HEADERS 7 +#define RIL_CDMA_SMS_USER_DATA_MAX 229 +#define RIL_CDMA_SMS_ADDRESS_MAX 36 +#define RIL_CDMA_SMS_UDH_LARGE_PIC_SIZE 128 +#define RIL_CDMA_SMS_UDH_SMALL_PIC_SIZE 32 +#define RIL_CDMA_SMS_UDH_VAR_PIC_SIZE 134 +#define RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS 4 +#define RIL_CDMA_SMS_UDH_LARGE_BITMAP_SIZE 32 +#define RIL_CDMA_SMS_UDH_SMALL_BITMAP_SIZE 8 +#define RIL_CDMA_SMS_UDH_OTHER_SIZE 226 +#define RIL_CDMA_SMS_IP_ADDRESS_SIZE 4 + +/* ------------------- */ +/* ---- User Data ---- */ +/* ------------------- */ +typedef enum { + RIL_CDMA_SMS_UDH_CONCAT_8 = 0x00, + RIL_CDMA_SMS_UDH_SPECIAL_SM, + /* 02 - 03 Reserved */ + RIL_CDMA_SMS_UDH_PORT_8 = 0x04, + RIL_CDMA_SMS_UDH_PORT_16, + RIL_CDMA_SMS_UDH_SMSC_CONTROL, + RIL_CDMA_SMS_UDH_SOURCE, + RIL_CDMA_SMS_UDH_CONCAT_16, + RIL_CDMA_SMS_UDH_WCMP, + RIL_CDMA_SMS_UDH_TEXT_FORMATING, + RIL_CDMA_SMS_UDH_PRE_DEF_SOUND, + RIL_CDMA_SMS_UDH_USER_DEF_SOUND, + RIL_CDMA_SMS_UDH_PRE_DEF_ANIM, + RIL_CDMA_SMS_UDH_LARGE_ANIM, + RIL_CDMA_SMS_UDH_SMALL_ANIM, + RIL_CDMA_SMS_UDH_LARGE_PICTURE, + RIL_CDMA_SMS_UDH_SMALL_PICTURE, + RIL_CDMA_SMS_UDH_VAR_PICTURE, + + RIL_CDMA_SMS_UDH_USER_PROMPT = 0x13, + RIL_CDMA_SMS_UDH_EXTENDED_OBJECT = 0x14, + + /* 15 - 1F Reserved for future EMS */ + + RIL_CDMA_SMS_UDH_RFC822 = 0x20, + + /* 21 - 6F Reserved for future use */ + /* 70 - 7f Reserved for (U)SIM Toolkit Security Headers */ + /* 80 - 9F SME to SME specific use */ + /* A0 - BF Reserved for future use */ + /* C0 - DF SC specific use */ + /* E0 - FF Reserved for future use */ + + RIL_CDMA_SMS_UDH_OTHER = 0xFFFF, /* For unsupported or proprietary headers */ + RIL_CDMA_SMS_UDH_ID_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ + +} RIL_CDMA_SMS_UdhId; + +typedef struct { + /*indicates the reference number for a particular concatenated short message. */ + /*it is constant for every short message which makes up a particular concatenated short message*/ + unsigned char msg_ref; + + /*indicates the total number of short messages within the concatenated short message. + The value shall start at 1 and remain constant for every + short message which makes up the concatenated short message. + if it is 0 then the receiving entity shall ignore the whole Information Element*/ + unsigned char total_sm; + + /* + * it indicates the sequence number of a particular short message within the concatenated short + * message. The value shall start at 1 and increment by one for every short message sent + * within the concatenated short message. If the value is zero or the value is + * greater than the value in octet 2 then the receiving + * entity shall ignore the whole Information Element. + */ + unsigned char seq_num; +} RIL_CDMA_SMS_UdhConcat8; + +/* GW message waiting actions +*/ +typedef enum { + RIL_CDMA_SMS_GW_MSG_WAITING_NONE, + RIL_CDMA_SMS_GW_MSG_WAITING_DISCARD, + RIL_CDMA_SMS_GW_MSG_WAITING_STORE, + RIL_CDMA_SMS_GW_MSG_WAITING_NONE_1111, + RIL_CDMA_SMS_GW_MSG_WAITING_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_GWMsgWaiting; + +/* GW message waiting types +*/ +typedef enum { + RIL_CDMA_SMS_GW_MSG_WAITING_VOICEMAIL, + RIL_CDMA_SMS_GW_MSG_WAITING_FAX, + RIL_CDMA_SMS_GW_MSG_WAITING_EMAIL, + RIL_CDMA_SMS_GW_MSG_WAITING_OTHER, + RIL_CDMA_SMS_GW_MSG_WAITING_KIND_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_GWMsgWaitingKind; + +typedef struct { + RIL_CDMA_SMS_GWMsgWaiting msg_waiting; + RIL_CDMA_SMS_GWMsgWaitingKind msg_waiting_kind; + + /*it indicates the number of messages of the type specified in Octet 1 waiting.*/ + unsigned char message_count; +} RIL_CDMA_SMS_UdhSpecialSM; + +typedef struct { + unsigned char dest_port; + unsigned char orig_port; +} RIL_CDMA_SMS_UdhWap8; + +typedef struct { + unsigned short dest_port; + unsigned short orig_port; +} RIL_CDMA_SMS_UdhWap16; + +typedef struct { + unsigned short msg_ref; + unsigned char total_sm; + unsigned char seq_num; + +} RIL_CDMA_SMS_UdhConcat16; + +typedef enum { + RIL_CDMA_SMS_UDH_LEFT_ALIGNMENT = 0, + RIL_CDMA_SMS_UDH_CENTER_ALIGNMENT, + RIL_CDMA_SMS_UDH_RIGHT_ALIGNMENT, + RIL_CDMA_SMS_UDH_DEFAULT_ALIGNMENT, + RIL_CDMA_SMS_UDH_MAX_ALIGNMENT, + RIL_CDMA_SMS_UDH_ALIGNMENT_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_UdhAlignment; + +typedef enum { + RIL_CDMA_SMS_UDH_FONT_NORMAL = 0, + RIL_CDMA_SMS_UDH_FONT_LARGE, + RIL_CDMA_SMS_UDH_FONT_SMALL, + RIL_CDMA_SMS_UDH_FONT_RESERVED, + RIL_CDMA_SMS_UDH_FONT_MAX, + RIL_CDMA_SMS_UDH_FONT_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_UdhFontSize; + +typedef enum { + RIL_CDMA_SMS_UDH_TEXT_COLOR_BLACK = 0x0, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_GREY = 0x1, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_RED = 0x2, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_YELLOW = 0x3, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_GREEN = 0x4, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_CYAN = 0x5, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_BLUE = 0x6, + RIL_CDMA_SMS_UDH_TEXT_COLOR_DARK_MAGENTA = 0x7, + RIL_CDMA_SMS_UDH_TEXT_COLOR_GREY = 0x8, + RIL_CDMA_SMS_UDH_TEXT_COLOR_WHITE = 0x9, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_RED = 0xA, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_YELLOW = 0xB, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_GREEN = 0xC, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_CYAN = 0xD, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_BLUE = 0xE, + RIL_CDMA_SMS_UDH_TEXT_COLOR_BRIGHT_MAGENTA = 0xF, + RIL_CDMA_SMS_UDH_TEXT_COLOR_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_UdhTextColor; + +typedef struct { + unsigned char start_position; + unsigned char text_formatting_length; + RIL_CDMA_SMS_UdhAlignment alignment_type ; /*bit 0 and bit 1*/ + RIL_CDMA_SMS_UdhFontSize font_size ; /*bit 3 and bit 2*/ + unsigned char style_bold; /*bit 4 */ + unsigned char style_italic; /*bit 5 */ + unsigned char style_underlined; /*bit 6 */ + unsigned char style_strikethrough; /*bit 7 */ + + /* if FALSE, ignore the following color information */ + unsigned char is_color_present; + RIL_CDMA_SMS_UdhTextColor text_color_foreground; + RIL_CDMA_SMS_UdhTextColor text_color_background; + +} RIL_CDMA_SMS_UdhTextFormating; + +/* Predefined sound +*/ +typedef struct { + unsigned char position; + unsigned char snd_number; +} RIL_CDMA_SMS_UdhPreDefSound; + +/* User Defined sound +*/ +typedef struct { + unsigned char data_length; + unsigned char position; + unsigned char user_def_sound[RIL_CDMA_SMS_UDH_MAX_SND_SIZE]; +} RIL_CDMA_SMS_UdhUserDefSound; + +/* Large picture +*/ +typedef struct { + unsigned char position; + unsigned char data[RIL_CDMA_SMS_UDH_LARGE_PIC_SIZE]; +} RIL_CDMA_SMS_UdhLargePictureData; + +/* Small picture +*/ +typedef struct { + unsigned char position; + unsigned char data[RIL_CDMA_SMS_UDH_SMALL_PIC_SIZE]; +} RIL_CDMA_SMS_UdhSmallPictureData; + +/* Variable length picture +*/ +typedef struct { + unsigned char position; + unsigned char width; /* Number of pixels - Should be a mutliple of 8 */ + unsigned char height; + unsigned char data[RIL_CDMA_SMS_UDH_VAR_PIC_SIZE]; +} RIL_CDMA_SMS_UdhVarPicture; + +/* Predefined animation +*/ +typedef struct { + unsigned char position; + unsigned char animation_number; +} RIL_CDMA_SMS_UdhPreDefAnim; + +/* Large animation +*/ +typedef struct { + unsigned char position; + unsigned char data[RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS][RIL_CDMA_SMS_UDH_LARGE_BITMAP_SIZE]; +} RIL_CDMA_SMS_UdhLargeAnim; + +/* Small animation +*/ +typedef struct { + unsigned char position; + unsigned char data[RIL_CDMA_SMS_UDH_ANIM_NUM_BITMAPS][RIL_CDMA_SMS_UDH_SMALL_BITMAP_SIZE]; +} RIL_CDMA_SMS_UdhSmallAnim; + +/* User Prompt Indicator UDH +*/ +typedef struct { + unsigned char number_of_objects; + /* Number of objects of the same kind that follow this header which will + ** be stitched together by the applications. For example, 5 small pictures + ** are to be stitched together horizontally, or 6 iMelody tones are to be + ** connected together with intermediate iMelody header and footer ignored. + ** Allowed objects to be stitched: + ** - Images (small, large, variable) + ** - User defined sounds + */ +} RIL_CDMA_SMS_UdhUserPrompt; + +typedef struct { + unsigned char length; + + unsigned char data[RIL_CDMA_SMS_UDH_EO_DATA_SEGMENT_MAX]; + /* RIL_CDMA_SMS_UDH_EO_VCARD: See http://www.imc.org/pdi/vcard-21.doc for payload */ + /* RIL_CDMA_SMS_UDH_EO_VCALENDAR: See http://www.imc.org/pdi/vcal-10.doc */ + /* Or: Unsupported/proprietary extended objects */ + +} RIL_CDMA_SMS_UdhEoContent; + +/* Extended Object UDH +*/ +/* Extended Object IDs/types +*/ +typedef enum { + RIL_CDMA_SMS_UDH_EO_VCARD = 0x09, + RIL_CDMA_SMS_UDH_EO_VCALENDAR = 0x0A, + RIL_CDMA_SMS_UDH_EO_MAX32 = 0x10000000 /* Force constant ENUM size in structures */ +} RIL_CDMA_SMS_UdhEoId; + +typedef struct { + /* Extended objects are to be used together with 16-bit concatenation + ** UDH. The max number of segments supported for E.O. is 8 at least. + */ + RIL_CDMA_SMS_UdhEoContent content; + + unsigned char first_segment; + /* The following fields are only present in the first segment of a + ** concatenated SMS message. + */ + unsigned char reference; + /* Identify those extended object segments which should be linked together + */ + unsigned short length; + /* Length of the whole extended object data + */ + unsigned char control; + RIL_CDMA_SMS_UdhEoId type; + unsigned short position; + /* Absolute position of the E.O. in the whole text after concatenation, + ** starting from 1. + */ +} RIL_CDMA_SMS_UdhEo; + +typedef struct { + RIL_CDMA_SMS_UdhId header_id; + unsigned char header_length; + unsigned char data[RIL_CDMA_SMS_UDH_OTHER_SIZE]; +} RIL_CDMA_SMS_UdhOther; + +typedef struct { + unsigned char header_length; +} RIL_CDMA_SMS_UdhRfc822; + +typedef struct { + RIL_CDMA_SMS_UdhId header_id; + + union { + RIL_CDMA_SMS_UdhConcat8 concat_8; // 00 + + RIL_CDMA_SMS_UdhSpecialSM special_sm; // 01 + RIL_CDMA_SMS_UdhWap8 wap_8; // 04 + RIL_CDMA_SMS_UdhWap16 wap_16; // 05 + RIL_CDMA_SMS_UdhConcat16 concat_16; // 08 + RIL_CDMA_SMS_UdhTextFormating text_formating; // 0a + RIL_CDMA_SMS_UdhPreDefSound pre_def_sound; // 0b + RIL_CDMA_SMS_UdhUserDefSound user_def_sound; // 0c + RIL_CDMA_SMS_UdhPreDefAnim pre_def_anim; // 0d + RIL_CDMA_SMS_UdhLargeAnim large_anim; // 0e + RIL_CDMA_SMS_UdhSmallAnim small_anim; // 0f + RIL_CDMA_SMS_UdhLargePictureData large_picture; // 10 + RIL_CDMA_SMS_UdhSmallPictureData small_picture; // 11 + RIL_CDMA_SMS_UdhVarPicture var_picture; // 12 + + RIL_CDMA_SMS_UdhUserPrompt user_prompt; // 13 + RIL_CDMA_SMS_UdhEo eo; // 14 + + RIL_CDMA_SMS_UdhRfc822 rfc822; // 20 + RIL_CDMA_SMS_UdhOther other; + + }u; +} RIL_CDMA_SMS_Udh; + +/* ----------------------------- */ +/* -- User data encoding type -- */ +/* ----------------------------- */ +typedef enum { + RIL_CDMA_SMS_ENCODING_OCTET = 0, /* 8-bit */ + RIL_CDMA_SMS_ENCODING_IS91EP, /* varies */ + RIL_CDMA_SMS_ENCODING_ASCII, /* 7-bit */ + RIL_CDMA_SMS_ENCODING_IA5, /* 7-bit */ + RIL_CDMA_SMS_ENCODING_UNICODE, /* 16-bit */ + RIL_CDMA_SMS_ENCODING_SHIFT_JIS, /* 8 or 16-bit */ + RIL_CDMA_SMS_ENCODING_KOREAN, /* 8 or 16-bit */ + RIL_CDMA_SMS_ENCODING_LATIN_HEBREW, /* 8-bit */ + RIL_CDMA_SMS_ENCODING_LATIN, /* 8-bit */ + RIL_CDMA_SMS_ENCODING_GSM_7_BIT_DEFAULT, /* 7-bit */ + RIL_CDMA_SMS_ENCODING_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_UserDataEncoding; + +/* ------------------------ */ +/* -- IS-91 EP data type -- */ +/* ------------------------ */ +typedef enum { + RIL_CDMA_SMS_IS91EP_VOICE_MAIL = 0x82, + RIL_CDMA_SMS_IS91EP_SHORT_MESSAGE_FULL = 0x83, + RIL_CDMA_SMS_IS91EP_CLI_ORDER = 0x84, + RIL_CDMA_SMS_IS91EP_SHORT_MESSAGE = 0x85, + RIL_CDMA_SMS_IS91EP_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_IS91EPType; + +typedef struct { + /* NOTE: If message_id.udh_present == TRUE: + ** 'num_headers' is the number of User Data Headers (UDHs), + ** and 'headers' include all those headers. + */ + unsigned char num_headers; + RIL_CDMA_SMS_Udh headers[RIL_CDMA_SMS_MAX_UD_HEADERS]; + + RIL_CDMA_SMS_UserDataEncoding encoding; + RIL_CDMA_SMS_IS91EPType is91ep_type; + + /*---------------------------------------------------------------------- + 'data_len' indicates the valid number of bytes in the 'data' array. + + 'padding_bits' (0-7) indicates how many bits in the last byte of 'data' + are invalid bits. This parameter is only used for Mobile-Originated + messages. There is no way for the API to tell how many padding bits + exist in the received message. Instead, the application can find out how + many padding bits exist in the user data when decoding the user data. + + 'data' has the raw bits of the user data field of the SMS message. + The client software should decode the raw user data according to its + supported encoding types and languages. + + EXCEPTION 1: CMT-91 user data raw bits are first translated into BD fields + (e.g. num_messages, callback, etc.) The translated user data field in + VMN and Short Message is in the form of ASCII characters, each occupying + a byte in the resulted 'data'. + + EXCEPTION 2: GSM 7-bit Default characters are decoded so that each byte + has one 7-bit GSM character. + + 'number_of_digits' is the number of digits/characters (7, 8, 16, or + whatever bits) in the raw user data, which can be used by the client + when decoding the user data according to the encoding type and language. + -------------------------------------------------------------------------*/ + unsigned char data_len; + unsigned char padding_bits; + unsigned char data[ RIL_CDMA_SMS_USER_DATA_MAX ]; + unsigned char number_of_digits; + +} RIL_CDMA_SMS_CdmaUserData; + +/* -------------------- */ +/* ---- Message Id ---- */ +/* -------------------- */ +typedef enum { + RIL_CDMA_SMS_BD_TYPE_RESERVED_0 = 0, + RIL_CDMA_SMS_BD_TYPE_DELIVER, /* MT only */ + RIL_CDMA_SMS_BD_TYPE_SUBMIT, /* MO only */ + RIL_CDMA_SMS_BD_TYPE_CANCELLATION, /* MO only */ + RIL_CDMA_SMS_BD_TYPE_DELIVERY_ACK, /* MT only */ + RIL_CDMA_SMS_BD_TYPE_USER_ACK, /* MT & MO */ + RIL_CDMA_SMS_BD_TYPE_READ_ACK, /* MT & MO */ + RIL_CDMA_SMS_BD_TYPE_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_BdMessageType; + +typedef unsigned int RIL_CDMA_SMS_MessageNumber; + +typedef struct { + RIL_CDMA_SMS_BdMessageType type; + RIL_CDMA_SMS_MessageNumber id_number; + unsigned char udh_present; + /* NOTE: if FEATURE_SMS_UDH is not defined, + ** udh_present should be ignored. + */ +} RIL_CDMA_SMS_MessageId; + +typedef unsigned char RIL_CDMA_SMS_UserResponse; + +/* ------------------- */ +/* ---- Timestamp ---- */ +/* ------------------- */ +typedef struct { + /* If 'year' is between 96 and 99, the actual year is 1900 + 'year'; + if 'year' is between 00 and 95, the actual year is 2000 + 'year'. + NOTE: Each field has two BCD digits and byte arrangement is + */ + unsigned char year; /* 0x00-0x99 */ + unsigned char month; /* 0x01-0x12 */ + unsigned char day; /* 0x01-0x31 */ + unsigned char hour; /* 0x00-0x23 */ + unsigned char minute; /* 0x00-0x59 */ + unsigned char second; /* 0x00-0x59 */ + signed char timezone; /* +/-, [-48,+48] number of 15 minutes - GW only */ +} RIL_CDMA_SMS_Timestamp; + +/* ------------------ */ +/* ---- Priority ---- */ +/* ------------------ */ +typedef enum { + RIL_CDMA_SMS_PRIORITY_NORMAL = 0, + RIL_CDMA_SMS_PRIORITY_INTERACTIVE, + RIL_CDMA_SMS_PRIORITY_URGENT, + RIL_CDMA_SMS_PRIORITY_EMERGENCY, + RIL_CDMA_SMS_PRIORITY_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_Priority; + +/* ----------------- */ +/* ---- Privacy ---- */ +/* ----------------- */ +typedef enum { + RIL_CDMA_SMS_PRIVACY_NORMAL = 0, + RIL_CDMA_SMS_PRIVACY_RESTRICTED, + RIL_CDMA_SMS_PRIVACY_CONFIDENTIAL, + RIL_CDMA_SMS_PRIVACY_SECRET, + RIL_CDMA_SMS_PRIVACY_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_Privacy; + +/* ---------------------- */ +/* ---- Reply option ---- */ +/* ---------------------- */ +typedef struct { + /* whether user ack is requested + */ + unsigned char user_ack_requested; + + /* whether delivery ack is requested. + Should be FALSE for incoming messages. + */ + unsigned char delivery_ack_requested; + + /* Message originator requests the receiving phone to send back a READ_ACK + ** message automatically when the user reads the received message. + */ + unsigned char read_ack_requested; + +} RIL_CDMA_SMS_ReplyOption; + +typedef enum { + RIL_CDMA_SMS_ALERT_MODE_DEFAULT = 0, + RIL_CDMA_SMS_ALERT_MODE_LOW_PRIORITY = 1, + RIL_CDMA_SMS_ALERT_MODE_MEDIUM_PRIORITY = 2, + RIL_CDMA_SMS_ALERT_MODE_HIGH_PRIORITY = 3, + + /* For pre-IS637A implementations, alert_mode only has values of True/False: + */ + RIL_CDMA_SMS_ALERT_MODE_OFF = 0, + RIL_CDMA_SMS_ALERT_MODE_ON = 1 + +} RIL_CDMA_SMS_AlertMode; + +/* ------------------ */ +/* ---- Language ---- */ +/* ------------------ */ +typedef enum { + RIL_CDMA_SMS_LANGUAGE_UNSPECIFIED = 0, + RIL_CDMA_SMS_LANGUAGE_ENGLISH, + RIL_CDMA_SMS_LANGUAGE_FRENCH, + RIL_CDMA_SMS_LANGUAGE_SPANISH, + RIL_CDMA_SMS_LANGUAGE_JAPANESE, + RIL_CDMA_SMS_LANGUAGE_KOREAN, + RIL_CDMA_SMS_LANGUAGE_CHINESE, + RIL_CDMA_SMS_LANGUAGE_HEBREW, + RIL_CDMA_SMS_LANGUAGE_MAX32 = 0x10000000 + +} RIL_CDMA_SMS_Language; + +/* ---------------------------------- */ +/* ---------- Display Mode ---------- */ +/* ---------------------------------- */ +typedef enum { + RIL_CDMA_SMS_DISPLAY_MODE_IMMEDIATE = 0, + RIL_CDMA_SMS_DISPLAY_MODE_DEFAULT = 1, + RIL_CDMA_SMS_DISPLAY_MODE_USER_INVOKE = 2, + RIL_CDMA_SMS_DISPLAY_MODE_RESERVED = 3 +} RIL_CDMA_SMS_DisplayMode; + +/* IS-637B parameters/fields +*/ + +/* ---------------------------------- */ +/* ---------- Delivery Status ------- */ +/* ---------------------------------- */ +typedef enum { + RIL_CDMA_SMS_DELIVERY_STATUS_ACCEPTED = 0, /* ERROR_CLASS_NONE */ + RIL_CDMA_SMS_DELIVERY_STATUS_DEPOSITED_TO_INTERNET = 1, /* ERROR_CLASS_NONE */ + RIL_CDMA_SMS_DELIVERY_STATUS_DELIVERED = 2, /* ERROR_CLASS_NONE */ + RIL_CDMA_SMS_DELIVERY_STATUS_CANCELLED = 3, /* ERROR_CLASS_NONE */ + + RIL_CDMA_SMS_DELIVERY_STATUS_NETWORK_CONGESTION = 4, /* ERROR_CLASS_TEMP & PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_NETWORK_ERROR = 5, /* ERROR_CLASS_TEMP & PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_CANCEL_FAILED = 6, /* ERROR_CLASS_PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_BLOCKED_DESTINATION = 7, /* ERROR_CLASS_PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_TEXT_TOO_LONG = 8, /* ERROR_CLASS_PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_DUPLICATE_MESSAGE = 9, /* ERROR_CLASS_PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_INVALID_DESTINATION = 10, /* ERROR_CLASS_PERM */ + RIL_CDMA_SMS_DELIVERY_STATUS_MESSAGE_EXPIRED = 13, /* ERROR_CLASS_PERM */ + + RIL_CDMA_SMS_DELIVERY_STATUS_UNKNOWN_ERROR = 0x1F /* ERROR_CLASS_PERM */ + + /* All the other values are reserved */ + +} RIL_CDMA_SMS_DeliveryStatusE; + +typedef struct { + RIL_CDMA_SMS_ErrorClass error_class; + RIL_CDMA_SMS_DeliveryStatusE status; +} RIL_CDMA_SMS_DeliveryStatus; + +typedef struct { + unsigned char address[RIL_CDMA_SMS_IP_ADDRESS_SIZE]; + unsigned char is_valid; +} RIL_CDMA_SMS_IpAddress; + +/* This special parameter captures any unrecognized/proprietary parameters +*/ +typedef struct { + unsigned char input_other_len; + unsigned char desired_other_len; /* used during decoding */ + unsigned char * other_data; +} RIL_CDMA_SMS_OtherParm; + +typedef struct { + /* the mask indicates which fields are present in this message */ + unsigned int mask; + + RIL_CDMA_SMS_MessageId message_id; + RIL_CDMA_SMS_CdmaUserData user_data; + RIL_CDMA_SMS_UserResponse user_response; + RIL_CDMA_SMS_Timestamp mc_time; + RIL_CDMA_SMS_Timestamp validity_absolute; + RIL_CDMA_SMS_Timestamp validity_relative; + RIL_CDMA_SMS_Timestamp deferred_absolute; + RIL_CDMA_SMS_Timestamp deferred_relative; + RIL_CDMA_SMS_Priority priority; + RIL_CDMA_SMS_Privacy privacy; + RIL_CDMA_SMS_ReplyOption reply_option; + unsigned char num_messages; /* the actual value; not BCDs */ + RIL_CDMA_SMS_AlertMode alert_mode; + /* For pre-IS-637A implementations, alert_mode is either Off or On. */ + RIL_CDMA_SMS_Language language; + RIL_CDMA_SMS_Address callback; + RIL_CDMA_SMS_DisplayMode display_mode; + + RIL_CDMA_SMS_DeliveryStatus delivery_status; + unsigned int deposit_index; + + RIL_CDMA_SMS_IpAddress ip_address; + unsigned char rsn_no_notify; + + /* See function comments of wms_ts_decode() and + ** wms_ts_decode_cdma_bd_with_other() for details regarding 'other' parameters + */ + RIL_CDMA_SMS_OtherParm other; + +} RIL_CDMA_SMS_ClientBd; + +typedef struct { + unsigned char length; /* length, in bytes, of the encoded SMS message */ + unsigned char * data; /* the encoded SMS message (max 255 bytes) */ +} RIL_CDMA_Encoded_SMS; + +#ifdef __cplusplus +} +#endif + +#endif /*ANDROID_RIL_CDMA_SMS_H*/ diff --git a/libril/Android.mk b/libril/Android.mk new file mode 100644 index 0000000..3d8062c --- /dev/null +++ b/libril/Android.mk @@ -0,0 +1,50 @@ +# Copyright 2006 The Android Open Source Project + +ifneq ($(BOARD_PROVIDES_LIBRIL),true) + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_VENDOR_MODULE := true + +LOCAL_SRC_FILES:= \ + ril.cpp \ + ril_event.cpp\ + RilSapSocket.cpp \ + ril_service.cpp \ + sap_service.cpp + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libcutils \ + libhardware_legacy \ + librilutils \ + android.hardware.radio@1.0 \ + android.hardware.radio@1.1 \ + android.hardware.radio.deprecated@1.0 \ + libhidlbase \ + libhidltransport \ + libhwbinder + +LOCAL_STATIC_LIBRARIES := \ + libprotobuf-c-nano-enable_malloc \ + +LOCAL_CFLAGS += -Wall -Wextra -Wno-unused-parameter -Werror + +ifeq ($(SIM_COUNT), 2) + LOCAL_CFLAGS += -DANDROID_MULTI_SIM -DDSDA_RILD1 + LOCAL_CFLAGS += -DANDROID_SIM_COUNT_2 +endif + +LOCAL_C_INCLUDES += external/nanopb-c +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../include +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/../include + +LOCAL_MODULE:= libril +LOCAL_CLANG := true +LOCAL_SANITIZE := integer + +include $(BUILD_SHARED_LIBRARY) + +endif # BOARD_PROVIDES_LIBRIL diff --git a/libril/MODULE_LICENSE_APACHE2 b/libril/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 diff --git a/libril/NOTICE b/libril/NOTICE new file mode 100644 index 0000000..c5b1efa --- /dev/null +++ b/libril/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, 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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/libril/RilSapSocket.cpp b/libril/RilSapSocket.cpp new file mode 100644 index 0000000..cf99773 --- /dev/null +++ b/libril/RilSapSocket.cpp @@ -0,0 +1,290 @@ +/* +* Copyright (C) 2014 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 __STDC_LIMIT_MACROS +#include +#define RIL_SHLIB +#include "telephony/ril.h" +#include "RilSapSocket.h" +#include "pb_decode.h" +#include "pb_encode.h" +#undef LOG_TAG +#define LOG_TAG "RIL_UIM_SOCKET" +#include +#include +#include +#include + +static RilSapSocket::RilSapSocketList *head = NULL; + +extern "C" void +RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, + const struct timeval *relativeTime); + +struct RIL_Env RilSapSocket::uimRilEnv = { + .OnRequestComplete = RilSapSocket::sOnRequestComplete, + .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse, + .RequestTimedCallback = RIL_requestTimedCallback +}; + +void RilSapSocket::sOnRequestComplete (RIL_Token t, + RIL_Errno e, + void *response, + size_t responselen) { + RilSapSocket *sap_socket; + SapSocketRequest *request = (SapSocketRequest*) t; + + RLOGD("Socket id:%d", request->socketId); + + sap_socket = getSocketById(request->socketId); + + if (sap_socket) { + sap_socket->onRequestComplete(t,e,response,responselen); + } else { + RLOGE("Invalid socket id"); + if (request->curr->payload) { + free(request->curr->payload); + } + free(request->curr); + free(request); + } +} + +#if defined(ANDROID_MULTI_SIM) +void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, + const void *data, + size_t datalen, + RIL_SOCKET_ID socketId) { + RilSapSocket *sap_socket = getSocketById(socketId); + if (sap_socket) { + sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); + } +} +#else +void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse, + const void *data, + size_t datalen) { + RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1); + if(sap_socket){ + sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen); + } +} +#endif + +void RilSapSocket::printList() { + RilSapSocketList *current = head; + RLOGD("Printing socket list"); + while(NULL != current) { + RLOGD("SocketName:%s",current->socket->name); + RLOGD("Socket id:%d",current->socket->id); + current = current->next; + } +} + +RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) { + RilSapSocket *sap_socket; + RilSapSocketList *current = head; + + RLOGD("Entered getSocketById"); + printList(); + + while(NULL != current) { + if(socketId == current->socket->id) { + sap_socket = current->socket; + return sap_socket; + } + current = current->next; + } + return NULL; +} + +void RilSapSocket::initSapSocket(const char *socketName, + RIL_RadioFunctions *uimFuncs) { + + if (strcmp(socketName, RIL1_SERVICE_NAME) == 0) { + if(!SocketExists(socketName)) { + addSocketToList(socketName, RIL_SOCKET_1, uimFuncs); + } + } + +#if (SIM_COUNT >= 2) + if (strcmp(socketName, RIL2_SERVICE_NAME) == 0) { + if(!SocketExists(socketName)) { + addSocketToList(socketName, RIL_SOCKET_2, uimFuncs); + } + } +#endif + +#if (SIM_COUNT >= 3) + if (strcmp(socketName, RIL3_SERVICE_NAME) == 0) { + if(!SocketExists(socketName)) { + addSocketToList(socketName, RIL_SOCKET_3, uimFuncs); + } + } +#endif + +#if (SIM_COUNT >= 4) + if (strcmp(socketName, RIL4_SERVICE_NAME) == 0) { + if(!SocketExists(socketName)) { + addSocketToList(socketName, RIL_SOCKET_4, uimFuncs); + } + } +#endif +} + +void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid, + RIL_RadioFunctions *uimFuncs) { + RilSapSocket* socket = NULL; + RilSapSocketList *current; + + if(!SocketExists(socketName)) { + socket = new RilSapSocket(socketName, socketid, uimFuncs); + RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList)); + if (!listItem) { + RLOGE("addSocketToList: OOM"); + delete socket; + return; + } + listItem->socket = socket; + listItem->next = NULL; + + RLOGD("Adding socket with id: %d", socket->id); + + if(NULL == head) { + head = listItem; + head->next = NULL; + } + else { + current = head; + while(NULL != current->next) { + current = current->next; + } + current->next = listItem; + } + } +} + +bool RilSapSocket::SocketExists(const char *socketName) { + RilSapSocketList* current = head; + + while(NULL != current) { + if(strcmp(current->socket->name, socketName) == 0) { + return true; + } + current = current->next; + } + return false; +} + +RilSapSocket::RilSapSocket(const char *socketName, + RIL_SOCKET_ID socketId, + RIL_RadioFunctions *inputUimFuncs): + RilSocket(socketName, socketId) { + if (inputUimFuncs) { + uimFuncs = inputUimFuncs; + } +} + +void RilSapSocket::dispatchRequest(MsgHeader *req) { + // SapSocketRequest will be deallocated in onRequestComplete() + SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest)); + if (!currRequest) { + RLOGE("dispatchRequest: OOM"); + // Free MsgHeader allocated in pushRecord() + free(req); + return; + } + currRequest->token = req->token; + currRequest->curr = req; + currRequest->p_next = NULL; + currRequest->socketId = id; + + pendingResponseQueue.enqueue(currRequest); + + if (uimFuncs) { + RLOGI("RilSapSocket::dispatchRequest [%d] > SAP REQUEST type: %d. id: %d. error: %d, \ + token 0x%p", + req->token, + req->type, + req->id, + req->error, + currRequest ); + +#if defined(ANDROID_MULTI_SIM) + uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id); +#else + uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest); +#endif + } +} + +void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response, + size_t response_len) { + SapSocketRequest* request= (SapSocketRequest*)t; + MsgHeader *hdr = request->curr; + + MsgHeader rsp; + rsp.token = request->curr->token; + rsp.type = MsgType_RESPONSE; + rsp.id = request->curr->id; + rsp.error = (Error)e; + rsp.payload = (pb_bytes_array_t *)calloc(1, sizeof(pb_bytes_array_t) + response_len); + if (!rsp.payload) { + RLOGE("onRequestComplete: OOM"); + } else { + if (response && response_len > 0) { + memcpy(rsp.payload->bytes, response, response_len); + rsp.payload->size = response_len; + } else { + rsp.payload->size = 0; + } + + RLOGE("RilSapSocket::onRequestComplete: Token:%d, MessageId:%d ril token 0x%p", + hdr->token, hdr->id, t); + + sap::processResponse(&rsp, this); + free(rsp.payload); + } + + // Deallocate SapSocketRequest + if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) { + RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id); + RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id"); + } + + // Deallocate MsgHeader + free(hdr); +} + +void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) { + if (data && datalen > 0) { + pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1, + sizeof(pb_bytes_array_t) + datalen); + if (!payload) { + RLOGE("onUnsolicitedResponse: OOM"); + return; + } + memcpy(payload->bytes, data, datalen); + payload->size = datalen; + MsgHeader rsp; + rsp.payload = payload; + rsp.type = MsgType_UNSOL_RESPONSE; + rsp.id = (MsgId)unsolResponse; + rsp.error = Error_RIL_E_SUCCESS; + sap::processUnsolResponse(&rsp, this); + free(payload); + } +} \ No newline at end of file diff --git a/libril/RilSapSocket.h b/libril/RilSapSocket.h new file mode 100644 index 0000000..8c8c4bc --- /dev/null +++ b/libril/RilSapSocket.h @@ -0,0 +1,200 @@ +/* +* Copyright (C) 2014 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. +*/ + +#ifndef RIL_UIM_SOCKET_H_INCLUDED +#define RIL_UIM_SOCKET_H_INCLUDED +#define RIL_SHLIB +#include "telephony/ril.h" +#include "RilSocket.h" +#include + +/** + * RilSapSocket is a derived class, derived from the RilSocket abstract + * class, representing sockets for communication between bluetooth SAP module and + * the ril daemon. + *

+ * This class performs the following functions : + *

    + *
  • Initialize the socket. + *
  • Process the requests coming on the socket. + *
  • Provide handlers for Unsolicited and request responses. + *
  • Request and pending response queue handling. + *
+ */ +class RilSapSocket : public RilSocket { + /** + * Place holder for the radio functions returned by the initialization + * function. Currenty only onRequest handler is being used. + */ + RIL_RadioFunctions* uimFuncs; + + /** + * Wrapper struct for handling the requests in the queue. + */ + typedef struct SapSocketRequest { + int token; + MsgHeader* curr; + struct SapSocketRequest* p_next; + RIL_SOCKET_ID socketId; + } SapSocketRequest; + + /** + * Queue for requests that are pending dispatch. + */ + Ril_queue dispatchQueue; + + /** + * Queue for requests that are dispatched but are pending response + */ + Ril_queue pendingResponseQueue; + + public: + /** + * Initialize the socket and add the socket to the list. + * + * @param Name of the socket. + * @param Radio functions to be used by the socket. + */ + static void initSapSocket(const char *socketName, + RIL_RadioFunctions *uimFuncs); + + /** + * Ril envoronment variable that holds the request and + * unsol response handlers. + */ + static struct RIL_Env uimRilEnv; + + /** + * Function to print the socket list. + */ + static void printList(); + + /** + * Dispatches the request to the lower layers. + * It calls the on request function. + * + * @param request The request message. + */ + void dispatchRequest(MsgHeader *request); + + /** + * Class method to get the socket from the socket list. + * + * @param socketId Socket id. + * @return the sap socket. + */ + static RilSapSocket* getSocketById(RIL_SOCKET_ID socketId); + + /** + * Datatype to handle the socket list. + */ + typedef struct RilSapSocketList { + RilSapSocket* socket; + RilSapSocketList *next; + } RilSapSocketList; + + protected: + /** + * Socket handler to be called when a request has + * been completed. + * + * @param Token associated with the request. + * @param Error, if any, while processing the request. + * @param The response payload. + * @param Response payload length. + */ + void onRequestComplete(RIL_Token t,RIL_Errno e, + void *response, size_t response_len); + + /** + * Socket handler to be called when there is an + * unsolicited response. + * + * @param Message id. + * @param Response data. + * @param Response data length. + */ + void onUnsolicitedResponse(int unsolResponse, + void *data, size_t datalen); + + /** + * Class method to add the sap socket to the list of sockets. + * Does nothing if the socket is already present in the list. + * Otherwise, calls the constructor of the parent class(To startlistening) + * and add socket to the socket list. + */ + static void addSocketToList(const char *socketName, RIL_SOCKET_ID socketid, + RIL_RadioFunctions *uimFuncs); + + /** + * Check if a socket of the given name exists in the socket list. + * + * @param Socket name. + * @return true if exists, false otherwise. + */ + static bool SocketExists(const char *socketName); + + private: + /** + * Constructor. + * + * @param Socket name. + * @param Socket id. + * @param Radio functions. + */ + RilSapSocket(const char *socketName, + RIL_SOCKET_ID socketId, + RIL_RadioFunctions *inputUimFuncs); + + /** + * Class method that selects the socket on which the onRequestComplete + * is called. + * + * @param Token associated with the request. + * @param Error, if any, while processing the request. + * @param The response payload. + * @param Response payload length. + */ + static void sOnRequestComplete(RIL_Token t, + RIL_Errno e, void *response, size_t responselen); + +#if defined(ANDROID_MULTI_SIM) + /** + * Class method that selects the socket on which the onUnsolicitedResponse + * is called. + * + * @param Message id. + * @param Response data. + * @param Response data length. + * @param Socket id. + */ + static void sOnUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen, RIL_SOCKET_ID socket_id); +#else + /** + * Class method that selects the socket on which the onUnsolicitedResponse + * is called. + * + * @param Message id. + * @param Response data. + * @param Response data length. + */ + static void sOnUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen); +#endif +}; + +#endif /*RIL_UIM_SOCKET_H_INCLUDED*/ diff --git a/libril/RilSocket.h b/libril/RilSocket.h new file mode 100644 index 0000000..53b00c9 --- /dev/null +++ b/libril/RilSocket.h @@ -0,0 +1,70 @@ +/* +* Copyright (C) 2014 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. +*/ + +#ifndef RIL_SOCKET_H_INCLUDED +#define RIL_SOCKET_H_INCLUDED +#include +#include "rilSocketQueue.h" +#include + +/** + * Abstract socket class representing sockets in rild. + *

+ * This class performs the following functions : + *

    + *
  • Start socket listen. + *
  • Handle socket listen and command callbacks. + *
+ */ +class RilSocket { + protected: + + /** + * Socket name. + */ + const char* name; + + /** + * Socket id. + */ + RIL_SOCKET_ID id; + + public: + + /** + * Constructor. + * + * @param Socket name. + * @param Socket id. + */ + RilSocket(const char* socketName, RIL_SOCKET_ID socketId) { + name = socketName; + id = socketId; + } + + /** + * Get socket id. + * + * @return RIL_SOCKET_ID socket id. + */ + RIL_SOCKET_ID getSocketId(void) { + return id; + } + + virtual ~RilSocket(){} +}; + +#endif diff --git a/libril/ril.cpp b/libril/ril.cpp new file mode 100644 index 0000000..6d375ca --- /dev/null +++ b/libril/ril.cpp @@ -0,0 +1,1227 @@ +/* //device/libs/telephony/ril.cpp +** +** Copyright 2006, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" void +RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen); + +extern "C" void +RIL_onRequestAck(RIL_Token t); +namespace android { + +#define PHONE_PROCESS "radio" +#define BLUETOOTH_PROCESS "bluetooth" + +#define ANDROID_WAKE_LOCK_NAME "radio-interface" + +#define ANDROID_WAKE_LOCK_SECS 0 +#define ANDROID_WAKE_LOCK_USECS 200000 + +#define PROPERTY_RIL_IMPL "gsm.version.ril-impl" + +// match with constant in RIL.java +#define MAX_COMMAND_BYTES (8 * 1024) + +// Basically: memset buffers that the client library +// shouldn't be using anymore in an attempt to find +// memory usage issues sooner. +#define MEMSET_FREED 1 + +#define NUM_ELEMS(a) (sizeof (a) / sizeof (a)[0]) + +/* Negative values for private RIL errno's */ +#define RIL_ERRNO_INVALID_RESPONSE (-1) +#define RIL_ERRNO_NO_MEMORY (-12) + +// request, response, and unsolicited msg print macro +#define PRINTBUF_SIZE 8096 + +enum WakeType {DONT_WAKE, WAKE_PARTIAL}; + +typedef struct { + int requestNumber; + int (*responseFunction) (int slotId, int responseType, int token, + RIL_Errno e, void *response, size_t responselen); + WakeType wakeType; +} UnsolResponseInfo; + +typedef struct UserCallbackInfo { + RIL_TimedCallback p_callback; + void *userParam; + struct ril_event event; + struct UserCallbackInfo *p_next; +} UserCallbackInfo; + +extern "C" const char * failCauseToString(RIL_Errno); +extern "C" const char * callStateToString(RIL_CallState); +extern "C" const char * radioStateToString(RIL_RadioState); +extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id); + +extern "C" +char ril_service_name_base[MAX_SERVICE_NAME_LENGTH] = RIL_SERVICE_NAME_BASE; +extern "C" +char ril_service_name[MAX_SERVICE_NAME_LENGTH] = RIL1_SERVICE_NAME; +/*******************************************************************/ + +RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL}; +static int s_registerCalled = 0; + +static pthread_t s_tid_dispatch; +static int s_started = 0; + +static int s_fdWakeupRead; +static int s_fdWakeupWrite; + +int s_wakelock_count = 0; + +static struct ril_event s_wakeupfd_event; + +static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests = NULL; + +#if (SIM_COUNT >= 2) +static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket2 = NULL; +#endif + +#if (SIM_COUNT >= 3) +static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket3 = NULL; +#endif + +#if (SIM_COUNT >= 4) +static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket4 = NULL; +#endif + +static const struct timeval TIMEVAL_WAKE_TIMEOUT = {ANDROID_WAKE_LOCK_SECS,ANDROID_WAKE_LOCK_USECS}; + + +static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER; + +static UserCallbackInfo *s_last_wake_timeout_info = NULL; + +static void *s_lastNITZTimeData = NULL; +static size_t s_lastNITZTimeDataSize; + +#if RILC_LOG + static char printBuf[PRINTBUF_SIZE]; +#endif + +/*******************************************************************/ +static void grabPartialWakeLock(); +void releaseWakeLock(); +static void wakeTimeoutCallback(void *); + +#ifdef RIL_SHLIB +#if defined(ANDROID_MULTI_SIM) +extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen, RIL_SOCKET_ID socket_id); +#else +extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen); +#endif +#endif + +#if defined(ANDROID_MULTI_SIM) +#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d)) +#else +#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c)) +#endif + +static UserCallbackInfo * internalRequestTimedCallback + (RIL_TimedCallback callback, void *param, + const struct timeval *relativeTime); + +/** Index == requestNumber */ +static CommandInfo s_commands[] = { +#include "ril_commands.h" +}; + +static UnsolResponseInfo s_unsolResponses[] = { +#include "ril_unsol_commands.h" +}; + +char * RIL_getServiceName() { + return ril_service_name; +} + +extern "C" +void RIL_setServiceName(const char * s) { + strncpy(ril_service_name, s, MAX_SERVICE_NAME_LENGTH); +} + +RequestInfo * +addRequestToList(int serial, int slotId, int request) { + RequestInfo *pRI; + int ret; + RIL_SOCKET_ID socket_id = (RIL_SOCKET_ID) slotId; + /* Hook for current context */ + /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ + pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; + /* pendingRequestsHook refer to &s_pendingRequests */ + RequestInfo** pendingRequestsHook = &s_pendingRequests; + +#if (SIM_COUNT >= 2) + if (socket_id == RIL_SOCKET_2) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; + pendingRequestsHook = &s_pendingRequests_socket2; + } +#if (SIM_COUNT >= 3) + else if (socket_id == RIL_SOCKET_3) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3; + pendingRequestsHook = &s_pendingRequests_socket3; + } +#endif +#if (SIM_COUNT >= 4) + else if (socket_id == RIL_SOCKET_4) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4; + pendingRequestsHook = &s_pendingRequests_socket4; + } +#endif +#endif + + pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); + if (pRI == NULL) { + RLOGE("Memory allocation failed for request %s", requestToString(request)); + return NULL; + } + + pRI->token = serial; + pRI->pCI = &(s_commands[request]); + pRI->socket_id = socket_id; + + ret = pthread_mutex_lock(pendingRequestsMutexHook); + assert (ret == 0); + + pRI->p_next = *pendingRequestsHook; + *pendingRequestsHook = pRI; + + ret = pthread_mutex_unlock(pendingRequestsMutexHook); + assert (ret == 0); + + return pRI; +} + +static void triggerEvLoop() { + int ret; + if (!pthread_equal(pthread_self(), s_tid_dispatch)) { + /* trigger event loop to wakeup. No reason to do this, + * if we're in the event loop thread */ + do { + ret = write (s_fdWakeupWrite, " ", 1); + } while (ret < 0 && errno == EINTR); + } +} + +static void rilEventAddWakeup(struct ril_event *ev) { + ril_event_add(ev); + triggerEvLoop(); +} + +/** + * A write on the wakeup fd is done just to pop us out of select() + * We empty the buffer here and then ril_event will reset the timers on the + * way back down + */ +static void processWakeupCallback(int fd, short flags, void *param) { + char buff[16]; + int ret; + + RLOGV("processWakeupCallback"); + + /* empty our wakeup socket out */ + do { + ret = read(s_fdWakeupRead, &buff, sizeof(buff)); + } while (ret > 0 || (ret < 0 && errno == EINTR)); +} + +static void resendLastNITZTimeData(RIL_SOCKET_ID socket_id) { + if (s_lastNITZTimeData != NULL) { + int responseType = (s_callbacks.version >= 13) + ? RESPONSE_UNSOLICITED_ACK_EXP + : RESPONSE_UNSOLICITED; + int ret = radio::nitzTimeReceivedInd( + (int)socket_id, responseType, 0, + RIL_E_SUCCESS, s_lastNITZTimeData, s_lastNITZTimeDataSize); + if (ret == 0) { + free(s_lastNITZTimeData); + s_lastNITZTimeData = NULL; + } + } +} + +void onNewCommandConnect(RIL_SOCKET_ID socket_id) { + // Inform we are connected and the ril version + int rilVer = s_callbacks.version; + RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, + &rilVer, sizeof(rilVer), socket_id); + + // implicit radio state changed + RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, + NULL, 0, socket_id); + + // Send last NITZ time data, in case it was missed + if (s_lastNITZTimeData != NULL) { + resendLastNITZTimeData(socket_id); + } + + // Get version string + if (s_callbacks.getVersion != NULL) { + const char *version; + version = s_callbacks.getVersion(); + RLOGI("RIL Daemon version: %s\n", version); + + property_set(PROPERTY_RIL_IMPL, version); + } else { + RLOGI("RIL Daemon version: unavailable\n"); + property_set(PROPERTY_RIL_IMPL, "unavailable"); + } + +} + +static void userTimerCallback (int fd, short flags, void *param) { + UserCallbackInfo *p_info; + + p_info = (UserCallbackInfo *)param; + + p_info->p_callback(p_info->userParam); + + + // FIXME generalize this...there should be a cancel mechanism + if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) { + s_last_wake_timeout_info = NULL; + } + + free(p_info); +} + + +static void * +eventLoop(void *param) { + int ret; + int filedes[2]; + + ril_event_init(); + + pthread_mutex_lock(&s_startupMutex); + + s_started = 1; + pthread_cond_broadcast(&s_startupCond); + + pthread_mutex_unlock(&s_startupMutex); + + ret = pipe(filedes); + + if (ret < 0) { + RLOGE("Error in pipe() errno:%d", errno); + return NULL; + } + + s_fdWakeupRead = filedes[0]; + s_fdWakeupWrite = filedes[1]; + + fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK); + + ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, + processWakeupCallback, NULL); + + rilEventAddWakeup (&s_wakeupfd_event); + + // Only returns on error + ril_event_loop(); + RLOGE ("error in event_loop_base errno:%d", errno); + // kill self to restart on error + kill(0, SIGKILL); + + return NULL; +} + +extern "C" void +RIL_startEventLoop(void) { + /* spin up eventLoop thread and wait for it to get started */ + s_started = 0; + pthread_mutex_lock(&s_startupMutex); + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL); + if (result != 0) { + RLOGE("Failed to create dispatch thread: %s", strerror(result)); + goto done; + } + + while (s_started == 0) { + pthread_cond_wait(&s_startupCond, &s_startupMutex); + } + +done: + pthread_mutex_unlock(&s_startupMutex); +} + +// Used for testing purpose only. +extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) { + memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); +} + +extern "C" void +RIL_register (const RIL_RadioFunctions *callbacks) { + RLOGI("SIM_COUNT: %d", SIM_COUNT); + + if (callbacks == NULL) { + RLOGE("RIL_register: RIL_RadioFunctions * null"); + return; + } + if (callbacks->version < RIL_VERSION_MIN) { + RLOGE("RIL_register: version %d is to old, min version is %d", + callbacks->version, RIL_VERSION_MIN); + return; + } + + RLOGE("RIL_register: RIL version %d", callbacks->version); + + if (s_registerCalled > 0) { + RLOGE("RIL_register has been called more than once. " + "Subsequent call ignored"); + return; + } + + memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); + + s_registerCalled = 1; + + RLOGI("s_registerCalled flag set, %d", s_started); + // Little self-check + + for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) { + assert(i == s_commands[i].requestNumber); + } + + for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) { + assert(i + RIL_UNSOL_RESPONSE_BASE + == s_unsolResponses[i].requestNumber); + } + + radio::registerService(&s_callbacks, s_commands); + RLOGI("RILHIDL called registerService"); + +} + +extern "C" void +RIL_register_socket (RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **), + RIL_SOCKET_TYPE socketType, int argc, char **argv) { + + RIL_RadioFunctions* UimFuncs = NULL; + + if(Init) { + UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv); + + switch(socketType) { + case RIL_SAP_SOCKET: + RilSapSocket::initSapSocket(RIL1_SERVICE_NAME, UimFuncs); + +#if (SIM_COUNT >= 2) + RilSapSocket::initSapSocket(RIL2_SERVICE_NAME, UimFuncs); +#endif + +#if (SIM_COUNT >= 3) + RilSapSocket::initSapSocket(RIL3_SERVICE_NAME, UimFuncs); +#endif + +#if (SIM_COUNT >= 4) + RilSapSocket::initSapSocket(RIL4_SERVICE_NAME, UimFuncs); +#endif + break; + default:; + } + + RLOGI("RIL_register_socket: calling registerService"); + sap::registerService(UimFuncs); + } +} + +// Check and remove RequestInfo if its a response and not just ack sent back +static int +checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) { + int ret = 0; + /* Hook for current context + pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ + pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; + /* pendingRequestsHook refer to &s_pendingRequests */ + RequestInfo ** pendingRequestsHook = &s_pendingRequests; + + if (pRI == NULL) { + return 0; + } + +#if (SIM_COUNT >= 2) + if (pRI->socket_id == RIL_SOCKET_2) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2; + pendingRequestsHook = &s_pendingRequests_socket2; + } +#if (SIM_COUNT >= 3) + if (pRI->socket_id == RIL_SOCKET_3) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3; + pendingRequestsHook = &s_pendingRequests_socket3; + } +#endif +#if (SIM_COUNT >= 4) + if (pRI->socket_id == RIL_SOCKET_4) { + pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4; + pendingRequestsHook = &s_pendingRequests_socket4; + } +#endif +#endif + pthread_mutex_lock(pendingRequestsMutexHook); + + for(RequestInfo **ppCur = pendingRequestsHook + ; *ppCur != NULL + ; ppCur = &((*ppCur)->p_next) + ) { + if (pRI == *ppCur) { + ret = 1; + if (isAck) { // Async ack + if (pRI->wasAckSent == 1) { + RLOGD("Ack was already sent for %s", requestToString(pRI->pCI->requestNumber)); + } else { + pRI->wasAckSent = 1; + } + } else { + *ppCur = (*ppCur)->p_next; + } + break; + } + } + + pthread_mutex_unlock(pendingRequestsMutexHook); + + return ret; +} + +extern "C" void +RIL_onRequestAck(RIL_Token t) { + RequestInfo *pRI; + + RIL_SOCKET_ID socket_id = RIL_SOCKET_1; + + pRI = (RequestInfo *)t; + + if (!checkAndDequeueRequestInfoIfAck(pRI, true)) { + RLOGE ("RIL_onRequestAck: invalid RIL_Token"); + return; + } + + socket_id = pRI->socket_id; + +#if VDBG + RLOGD("Request Ack, %s", rilSocketIdToString(socket_id)); +#endif + + appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber)); + + if (pRI->cancelled == 0) { + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock( + (int) socket_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + + radio::acknowledgeRequest((int) socket_id, pRI->token); + + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + } +} +extern "C" void +RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) { + RequestInfo *pRI; + int ret; + RIL_SOCKET_ID socket_id = RIL_SOCKET_1; + + pRI = (RequestInfo *)t; + + if (!checkAndDequeueRequestInfoIfAck(pRI, false)) { + RLOGE ("RIL_onRequestComplete: invalid RIL_Token"); + return; + } + + socket_id = pRI->socket_id; +#if VDBG + RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id)); +#endif + + if (pRI->local > 0) { + // Locally issued command...void only! + // response does not go back up the command socket + RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber)); + + free(pRI); + return; + } + + appendPrintBuf("[%04d]< %s", + pRI->token, requestToString(pRI->pCI->requestNumber)); + + if (pRI->cancelled == 0) { + int responseType; + if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) { + // If ack was already sent, then this call is an asynchronous response. So we need to + // send id indicating that we expect an ack from RIL.java as we acquire wakelock here. + responseType = RESPONSE_SOLICITED_ACK_EXP; + grabPartialWakeLock(); + } else { + responseType = RESPONSE_SOLICITED; + } + + // there is a response payload, no matter success or not. +#if VDBG + RLOGE ("Calling responseFunction() for token %d", pRI->token); +#endif + + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock((int) socket_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + + ret = pRI->pCI->responseFunction((int) socket_id, + responseType, pRI->token, e, response, responselen); + + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + } + free(pRI); +} + +static void +grabPartialWakeLock() { + if (s_callbacks.version >= 13) { + int ret; + ret = pthread_mutex_lock(&s_wakeLockCountMutex); + assert(ret == 0); + acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME); + + UserCallbackInfo *p_info = + internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT); + if (p_info == NULL) { + release_wake_lock(ANDROID_WAKE_LOCK_NAME); + } else { + s_wakelock_count++; + if (s_last_wake_timeout_info != NULL) { + s_last_wake_timeout_info->userParam = (void *)1; + } + s_last_wake_timeout_info = p_info; + } + ret = pthread_mutex_unlock(&s_wakeLockCountMutex); + assert(ret == 0); + } else { + acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME); + } +} + +void +releaseWakeLock() { + if (s_callbacks.version >= 13) { + int ret; + ret = pthread_mutex_lock(&s_wakeLockCountMutex); + assert(ret == 0); + + if (s_wakelock_count > 1) { + s_wakelock_count--; + } else { + s_wakelock_count = 0; + release_wake_lock(ANDROID_WAKE_LOCK_NAME); + if (s_last_wake_timeout_info != NULL) { + s_last_wake_timeout_info->userParam = (void *)1; + } + } + + ret = pthread_mutex_unlock(&s_wakeLockCountMutex); + assert(ret == 0); + } else { + release_wake_lock(ANDROID_WAKE_LOCK_NAME); + } +} + +/** + * Timer callback to put us back to sleep before the default timeout + */ +static void +wakeTimeoutCallback (void *param) { + // We're using "param != NULL" as a cancellation mechanism + if (s_callbacks.version >= 13) { + if (param == NULL) { + int ret; + ret = pthread_mutex_lock(&s_wakeLockCountMutex); + assert(ret == 0); + s_wakelock_count = 0; + release_wake_lock(ANDROID_WAKE_LOCK_NAME); + ret = pthread_mutex_unlock(&s_wakeLockCountMutex); + assert(ret == 0); + } + } else { + if (param == NULL) { + releaseWakeLock(); + } + } +} + +#if defined(ANDROID_MULTI_SIM) +extern "C" +void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen, RIL_SOCKET_ID socket_id) +#else +extern "C" +void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, + size_t datalen) +#endif +{ + int unsolResponseIndex; + int ret; + bool shouldScheduleTimeout = false; + RIL_SOCKET_ID soc_id = RIL_SOCKET_1; + +#if defined(ANDROID_MULTI_SIM) + soc_id = socket_id; +#endif + + + if (s_registerCalled == 0) { + // Ignore RIL_onUnsolicitedResponse before RIL_register + RLOGW("RIL_onUnsolicitedResponse called before RIL_register"); + return; + } + + unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE; + + if ((unsolResponseIndex < 0) + || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) { + RLOGE("unsupported unsolicited response code %d", unsolResponse); + return; + } + + // Grab a wake lock if needed for this reponse, + // as we exit we'll either release it immediately + // or set a timer to release it later. + switch (s_unsolResponses[unsolResponseIndex].wakeType) { + case WAKE_PARTIAL: + grabPartialWakeLock(); + shouldScheduleTimeout = true; + break; + + case DONT_WAKE: + default: + // No wake lock is grabed so don't set timeout + shouldScheduleTimeout = false; + break; + } + + appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse)); + + int responseType; + if (s_callbacks.version >= 13 + && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) { + responseType = RESPONSE_UNSOLICITED_ACK_EXP; + } else { + responseType = RESPONSE_UNSOLICITED; + } + + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock((int) soc_id); + int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + + ret = s_unsolResponses[unsolResponseIndex].responseFunction( + (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast(data), + datalen); + + rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(rwlockRet == 0); + + if (s_callbacks.version < 13) { + if (shouldScheduleTimeout) { + UserCallbackInfo *p_info = internalRequestTimedCallback(wakeTimeoutCallback, NULL, + &TIMEVAL_WAKE_TIMEOUT); + + if (p_info == NULL) { + goto error_exit; + } else { + // Cancel the previous request + if (s_last_wake_timeout_info != NULL) { + s_last_wake_timeout_info->userParam = (void *)1; + } + s_last_wake_timeout_info = p_info; + } + } + } + +#if VDBG + RLOGI("%s UNSOLICITED: %s length:%zu", rilSocketIdToString(soc_id), + requestToString(unsolResponse), datalen); +#endif + + if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { + // Unfortunately, NITZ time is not poll/update like everything + // else in the system. So, if the upstream client isn't connected, + // keep a copy of the last NITZ response (with receive time noted + // above) around so we can deliver it when it is connected + + if (s_lastNITZTimeData != NULL) { + free(s_lastNITZTimeData); + s_lastNITZTimeData = NULL; + } + + s_lastNITZTimeData = calloc(datalen, 1); + if (s_lastNITZTimeData == NULL) { + RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse"); + goto error_exit; + } + s_lastNITZTimeDataSize = datalen; + memcpy(s_lastNITZTimeData, data, datalen); + } + + // Normal exit + return; + +error_exit: + if (shouldScheduleTimeout) { + releaseWakeLock(); + } +} + +/** FIXME generalize this if you track UserCAllbackInfo, clear it + when the callback occurs +*/ +static UserCallbackInfo * +internalRequestTimedCallback (RIL_TimedCallback callback, void *param, + const struct timeval *relativeTime) +{ + struct timeval myRelativeTime; + UserCallbackInfo *p_info; + + p_info = (UserCallbackInfo *) calloc(1, sizeof(UserCallbackInfo)); + if (p_info == NULL) { + RLOGE("Memory allocation failed in internalRequestTimedCallback"); + return p_info; + + } + + p_info->p_callback = callback; + p_info->userParam = param; + + if (relativeTime == NULL) { + /* treat null parameter as a 0 relative time */ + memset (&myRelativeTime, 0, sizeof(myRelativeTime)); + } else { + /* FIXME I think event_add's tv param is really const anyway */ + memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime)); + } + + ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info); + + ril_timer_add(&(p_info->event), &myRelativeTime); + + triggerEvLoop(); + return p_info; +} + + +extern "C" void +RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, + const struct timeval *relativeTime) { + internalRequestTimedCallback (callback, param, relativeTime); +} + +const char * +failCauseToString(RIL_Errno e) { + switch(e) { + case RIL_E_SUCCESS: return "E_SUCCESS"; + case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE"; + case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE"; + case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT"; + case RIL_E_SIM_PIN2: return "E_SIM_PIN2"; + case RIL_E_SIM_PUK2: return "E_SIM_PUK2"; + case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED"; + case RIL_E_CANCELLED: return "E_CANCELLED"; + case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL"; + case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW"; + case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY"; + case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT"; + case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME"; +#ifdef FEATURE_MULTIMODE_ANDROID + case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE"; + case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED"; +#endif + case RIL_E_FDN_CHECK_FAILURE: return "E_FDN_CHECK_FAILURE"; + case RIL_E_MISSING_RESOURCE: return "E_MISSING_RESOURCE"; + case RIL_E_NO_SUCH_ELEMENT: return "E_NO_SUCH_ELEMENT"; + case RIL_E_DIAL_MODIFIED_TO_USSD: return "E_DIAL_MODIFIED_TO_USSD"; + case RIL_E_DIAL_MODIFIED_TO_SS: return "E_DIAL_MODIFIED_TO_SS"; + case RIL_E_DIAL_MODIFIED_TO_DIAL: return "E_DIAL_MODIFIED_TO_DIAL"; + case RIL_E_USSD_MODIFIED_TO_DIAL: return "E_USSD_MODIFIED_TO_DIAL"; + case RIL_E_USSD_MODIFIED_TO_SS: return "E_USSD_MODIFIED_TO_SS"; + case RIL_E_USSD_MODIFIED_TO_USSD: return "E_USSD_MODIFIED_TO_USSD"; + case RIL_E_SS_MODIFIED_TO_DIAL: return "E_SS_MODIFIED_TO_DIAL"; + case RIL_E_SS_MODIFIED_TO_USSD: return "E_SS_MODIFIED_TO_USSD"; + case RIL_E_SUBSCRIPTION_NOT_SUPPORTED: return "E_SUBSCRIPTION_NOT_SUPPORTED"; + case RIL_E_SS_MODIFIED_TO_SS: return "E_SS_MODIFIED_TO_SS"; + case RIL_E_LCE_NOT_SUPPORTED: return "E_LCE_NOT_SUPPORTED"; + case RIL_E_NO_MEMORY: return "E_NO_MEMORY"; + case RIL_E_INTERNAL_ERR: return "E_INTERNAL_ERR"; + case RIL_E_SYSTEM_ERR: return "E_SYSTEM_ERR"; + case RIL_E_MODEM_ERR: return "E_MODEM_ERR"; + case RIL_E_INVALID_STATE: return "E_INVALID_STATE"; + case RIL_E_NO_RESOURCES: return "E_NO_RESOURCES"; + case RIL_E_SIM_ERR: return "E_SIM_ERR"; + case RIL_E_INVALID_ARGUMENTS: return "E_INVALID_ARGUMENTS"; + case RIL_E_INVALID_SIM_STATE: return "E_INVALID_SIM_STATE"; + case RIL_E_INVALID_MODEM_STATE: return "E_INVALID_MODEM_STATE"; + case RIL_E_INVALID_CALL_ID: return "E_INVALID_CALL_ID"; + case RIL_E_NO_SMS_TO_ACK: return "E_NO_SMS_TO_ACK"; + case RIL_E_NETWORK_ERR: return "E_NETWORK_ERR"; + case RIL_E_REQUEST_RATE_LIMITED: return "E_REQUEST_RATE_LIMITED"; + case RIL_E_SIM_BUSY: return "E_SIM_BUSY"; + case RIL_E_SIM_FULL: return "E_SIM_FULL"; + case RIL_E_NETWORK_REJECT: return "E_NETWORK_REJECT"; + case RIL_E_OPERATION_NOT_ALLOWED: return "E_OPERATION_NOT_ALLOWED"; + case RIL_E_EMPTY_RECORD: return "E_EMPTY_RECORD"; + case RIL_E_INVALID_SMS_FORMAT: return "E_INVALID_SMS_FORMAT"; + case RIL_E_ENCODING_ERR: return "E_ENCODING_ERR"; + case RIL_E_INVALID_SMSC_ADDRESS: return "E_INVALID_SMSC_ADDRESS"; + case RIL_E_NO_SUCH_ENTRY: return "E_NO_SUCH_ENTRY"; + case RIL_E_NETWORK_NOT_READY: return "E_NETWORK_NOT_READY"; + case RIL_E_NOT_PROVISIONED: return "E_NOT_PROVISIONED"; + case RIL_E_NO_SUBSCRIPTION: return "E_NO_SUBSCRIPTION"; + case RIL_E_NO_NETWORK_FOUND: return "E_NO_NETWORK_FOUND"; + case RIL_E_DEVICE_IN_USE: return "E_DEVICE_IN_USE"; + case RIL_E_ABORTED: return "E_ABORTED"; + case RIL_E_INVALID_RESPONSE: return "INVALID_RESPONSE"; + case RIL_E_OEM_ERROR_1: return "E_OEM_ERROR_1"; + case RIL_E_OEM_ERROR_2: return "E_OEM_ERROR_2"; + case RIL_E_OEM_ERROR_3: return "E_OEM_ERROR_3"; + case RIL_E_OEM_ERROR_4: return "E_OEM_ERROR_4"; + case RIL_E_OEM_ERROR_5: return "E_OEM_ERROR_5"; + case RIL_E_OEM_ERROR_6: return "E_OEM_ERROR_6"; + case RIL_E_OEM_ERROR_7: return "E_OEM_ERROR_7"; + case RIL_E_OEM_ERROR_8: return "E_OEM_ERROR_8"; + case RIL_E_OEM_ERROR_9: return "E_OEM_ERROR_9"; + case RIL_E_OEM_ERROR_10: return "E_OEM_ERROR_10"; + case RIL_E_OEM_ERROR_11: return "E_OEM_ERROR_11"; + case RIL_E_OEM_ERROR_12: return "E_OEM_ERROR_12"; + case RIL_E_OEM_ERROR_13: return "E_OEM_ERROR_13"; + case RIL_E_OEM_ERROR_14: return "E_OEM_ERROR_14"; + case RIL_E_OEM_ERROR_15: return "E_OEM_ERROR_15"; + case RIL_E_OEM_ERROR_16: return "E_OEM_ERROR_16"; + case RIL_E_OEM_ERROR_17: return "E_OEM_ERROR_17"; + case RIL_E_OEM_ERROR_18: return "E_OEM_ERROR_18"; + case RIL_E_OEM_ERROR_19: return "E_OEM_ERROR_19"; + case RIL_E_OEM_ERROR_20: return "E_OEM_ERROR_20"; + case RIL_E_OEM_ERROR_21: return "E_OEM_ERROR_21"; + case RIL_E_OEM_ERROR_22: return "E_OEM_ERROR_22"; + case RIL_E_OEM_ERROR_23: return "E_OEM_ERROR_23"; + case RIL_E_OEM_ERROR_24: return "E_OEM_ERROR_24"; + case RIL_E_OEM_ERROR_25: return "E_OEM_ERROR_25"; + default: return ""; + } +} + +const char * +radioStateToString(RIL_RadioState s) { + switch(s) { + case RADIO_STATE_OFF: return "RADIO_OFF"; + case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE"; + case RADIO_STATE_ON:return"RADIO_ON"; + default: return ""; + } +} + +const char * +callStateToString(RIL_CallState s) { + switch(s) { + case RIL_CALL_ACTIVE : return "ACTIVE"; + case RIL_CALL_HOLDING: return "HOLDING"; + case RIL_CALL_DIALING: return "DIALING"; + case RIL_CALL_ALERTING: return "ALERTING"; + case RIL_CALL_INCOMING: return "INCOMING"; + case RIL_CALL_WAITING: return "WAITING"; + default: return ""; + } +} + +const char * +requestToString(int request) { +/* + cat libs/telephony/ril_commands.h \ + | egrep "^ *{RIL_" \ + | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' + + + cat libs/telephony/ril_unsol_commands.h \ + | egrep "^ *{RIL_" \ + | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/' + +*/ + switch(request) { + case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS"; + case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN"; + case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK"; + case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2"; + case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2"; + case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN"; + case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2"; + case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION"; + case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS"; + case RIL_REQUEST_DIAL: return "DIAL"; + case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; + case RIL_REQUEST_HANGUP: return "HANGUP"; + case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND"; + case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND"; + case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"; + case RIL_REQUEST_CONFERENCE: return "CONFERENCE"; + case RIL_REQUEST_UDUB: return "UDUB"; + case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE"; + case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH"; + case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE"; + case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE"; + case RIL_REQUEST_OPERATOR: return "OPERATOR"; + case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER"; + case RIL_REQUEST_DTMF: return "DTMF"; + case RIL_REQUEST_SEND_SMS: return "SEND_SMS"; + case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE"; + case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL"; + case RIL_REQUEST_SIM_IO: return "SIM_IO"; + case RIL_REQUEST_SEND_USSD: return "SEND_USSD"; + case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD"; + case RIL_REQUEST_GET_CLIR: return "GET_CLIR"; + case RIL_REQUEST_SET_CLIR: return "SET_CLIR"; + case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS"; + case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD"; + case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING"; + case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING"; + case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE"; + case RIL_REQUEST_GET_IMEI: return "GET_IMEI"; + case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV"; + case RIL_REQUEST_ANSWER: return "ANSWER"; + case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL"; + case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK"; + case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK"; + case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD"; + case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; + case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; + case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; + case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: return "QUERY_AVAILABLE_NETWORKS"; + case RIL_REQUEST_DTMF_START: return "DTMF_START"; + case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; + case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; + case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; + case RIL_REQUEST_SET_MUTE: return "SET_MUTE"; + case RIL_REQUEST_GET_MUTE: return "GET_MUTE"; + case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP"; + case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE"; + case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST"; + case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO"; + case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW"; + case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS"; + case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; + case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; + case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; + case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; + case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; + case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; + case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE"; + case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE"; + case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND"; + case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE"; + case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; + case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER"; + case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE"; + case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE"; + case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS"; + case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES"; + case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "CDMA_SET_SUBSCRIPTION_SOURCE"; + case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "CDMA_SET_ROAMING_PREFERENCE"; + case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "CDMA_QUERY_ROAMING_PREFERENCE"; + case RIL_REQUEST_SET_TTY_MODE: return "SET_TTY_MODE"; + case RIL_REQUEST_QUERY_TTY_MODE: return "QUERY_TTY_MODE"; + case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE"; + case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE"; + case RIL_REQUEST_CDMA_FLASH: return "CDMA_FLASH"; + case RIL_REQUEST_CDMA_BURST_DTMF: return "CDMA_BURST_DTMF"; + case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "CDMA_VALIDATE_AND_WRITE_AKEY"; + case RIL_REQUEST_CDMA_SEND_SMS: return "CDMA_SEND_SMS"; + case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "CDMA_SMS_ACKNOWLEDGE"; + case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG: return "GSM_GET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG: return "GSM_SET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION: return "GSM_SMS_BROADCAST_ACTIVATION"; + case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG: return "CDMA_GET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG: return "CDMA_SET_BROADCAST_SMS_CONFIG"; + case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION: return "CDMA_SMS_BROADCAST_ACTIVATION"; + case RIL_REQUEST_CDMA_SUBSCRIPTION: return "CDMA_SUBSCRIPTION"; + case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM"; + case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM"; + case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY"; + case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE"; + case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS"; + case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS"; + case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS"; + case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING"; + case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE"; + case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION"; + case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU"; + case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "STK_SEND_ENVELOPE_WITH_STATUS"; + case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH"; + case RIL_REQUEST_GET_CELL_INFO_LIST: return "GET_CELL_INFO_LIST"; + case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return "SET_UNSOL_CELL_INFO_LIST_RATE"; + case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "SET_INITIAL_ATTACH_APN"; + case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE"; + case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS"; + case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC"; + case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL"; + case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL"; + case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL"; + case RIL_REQUEST_NV_READ_ITEM: return "NV_READ_ITEM"; + case RIL_REQUEST_NV_WRITE_ITEM: return "NV_WRITE_ITEM"; + case RIL_REQUEST_NV_WRITE_CDMA_PRL: return "NV_WRITE_CDMA_PRL"; + case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG"; + case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION"; + case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA"; + case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG"; + case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION"; + case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO"; + case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE"; + case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE"; + case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN"; + case RIL_REQUEST_GET_RADIO_CAPABILITY: return "GET_RADIO_CAPABILITY"; + case RIL_REQUEST_SET_RADIO_CAPABILITY: return "SET_RADIO_CAPABILITY"; + case RIL_REQUEST_START_LCE: return "START_LCE"; + case RIL_REQUEST_STOP_LCE: return "STOP_LCE"; + case RIL_REQUEST_PULL_LCEDATA: return "PULL_LCEDATA"; + case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO"; + case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS"; + case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS"; + case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION: return "SET_CARRIER_INFO_IMSI_ENCRYPTION"; + case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT"; + case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; + case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; + case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; + case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS"; + case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; + case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; + case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; + case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; + case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; + case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; + case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED"; + case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; + case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; + case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; + case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; + case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; + case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; + case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; + case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; + case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED"; + case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS"; + case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS"; + case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL"; + case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED"; + case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE"; + case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING"; + case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS"; + case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; + case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; + case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE"; + case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; + case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED"; + case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED"; + case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE"; + case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; + case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; + case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; + case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED"; + case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED"; + case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY"; + case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "UNSOL_HARDWARE_CONFIG_CHANGED"; + case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED"; + case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY"; + case RIL_UNSOL_MODEM_RESTART: return "UNSOL_MODEM_RESTART"; + case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION: return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION"; + case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS"; + case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY"; + case RIL_UNSOL_LCEDATA_RECV: return "UNSOL_LCEDATA_RECV"; + case RIL_UNSOL_PCO_DATA: return "UNSOL_PCO_DATA"; + default: return ""; + } +} + +const char * +rilSocketIdToString(RIL_SOCKET_ID socket_id) +{ + switch(socket_id) { + case RIL_SOCKET_1: + return "RIL_SOCKET_1"; +#if (SIM_COUNT >= 2) + case RIL_SOCKET_2: + return "RIL_SOCKET_2"; +#endif +#if (SIM_COUNT >= 3) + case RIL_SOCKET_3: + return "RIL_SOCKET_3"; +#endif +#if (SIM_COUNT >= 4) + case RIL_SOCKET_4: + return "RIL_SOCKET_4"; +#endif + default: + return "not a valid RIL"; + } +} + +} /* namespace android */ diff --git a/libril/rilSocketQueue.h b/libril/rilSocketQueue.h new file mode 100644 index 0000000..eaa5155 --- /dev/null +++ b/libril/rilSocketQueue.h @@ -0,0 +1,167 @@ +/* +* Copyright (C) 2014 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. +*/ + +#include "pb_decode.h" +#include +#include +#include + +using namespace std; + +/** + * Template queue class to handling requests for a rild socket. + *

+ * This class performs the following functions : + *

    + *
  • Enqueue. + *
  • Dequeue. + *
  • Check and dequeue. + *
+ */ + +template +class Ril_queue { + + /** + * Mutex attribute used in queue mutex initialization. + */ + pthread_mutexattr_t attr; + + /** + * Queue mutex variable for synchronized queue access. + */ + pthread_mutex_t mutex_instance; + + /** + * Condition to be waited on for dequeuing. + */ + pthread_cond_t cond; + + /** + * Front of the queue. + */ + T *front; + + public: + + /** + * Remove the first element of the queue. + * + * @return first element of the queue. + */ + T* dequeue(void); + + /** + * Add a request to the front of the queue. + * + * @param Request to be added. + */ + void enqueue(T* request); + + /** + * Check if the queue is empty. + */ + int empty(void); + + /** + * Check and remove an element with a particular message id and token. + * + * @param Request message id. + * @param Request token. + */ + int checkAndDequeue( MsgId id, int token); + + /** + * Queue constructor. + */ + Ril_queue(void); +}; + +template +Ril_queue::Ril_queue(void) { + pthread_mutexattr_init(&attr); + pthread_mutex_init(&mutex_instance, &attr); + cond = PTHREAD_COND_INITIALIZER; + front = NULL; +} + +template +T* Ril_queue::dequeue(void) { + T* temp = NULL; + + pthread_mutex_lock(&mutex_instance); + while(empty()) { + pthread_cond_wait(&cond, &mutex_instance); + } + temp = this->front; + if(NULL != this->front->p_next) { + this->front = this->front->p_next; + } else { + this->front = NULL; + } + pthread_mutex_unlock(&mutex_instance); + + return temp; +} + +template +void Ril_queue::enqueue(T* request) { + + pthread_mutex_lock(&mutex_instance); + + if(NULL == this->front) { + this->front = request; + request->p_next = NULL; + } else { + request->p_next = this->front; + this->front = request; + } + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&mutex_instance); +} + +template +int Ril_queue::checkAndDequeue(MsgId id, int token) { + int ret = 0; + T* temp; + + pthread_mutex_lock(&mutex_instance); + + for(T **ppCur = &(this->front); *ppCur != NULL; ppCur = &((*ppCur)->p_next)) { + if (token == (*ppCur)->token && id == (*ppCur)->curr->id) { + ret = 1; + temp = *ppCur; + *ppCur = (*ppCur)->p_next; + free(temp); + break; + } + } + + pthread_mutex_unlock(&mutex_instance); + + return ret; +} + + +template +int Ril_queue::empty(void) { + + if(this->front == NULL) { + return 1; + } else { + return 0; + } +} diff --git a/libril/ril_commands.h b/libril/ril_commands.h new file mode 100644 index 0000000..94c2a26 --- /dev/null +++ b/libril/ril_commands.h @@ -0,0 +1,162 @@ +/* //device/libs/telephony/ril_commands.h +** +** Copyright 2006, 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. +*/ + {0, NULL}, //none + {RIL_REQUEST_GET_SIM_STATUS, radio::getIccCardStatusResponse}, + {RIL_REQUEST_ENTER_SIM_PIN, radio::supplyIccPinForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PUK, radio::supplyIccPukForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PIN2, radio::supplyIccPin2ForAppResponse}, + {RIL_REQUEST_ENTER_SIM_PUK2, radio::supplyIccPuk2ForAppResponse}, + {RIL_REQUEST_CHANGE_SIM_PIN, radio::changeIccPinForAppResponse}, + {RIL_REQUEST_CHANGE_SIM_PIN2, radio::changeIccPin2ForAppResponse}, + {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, radio::supplyNetworkDepersonalizationResponse}, + {RIL_REQUEST_GET_CURRENT_CALLS, radio::getCurrentCallsResponse}, + {RIL_REQUEST_DIAL, radio::dialResponse}, + {RIL_REQUEST_GET_IMSI, radio::getIMSIForAppResponse}, + {RIL_REQUEST_HANGUP, radio::hangupConnectionResponse}, + {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, radio::hangupWaitingOrBackgroundResponse}, + {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, radio::hangupForegroundResumeBackgroundResponse}, + {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, radio::switchWaitingOrHoldingAndActiveResponse}, + {RIL_REQUEST_CONFERENCE, radio::conferenceResponse}, + {RIL_REQUEST_UDUB, radio::rejectCallResponse}, + {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, radio::getLastCallFailCauseResponse}, + {RIL_REQUEST_SIGNAL_STRENGTH, radio::getSignalStrengthResponse}, + {RIL_REQUEST_VOICE_REGISTRATION_STATE, radio::getVoiceRegistrationStateResponse}, + {RIL_REQUEST_DATA_REGISTRATION_STATE, radio::getDataRegistrationStateResponse}, + {RIL_REQUEST_OPERATOR, radio::getOperatorResponse}, + {RIL_REQUEST_RADIO_POWER, radio::setRadioPowerResponse}, + {RIL_REQUEST_DTMF, radio::sendDtmfResponse}, + {RIL_REQUEST_SEND_SMS, radio::sendSmsResponse}, + {RIL_REQUEST_SEND_SMS_EXPECT_MORE, radio::sendSMSExpectMoreResponse}, + {RIL_REQUEST_SETUP_DATA_CALL, radio::setupDataCallResponse}, + {RIL_REQUEST_SIM_IO, radio::iccIOForAppResponse}, + {RIL_REQUEST_SEND_USSD, radio::sendUssdResponse}, + {RIL_REQUEST_CANCEL_USSD, radio::cancelPendingUssdResponse}, + {RIL_REQUEST_GET_CLIR, radio::getClirResponse}, + {RIL_REQUEST_SET_CLIR, radio::setClirResponse}, + {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, radio::getCallForwardStatusResponse}, + {RIL_REQUEST_SET_CALL_FORWARD, radio::setCallForwardResponse}, + {RIL_REQUEST_QUERY_CALL_WAITING, radio::getCallWaitingResponse}, + {RIL_REQUEST_SET_CALL_WAITING, radio::setCallWaitingResponse}, + {RIL_REQUEST_SMS_ACKNOWLEDGE, radio::acknowledgeLastIncomingGsmSmsResponse}, + {RIL_REQUEST_GET_IMEI, NULL}, + {RIL_REQUEST_GET_IMEISV, NULL}, + {RIL_REQUEST_ANSWER, radio::acceptCallResponse}, + {RIL_REQUEST_DEACTIVATE_DATA_CALL, radio::deactivateDataCallResponse}, + {RIL_REQUEST_QUERY_FACILITY_LOCK, radio::getFacilityLockForAppResponse}, + {RIL_REQUEST_SET_FACILITY_LOCK, radio::setFacilityLockForAppResponse}, + {RIL_REQUEST_CHANGE_BARRING_PASSWORD, radio::setBarringPasswordResponse}, + {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, radio::getNetworkSelectionModeResponse}, + {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, radio::setNetworkSelectionModeAutomaticResponse}, + {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, radio::setNetworkSelectionModeManualResponse}, + {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , radio::getAvailableNetworksResponse}, + {RIL_REQUEST_DTMF_START, radio::startDtmfResponse}, + {RIL_REQUEST_DTMF_STOP, radio::stopDtmfResponse}, + {RIL_REQUEST_BASEBAND_VERSION, radio::getBasebandVersionResponse}, + {RIL_REQUEST_SEPARATE_CONNECTION, radio::separateConnectionResponse}, + {RIL_REQUEST_SET_MUTE, radio::setMuteResponse}, + {RIL_REQUEST_GET_MUTE, radio::getMuteResponse}, + {RIL_REQUEST_QUERY_CLIP, radio::getClipResponse}, + {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, NULL}, + {RIL_REQUEST_DATA_CALL_LIST, radio::getDataCallListResponse}, + {RIL_REQUEST_RESET_RADIO, NULL}, + {RIL_REQUEST_OEM_HOOK_RAW, radio::sendRequestRawResponse}, + {RIL_REQUEST_OEM_HOOK_STRINGS, radio::sendRequestStringsResponse}, + {RIL_REQUEST_SCREEN_STATE, radio::sendDeviceStateResponse}, // Note the response function is different. + {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, radio::setSuppServiceNotificationsResponse}, + {RIL_REQUEST_WRITE_SMS_TO_SIM, radio::writeSmsToSimResponse}, + {RIL_REQUEST_DELETE_SMS_ON_SIM, radio::deleteSmsOnSimResponse}, + {RIL_REQUEST_SET_BAND_MODE, radio::setBandModeResponse}, + {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, radio::getAvailableBandModesResponse}, + {RIL_REQUEST_STK_GET_PROFILE, NULL}, + {RIL_REQUEST_STK_SET_PROFILE, NULL}, + {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, radio::sendEnvelopeResponse}, + {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, radio::sendTerminalResponseToSimResponse}, + {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, radio::handleStkCallSetupRequestFromSimResponse}, + {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, radio::explicitCallTransferResponse}, + {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, radio::setPreferredNetworkTypeResponse}, + {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, radio::getPreferredNetworkTypeResponse}, + {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, radio::getNeighboringCidsResponse}, + {RIL_REQUEST_SET_LOCATION_UPDATES, radio::setLocationUpdatesResponse}, + {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, radio::setCdmaSubscriptionSourceResponse}, + {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, radio::setCdmaRoamingPreferenceResponse}, + {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, radio::getCdmaRoamingPreferenceResponse}, + {RIL_REQUEST_SET_TTY_MODE, radio::setTTYModeResponse}, + {RIL_REQUEST_QUERY_TTY_MODE, radio::getTTYModeResponse}, + {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, radio::setPreferredVoicePrivacyResponse}, + {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, radio::getPreferredVoicePrivacyResponse}, + {RIL_REQUEST_CDMA_FLASH, radio::sendCDMAFeatureCodeResponse}, + {RIL_REQUEST_CDMA_BURST_DTMF, radio::sendBurstDtmfResponse}, + {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, NULL}, + {RIL_REQUEST_CDMA_SEND_SMS, radio::sendCdmaSmsResponse}, + {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, radio::acknowledgeLastIncomingCdmaSmsResponse}, + {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, radio::getGsmBroadcastConfigResponse}, + {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, radio::setGsmBroadcastConfigResponse}, + {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, radio::setGsmBroadcastActivationResponse}, + {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, radio::getCdmaBroadcastConfigResponse}, + {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, radio::setCdmaBroadcastConfigResponse}, + {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, radio::setCdmaBroadcastActivationResponse}, + {RIL_REQUEST_CDMA_SUBSCRIPTION, radio::getCDMASubscriptionResponse}, + {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, radio::writeSmsToRuimResponse}, + {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, radio::deleteSmsOnRuimResponse}, + {RIL_REQUEST_DEVICE_IDENTITY, radio::getDeviceIdentityResponse}, + {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, radio::exitEmergencyCallbackModeResponse}, + {RIL_REQUEST_GET_SMSC_ADDRESS, radio::getSmscAddressResponse}, + {RIL_REQUEST_SET_SMSC_ADDRESS, radio::setSmscAddressResponse}, + {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, radio::reportSmsMemoryStatusResponse}, + {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, radio::reportStkServiceIsRunningResponse}, + {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, radio::getCdmaSubscriptionSourceResponse}, + {RIL_REQUEST_ISIM_AUTHENTICATION, radio::requestIsimAuthenticationResponse}, + {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, radio::acknowledgeIncomingGsmSmsWithPduResponse}, + {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, radio::sendEnvelopeWithStatusResponse}, + {RIL_REQUEST_VOICE_RADIO_TECH, radio::getVoiceRadioTechnologyResponse}, + {RIL_REQUEST_GET_CELL_INFO_LIST, radio::getCellInfoListResponse}, + {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, radio::setCellInfoListRateResponse}, + {RIL_REQUEST_SET_INITIAL_ATTACH_APN, radio::setInitialAttachApnResponse}, + {RIL_REQUEST_IMS_REGISTRATION_STATE, radio::getImsRegistrationStateResponse}, + {RIL_REQUEST_IMS_SEND_SMS, radio::sendImsSmsResponse}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, radio::iccTransmitApduBasicChannelResponse}, + {RIL_REQUEST_SIM_OPEN_CHANNEL, radio::iccOpenLogicalChannelResponse}, + {RIL_REQUEST_SIM_CLOSE_CHANNEL, radio::iccCloseLogicalChannelResponse}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, radio::iccTransmitApduLogicalChannelResponse}, + {RIL_REQUEST_NV_READ_ITEM, radio::nvReadItemResponse}, + {RIL_REQUEST_NV_WRITE_ITEM, radio::nvWriteItemResponse}, + {RIL_REQUEST_NV_WRITE_CDMA_PRL, radio::nvWriteCdmaPrlResponse}, + {RIL_REQUEST_NV_RESET_CONFIG, radio::nvResetConfigResponse}, + {RIL_REQUEST_SET_UICC_SUBSCRIPTION, radio::setUiccSubscriptionResponse}, + {RIL_REQUEST_ALLOW_DATA, radio::setDataAllowedResponse}, + {RIL_REQUEST_GET_HARDWARE_CONFIG, radio::getHardwareConfigResponse}, + {RIL_REQUEST_SIM_AUTHENTICATION, radio::requestIccSimAuthenticationResponse}, + {RIL_REQUEST_GET_DC_RT_INFO, NULL}, + {RIL_REQUEST_SET_DC_RT_INFO_RATE, NULL}, + {RIL_REQUEST_SET_DATA_PROFILE, radio::setDataProfileResponse}, + {RIL_REQUEST_SHUTDOWN, radio::requestShutdownResponse}, + {RIL_REQUEST_GET_RADIO_CAPABILITY, radio::getRadioCapabilityResponse}, + {RIL_REQUEST_SET_RADIO_CAPABILITY, radio::setRadioCapabilityResponse}, + {RIL_REQUEST_START_LCE, radio::startLceServiceResponse}, + {RIL_REQUEST_STOP_LCE, radio::stopLceServiceResponse}, + {RIL_REQUEST_PULL_LCEDATA, radio::pullLceDataResponse}, + {RIL_REQUEST_GET_ACTIVITY_INFO, radio::getModemActivityInfoResponse}, + {RIL_REQUEST_SET_CARRIER_RESTRICTIONS, radio::setAllowedCarriersResponse}, + {RIL_REQUEST_GET_CARRIER_RESTRICTIONS, radio::getAllowedCarriersResponse}, + {RIL_REQUEST_SEND_DEVICE_STATE, radio::sendDeviceStateResponse}, + {RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, radio::setIndicationFilterResponse}, + {RIL_REQUEST_SET_SIM_CARD_POWER, radio::setSimCardPowerResponse}, + {RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, radio::setCarrierInfoForImsiEncryptionResponse}, + {RIL_REQUEST_START_NETWORK_SCAN, radio::startNetworkScanResponse}, + {RIL_REQUEST_STOP_NETWORK_SCAN, radio::stopNetworkScanResponse}, + {RIL_REQUEST_START_KEEPALIVE, radio::startKeepaliveResponse}, + {RIL_REQUEST_STOP_KEEPALIVE, radio::stopKeepaliveResponse}, diff --git a/libril/ril_event.cpp b/libril/ril_event.cpp new file mode 100644 index 0000000..84b8b72 --- /dev/null +++ b/libril/ril_event.cpp @@ -0,0 +1,384 @@ +/* //device/libs/telephony/ril_event.cpp +** +** Copyright 2008, 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +static pthread_mutex_t listMutex; +#define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex) +#define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex) +#define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL) +#define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex) + +#ifndef timeradd +#define timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#endif + +#ifndef timercmp +#define timercmp(a, b, op) \ + ((a)->tv_sec == (b)->tv_sec \ + ? (a)->tv_usec op (b)->tv_usec \ + : (a)->tv_sec op (b)->tv_sec) +#endif + +#ifndef timersub +#define timersub(a, b, res) \ + do { \ + (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((res)->tv_usec < 0) { \ + (res)->tv_usec += 1000000; \ + (res)->tv_sec -= 1; \ + } \ + } while(0); +#endif + +static fd_set readFds; +static int nfds = 0; + +static struct ril_event * watch_table[MAX_FD_EVENTS]; +static struct ril_event timer_list; +static struct ril_event pending_list; + +#define DEBUG 0 + +#if DEBUG +#define dlog(x...) RLOGD( x ) +static void dump_event(struct ril_event * ev) +{ + dlog("~~~~ Event %x ~~~~", (unsigned int)ev); + dlog(" next = %x", (unsigned int)ev->next); + dlog(" prev = %x", (unsigned int)ev->prev); + dlog(" fd = %d", ev->fd); + dlog(" pers = %d", ev->persist); + dlog(" timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec); + dlog(" func = %x", (unsigned int)ev->func); + dlog(" param = %x", (unsigned int)ev->param); + dlog("~~~~~~~~~~~~~~~~~~"); +} +#else +#define dlog(x...) do {} while(0) +#define dump_event(x) do {} while(0) +#endif + +static void getNow(struct timeval * tv) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec/1000; +} + +static void init_list(struct ril_event * list) +{ + memset(list, 0, sizeof(struct ril_event)); + list->next = list; + list->prev = list; + list->fd = -1; +} + +static void addToList(struct ril_event * ev, struct ril_event * list) +{ + ev->next = list; + ev->prev = list->prev; + ev->prev->next = ev; + list->prev = ev; + dump_event(ev); +} + +static void removeFromList(struct ril_event * ev) +{ + dlog("~~~~ +removeFromList ~~~~"); + dump_event(ev); + + ev->next->prev = ev->prev; + ev->prev->next = ev->next; + ev->next = NULL; + ev->prev = NULL; + dlog("~~~~ -removeFromList ~~~~"); +} + + +static void removeWatch(struct ril_event * ev, int index) +{ + dlog("~~~~ +removeWatch ~~~~"); + watch_table[index] = NULL; + ev->index = -1; + + FD_CLR(ev->fd, &readFds); + + if (ev->fd+1 == nfds) { + int n = 0; + + for (int i = 0; i < MAX_FD_EVENTS; i++) { + struct ril_event * rev = watch_table[i]; + + if ((rev != NULL) && (rev->fd > n)) { + n = rev->fd; + } + } + nfds = n + 1; + dlog("~~~~ nfds = %d ~~~~", nfds); + } + dlog("~~~~ -removeWatch ~~~~"); +} + +static void processTimeouts() +{ + dlog("~~~~ +processTimeouts ~~~~"); + MUTEX_ACQUIRE(); + struct timeval now; + struct ril_event * tev = timer_list.next; + struct ril_event * next; + + getNow(&now); + // walk list, see if now >= ev->timeout for any events + + dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); + while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) { + // Timer expired + dlog("~~~~ firing timer ~~~~"); + next = tev->next; + removeFromList(tev); + addToList(tev, &pending_list); + tev = next; + } + MUTEX_RELEASE(); + dlog("~~~~ -processTimeouts ~~~~"); +} + +static void processReadReadies(fd_set * rfds, int n) +{ + dlog("~~~~ +processReadReadies (%d) ~~~~", n); + MUTEX_ACQUIRE(); + + for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) { + struct ril_event * rev = watch_table[i]; + if (rev != NULL && FD_ISSET(rev->fd, rfds)) { + addToList(rev, &pending_list); + if (rev->persist == false) { + removeWatch(rev, i); + } + n--; + } + } + + MUTEX_RELEASE(); + dlog("~~~~ -processReadReadies (%d) ~~~~", n); +} + +static void firePending() +{ + dlog("~~~~ +firePending ~~~~"); + struct ril_event * ev = pending_list.next; + while (ev != &pending_list) { + struct ril_event * next = ev->next; + removeFromList(ev); + ev->func(ev->fd, 0, ev->param); + ev = next; + } + dlog("~~~~ -firePending ~~~~"); +} + +static int calcNextTimeout(struct timeval * tv) +{ + struct ril_event * tev = timer_list.next; + struct timeval now; + + getNow(&now); + + // Sorted list, so calc based on first node + if (tev == &timer_list) { + // no pending timers + return -1; + } + + dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec); + dlog("~~~~ next = %ds + %dus ~~~~", + (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec); + if (timercmp(&tev->timeout, &now, >)) { + timersub(&tev->timeout, &now, tv); + } else { + // timer already expired. + tv->tv_sec = tv->tv_usec = 0; + } + return 0; +} + +// Initialize internal data structs +void ril_event_init() +{ + MUTEX_INIT(); + + FD_ZERO(&readFds); + init_list(&timer_list); + init_list(&pending_list); + memset(watch_table, 0, sizeof(watch_table)); +} + +// Initialize an event +void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param) +{ + dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev); + memset(ev, 0, sizeof(struct ril_event)); + ev->fd = fd; + ev->index = -1; + ev->persist = persist; + ev->func = func; + ev->param = param; + fcntl(fd, F_SETFL, O_NONBLOCK); +} + +// Add event to watch list +void ril_event_add(struct ril_event * ev) +{ + dlog("~~~~ +ril_event_add ~~~~"); + MUTEX_ACQUIRE(); + for (int i = 0; i < MAX_FD_EVENTS; i++) { + if (watch_table[i] == NULL) { + watch_table[i] = ev; + ev->index = i; + dlog("~~~~ added at %d ~~~~", i); + dump_event(ev); + FD_SET(ev->fd, &readFds); + if (ev->fd >= nfds) nfds = ev->fd+1; + dlog("~~~~ nfds = %d ~~~~", nfds); + break; + } + } + MUTEX_RELEASE(); + dlog("~~~~ -ril_event_add ~~~~"); +} + +// Add timer event +void ril_timer_add(struct ril_event * ev, struct timeval * tv) +{ + dlog("~~~~ +ril_timer_add ~~~~"); + MUTEX_ACQUIRE(); + + struct ril_event * list; + if (tv != NULL) { + // add to timer list + list = timer_list.next; + ev->fd = -1; // make sure fd is invalid + + struct timeval now; + getNow(&now); + timeradd(&now, tv, &ev->timeout); + + // keep list sorted + while (timercmp(&list->timeout, &ev->timeout, < ) + && (list != &timer_list)) { + list = list->next; + } + // list now points to the first event older than ev + addToList(ev, list); + } + + MUTEX_RELEASE(); + dlog("~~~~ -ril_timer_add ~~~~"); +} + +// Remove event from watch or timer list +void ril_event_del(struct ril_event * ev) +{ + dlog("~~~~ +ril_event_del ~~~~"); + MUTEX_ACQUIRE(); + + if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) { + MUTEX_RELEASE(); + return; + } + + removeWatch(ev, ev->index); + + MUTEX_RELEASE(); + dlog("~~~~ -ril_event_del ~~~~"); +} + +#if DEBUG +static void printReadies(fd_set * rfds) +{ + for (int i = 0; (i < MAX_FD_EVENTS); i++) { + struct ril_event * rev = watch_table[i]; + if (rev != NULL && FD_ISSET(rev->fd, rfds)) { + dlog("DON: fd=%d is ready", rev->fd); + } + } +} +#else +#define printReadies(rfds) do {} while(0) +#endif + +void ril_event_loop() +{ + int n; + fd_set rfds; + struct timeval tv; + struct timeval * ptv; + + + for (;;) { + + // make local copy of read fd_set + memcpy(&rfds, &readFds, sizeof(fd_set)); + if (-1 == calcNextTimeout(&tv)) { + // no pending timers; block indefinitely + dlog("~~~~ no timers; blocking indefinitely ~~~~"); + ptv = NULL; + } else { + dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec); + ptv = &tv; + } + printReadies(&rfds); + n = select(nfds, &rfds, NULL, NULL, ptv); + printReadies(&rfds); + dlog("~~~~ %d events fired ~~~~", n); + if (n < 0) { + if (errno == EINTR) continue; + + RLOGE("ril_event: select error (%d)", errno); + // bail? + return; + } + + // Check for timeouts + processTimeouts(); + // Check for read-ready + processReadReadies(&rfds, n); + // Fire away + firePending(); + } +} diff --git a/libril/ril_event.h b/libril/ril_event.h new file mode 100644 index 0000000..7ba231b --- /dev/null +++ b/libril/ril_event.h @@ -0,0 +1,52 @@ +/* //device/libs/telephony/ril_event.h +** +** Copyright 2008, 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. +*/ + +// Max number of fd's we watch at any one time. Increase if necessary. +#define MAX_FD_EVENTS 8 + +typedef void (*ril_event_cb)(int fd, short events, void *userdata); + +struct ril_event { + struct ril_event *next; + struct ril_event *prev; + + int fd; + int index; + bool persist; + struct timeval timeout; + ril_event_cb func; + void *param; +}; + +// Initialize internal data structs +void ril_event_init(); + +// Initialize an event +void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param); + +// Add event to watch list +void ril_event_add(struct ril_event * ev); + +// Add timer event +void ril_timer_add(struct ril_event * ev, struct timeval * tv); + +// Remove event from watch list +void ril_event_del(struct ril_event * ev); + +// Event loop +void ril_event_loop(); + diff --git a/libril/ril_internal.h b/libril/ril_internal.h new file mode 100644 index 0000000..350791b --- /dev/null +++ b/libril/ril_internal.h @@ -0,0 +1,98 @@ +/* + * 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. + */ + +#ifndef ANDROID_RIL_INTERNAL_H +#define ANDROID_RIL_INTERNAL_H + +namespace android { + +#define RIL_SERVICE_NAME_BASE "slot" +#define RIL1_SERVICE_NAME "slot1" +#define RIL2_SERVICE_NAME "slot2" +#define RIL3_SERVICE_NAME "slot3" +#define RIL4_SERVICE_NAME "slot4" + +/* Constants for response types */ +#define RESPONSE_SOLICITED 0 +#define RESPONSE_UNSOLICITED 1 +#define RESPONSE_SOLICITED_ACK 2 +#define RESPONSE_SOLICITED_ACK_EXP 3 +#define RESPONSE_UNSOLICITED_ACK_EXP 4 + +// Enable verbose logging +#define VDBG 0 + +#define MIN(a,b) ((a)<(b) ? (a) : (b)) + +// Enable RILC log +#define RILC_LOG 0 + +#if RILC_LOG + #define startRequest sprintf(printBuf, "(") + #define closeRequest sprintf(printBuf, "%s)", printBuf) + #define printRequest(token, req) \ + RLOGD("[%04d]> %s %s", token, requestToString(req), printBuf) + + #define startResponse sprintf(printBuf, "%s {", printBuf) + #define closeResponse sprintf(printBuf, "%s}", printBuf) + #define printResponse RLOGD("%s", printBuf) + + #define clearPrintBuf printBuf[0] = 0 + #define removeLastChar printBuf[strlen(printBuf)-1] = 0 + #define appendPrintBuf(x...) snprintf(printBuf, PRINTBUF_SIZE, x) +#else + #define startRequest + #define closeRequest + #define printRequest(token, req) + #define startResponse + #define closeResponse + #define printResponse + #define clearPrintBuf + #define removeLastChar + #define appendPrintBuf(x...) +#endif + +typedef struct CommandInfo CommandInfo; + +extern "C" const char * requestToString(int request); + +typedef struct RequestInfo { + int32_t token; //this is not RIL_Token + CommandInfo *pCI; + struct RequestInfo *p_next; + char cancelled; + char local; // responses to local commands do not go back to command process + RIL_SOCKET_ID socket_id; + int wasAckSent; // Indicates whether an ack was sent earlier +} RequestInfo; + +typedef struct CommandInfo { + int requestNumber; + int(*responseFunction) (int slotId, int responseType, int token, + RIL_Errno e, void *response, size_t responselen); +} CommandInfo; + +RequestInfo * addRequestToList(int serial, int slotId, int request); + +char * RIL_getServiceName(); + +void releaseWakeLock(); + +void onNewCommandConnect(RIL_SOCKET_ID socket_id); + +} // namespace android + +#endif //ANDROID_RIL_INTERNAL_H diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp new file mode 100644 index 0000000..6ada423 --- /dev/null +++ b/libril/ril_service.cpp @@ -0,0 +1,8668 @@ +/* + * 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 +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define INVALID_HEX_CHAR 16 + +using namespace android::hardware::radio; +using namespace android::hardware::radio::V1_0; +using namespace android::hardware::radio::deprecated::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; +struct OemHookImpl; + +#if (SIM_COUNT >= 2) +sp radioService[SIM_COUNT]; +sp oemHookService[SIM_COUNT]; +// counter used for synchronization. It is incremented every time response callbacks are updated. +volatile int32_t mCounterRadio[SIM_COUNT]; +volatile int32_t mCounterOemHook[SIM_COUNT]; +#else +sp radioService[1]; +sp oemHookService[1]; +// counter used for synchronization. It is incremented every time response callbacks are updated. +volatile int32_t mCounterRadio[1]; +volatile int32_t mCounterOemHook[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& 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_v6 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallToHal(RIL_Data_Call_Response_v9 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, + SetupDataCallResult& dcResult); + +void convertRilDataCallListToHal(void *response, size_t responseLen, + hidl_vec& dcResultList); + +void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec& records); + +struct RadioImpl : public V1_1::IRadio { + int32_t mSlotId; + sp mRadioResponse; + sp mRadioIndication; + sp mRadioResponseV1_1; + sp mRadioIndicationV1_1; + + Return setResponseFunctions( + const ::android::sp& radioResponse, + const ::android::sp& radioIndication); + + Return getIccCardStatus(int32_t serial); + + Return supplyIccPinForApp(int32_t serial, const hidl_string& pin, + const hidl_string& aid); + + Return supplyIccPukForApp(int32_t serial, const hidl_string& puk, + const hidl_string& pin, const hidl_string& aid); + + Return supplyIccPin2ForApp(int32_t serial, + const hidl_string& pin2, + const hidl_string& aid); + + Return supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2, + const hidl_string& pin2, const hidl_string& aid); + + Return changeIccPinForApp(int32_t serial, const hidl_string& oldPin, + const hidl_string& newPin, const hidl_string& aid); + + Return changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2, + const hidl_string& newPin2, const hidl_string& aid); + + Return supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin); + + Return getCurrentCalls(int32_t serial); + + Return dial(int32_t serial, const Dial& dialInfo); + + Return getImsiForApp(int32_t serial, + const ::android::hardware::hidl_string& aid); + + Return hangup(int32_t serial, int32_t gsmIndex); + + Return hangupWaitingOrBackground(int32_t serial); + + Return hangupForegroundResumeBackground(int32_t serial); + + Return switchWaitingOrHoldingAndActive(int32_t serial); + + Return conference(int32_t serial); + + Return rejectCall(int32_t serial); + + Return getLastCallFailCause(int32_t serial); + + Return getSignalStrength(int32_t serial); + + Return getVoiceRegistrationState(int32_t serial); + + Return getDataRegistrationState(int32_t serial); + + Return getOperator(int32_t serial); + + Return setRadioPower(int32_t serial, bool on); + + Return sendDtmf(int32_t serial, + const ::android::hardware::hidl_string& s); + + Return sendSms(int32_t serial, const GsmSmsMessage& message); + + Return sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message); + + Return setupDataCall(int32_t serial, + RadioTechnology radioTechnology, + const DataProfileInfo& profileInfo, + bool modemCognitive, + bool roamingAllowed, + bool isRoaming); + + Return iccIOForApp(int32_t serial, + const IccIo& iccIo); + + Return sendUssd(int32_t serial, + const ::android::hardware::hidl_string& ussd); + + Return cancelPendingUssd(int32_t serial); + + Return getClir(int32_t serial); + + Return setClir(int32_t serial, int32_t status); + + Return getCallForwardStatus(int32_t serial, + const CallForwardInfo& callInfo); + + Return setCallForward(int32_t serial, + const CallForwardInfo& callInfo); + + Return getCallWaiting(int32_t serial, int32_t serviceClass); + + Return setCallWaiting(int32_t serial, bool enable, int32_t serviceClass); + + Return acknowledgeLastIncomingGsmSms(int32_t serial, + bool success, SmsAcknowledgeFailCause cause); + + Return acceptCall(int32_t serial); + + Return deactivateDataCall(int32_t serial, + int32_t cid, bool reasonRadioShutDown); + + Return 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 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 setBarringPassword(int32_t serial, + const ::android::hardware::hidl_string& facility, + const ::android::hardware::hidl_string& oldPassword, + const ::android::hardware::hidl_string& newPassword); + + Return getNetworkSelectionMode(int32_t serial); + + Return setNetworkSelectionModeAutomatic(int32_t serial); + + Return setNetworkSelectionModeManual(int32_t serial, + const ::android::hardware::hidl_string& operatorNumeric); + + Return getAvailableNetworks(int32_t serial); + + Return startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request); + + Return stopNetworkScan(int32_t serial); + + Return startDtmf(int32_t serial, + const ::android::hardware::hidl_string& s); + + Return stopDtmf(int32_t serial); + + Return getBasebandVersion(int32_t serial); + + Return separateConnection(int32_t serial, int32_t gsmIndex); + + Return setMute(int32_t serial, bool enable); + + Return getMute(int32_t serial); + + Return getClip(int32_t serial); + + Return getDataCallList(int32_t serial); + + Return setSuppServiceNotifications(int32_t serial, bool enable); + + Return writeSmsToSim(int32_t serial, + const SmsWriteArgs& smsWriteArgs); + + Return deleteSmsOnSim(int32_t serial, int32_t index); + + Return setBandMode(int32_t serial, RadioBandMode mode); + + Return getAvailableBandModes(int32_t serial); + + Return sendEnvelope(int32_t serial, + const ::android::hardware::hidl_string& command); + + Return sendTerminalResponseToSim(int32_t serial, + const ::android::hardware::hidl_string& commandResponse); + + Return handleStkCallSetupRequestFromSim(int32_t serial, bool accept); + + Return explicitCallTransfer(int32_t serial); + + Return setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType); + + Return getPreferredNetworkType(int32_t serial); + + Return getNeighboringCids(int32_t serial); + + Return setLocationUpdates(int32_t serial, bool enable); + + Return setCdmaSubscriptionSource(int32_t serial, + CdmaSubscriptionSource cdmaSub); + + Return setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type); + + Return getCdmaRoamingPreference(int32_t serial); + + Return setTTYMode(int32_t serial, TtyMode mode); + + Return getTTYMode(int32_t serial); + + Return setPreferredVoicePrivacy(int32_t serial, bool enable); + + Return getPreferredVoicePrivacy(int32_t serial); + + Return sendCDMAFeatureCode(int32_t serial, + const ::android::hardware::hidl_string& featureCode); + + Return sendBurstDtmf(int32_t serial, + const ::android::hardware::hidl_string& dtmf, + int32_t on, + int32_t off); + + Return sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms); + + Return acknowledgeLastIncomingCdmaSms(int32_t serial, + const CdmaSmsAck& smsAck); + + Return getGsmBroadcastConfig(int32_t serial); + + Return setGsmBroadcastConfig(int32_t serial, + const hidl_vec& configInfo); + + Return setGsmBroadcastActivation(int32_t serial, bool activate); + + Return getCdmaBroadcastConfig(int32_t serial); + + Return setCdmaBroadcastConfig(int32_t serial, + const hidl_vec& configInfo); + + Return setCdmaBroadcastActivation(int32_t serial, bool activate); + + Return getCDMASubscription(int32_t serial); + + Return writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms); + + Return deleteSmsOnRuim(int32_t serial, int32_t index); + + Return getDeviceIdentity(int32_t serial); + + Return exitEmergencyCallbackMode(int32_t serial); + + Return getSmscAddress(int32_t serial); + + Return setSmscAddress(int32_t serial, + const ::android::hardware::hidl_string& smsc); + + Return reportSmsMemoryStatus(int32_t serial, bool available); + + Return reportStkServiceIsRunning(int32_t serial); + + Return getCdmaSubscriptionSource(int32_t serial); + + Return requestIsimAuthentication(int32_t serial, + const ::android::hardware::hidl_string& challenge); + + Return acknowledgeIncomingGsmSmsWithPdu(int32_t serial, + bool success, + const ::android::hardware::hidl_string& ackPdu); + + Return sendEnvelopeWithStatus(int32_t serial, + const ::android::hardware::hidl_string& contents); + + Return getVoiceRadioTechnology(int32_t serial); + + Return getCellInfoList(int32_t serial); + + Return setCellInfoListRate(int32_t serial, int32_t rate); + + Return setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo, + bool modemCognitive, bool isRoaming); + + Return getImsRegistrationState(int32_t serial); + + Return sendImsSms(int32_t serial, const ImsSmsMessage& message); + + Return iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message); + + Return iccOpenLogicalChannel(int32_t serial, + const ::android::hardware::hidl_string& aid, int32_t p2); + + Return iccCloseLogicalChannel(int32_t serial, int32_t channelId); + + Return iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message); + + Return nvReadItem(int32_t serial, NvItem itemId); + + Return nvWriteItem(int32_t serial, const NvWriteItem& item); + + Return nvWriteCdmaPrl(int32_t serial, + const ::android::hardware::hidl_vec& prl); + + Return nvResetConfig(int32_t serial, ResetNvType resetType); + + Return setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub); + + Return setDataAllowed(int32_t serial, bool allow); + + Return getHardwareConfig(int32_t serial); + + Return requestIccSimAuthentication(int32_t serial, + int32_t authContext, + const ::android::hardware::hidl_string& authData, + const ::android::hardware::hidl_string& aid); + + Return setDataProfile(int32_t serial, + const ::android::hardware::hidl_vec& profiles, bool isRoaming); + + Return requestShutdown(int32_t serial); + + Return getRadioCapability(int32_t serial); + + Return setRadioCapability(int32_t serial, const RadioCapability& rc); + + Return startLceService(int32_t serial, int32_t reportInterval, bool pullMode); + + Return stopLceService(int32_t serial); + + Return pullLceData(int32_t serial); + + Return getModemActivityInfo(int32_t serial); + + Return setAllowedCarriers(int32_t serial, + bool allAllowed, + const CarrierRestrictions& carriers); + + Return getAllowedCarriers(int32_t serial); + + Return sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state); + + Return setIndicationFilter(int32_t serial, int32_t indicationFilter); + + Return startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive); + + Return stopKeepalive(int32_t serial, int32_t sessionHandle); + + Return setSimCardPower(int32_t serial, bool powerUp); + Return setSimCardPower_1_1(int32_t serial, + const V1_1::CardPowerState state); + + Return responseAcknowledgement(); + + Return setCarrierInfoForImsiEncryption(int32_t serial, + const V1_1::ImsiEncryptionInfo& message); + + void checkReturnStatus(Return& ret); +}; + +struct OemHookImpl : public IOemHook { + int32_t mSlotId; + sp mOemHookResponse; + sp mOemHookIndication; + + Return setResponseFunctions( + const ::android::sp& oemHookResponse, + const ::android::sp& oemHookIndication); + + Return sendRequestRaw(int32_t serial, + const ::android::hardware::hidl_vec& data); + + Return sendRequestStrings(int32_t serial, + const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data); +}; + +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. + * Returns true on success, and false on failure. + */ +bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) { + size_t len = src.size(); + if (len == 0 && + (pRI->pCI->requestNumber != RIL_REQUEST_ENTER_SIM_PIN) && + (pRI->pCI->requestNumber != RIL_REQUEST_ENTER_SIM_PUK) && + (pRI->pCI->requestNumber != RIL_REQUEST_ENTER_SIM_PIN2) && + (pRI->pCI->requestNumber != RIL_REQUEST_ENTER_SIM_PUK2)) { + *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; + } + strncpy(*dest, src.c_str(), len + 1); + return true; +} + +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, 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)) { + 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& 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& 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& 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 = isRadioService ? mCounterRadio[slotId] : mCounterOemHook[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 == (isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId])) { + if (isRadioService) { + radioService[slotId]->mRadioResponse = NULL; + radioService[slotId]->mRadioIndication = NULL; + radioService[slotId]->mRadioResponseV1_1 = NULL; + radioService[slotId]->mRadioIndicationV1_1 = NULL; + } else { + oemHookService[slotId]->mOemHookResponse = NULL; + oemHookService[slotId]->mOemHookIndication = NULL; + } + isRadioService ? mCounterRadio[slotId]++ : mCounterOemHook[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& ret) { + ::checkReturnStatus(mSlotId, ret, true); +} + +Return RadioImpl::setResponseFunctions( + const ::android::sp& radioResponseParam, + const ::android::sp& 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 RadioImpl::getIccCardStatus(int32_t serial) { +#if VDBG + RLOGD("getIccCardStatus: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS); + return Void(); +} + +Return 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, + 2, pin.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 3, puk.c_str(), pin.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 2, pin2.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 3, puk2.c_str(), pin2.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 3, oldPin.c_str(), newPin.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 3, oldPin2.c_str(), newPin2.c_str(), aid.c_str()); + return Void(); +} + +Return 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, + 1, netPin.c_str()); + return Void(); +} + +Return RadioImpl::getCurrentCalls(int32_t serial) { +#if VDBG + RLOGD("getCurrentCalls: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS); + return Void(); +} + +Return 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 RadioImpl::getImsiForApp(int32_t serial, const hidl_string& aid) { +#if VDBG + RLOGD("getImsiForApp: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, + 1, aid.c_str()); + return Void(); +} + +Return 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 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 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 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 RadioImpl::conference(int32_t serial) { +#if VDBG + RLOGD("conference: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE); + return Void(); +} + +Return RadioImpl::rejectCall(int32_t serial) { +#if VDBG + RLOGD("rejectCall: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB); + return Void(); +} + +Return 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 RadioImpl::getSignalStrength(int32_t serial) { +#if VDBG + RLOGD("getSignalStrength: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH); + return Void(); +} + +Return RadioImpl::getVoiceRegistrationState(int32_t serial) { +#if VDBG + RLOGD("getVoiceRegistrationState: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE); + return Void(); +} + +Return RadioImpl::getDataRegistrationState(int32_t serial) { +#if VDBG + RLOGD("getDataRegistrationState: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE); + return Void(); +} + +Return RadioImpl::getOperator(int32_t serial) { +#if VDBG + RLOGD("getOperator: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR); + return Void(); +} + +Return 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 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 RadioImpl::sendSms(int32_t serial, const GsmSmsMessage& message) { +#if VDBG + RLOGD("sendSms: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, + 2, message.smscPdu.c_str(), message.pdu.c_str()); + return Void(); +} + +Return 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, + 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 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, 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, 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 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 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 RadioImpl::cancelPendingUssd(int32_t serial) { +#if VDBG + RLOGD("cancelPendingUssd: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD); + return Void(); +} + +Return RadioImpl::getClir(int32_t serial) { +#if VDBG + RLOGD("getClir: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR); + return Void(); +} + +Return 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 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 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 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 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 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 RadioImpl::acceptCall(int32_t serial) { +#if VDBG + RLOGD("acceptCall: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER); + return Void(); +} + +Return 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, + 2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0"); + return Void(); +} + +Return 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, + 4, facility.c_str(), password.c_str(), + (std::to_string(serviceClass)).c_str(), appId.c_str()); + return Void(); +} + +Return 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, + 5, facility.c_str(), lockState ? "1" : "0", password.c_str(), + (std::to_string(serviceClass)).c_str(), appId.c_str() ); + return Void(); +} + +Return 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, + 3, facility.c_str(), oldPassword.c_str(), newPassword.c_str()); + return Void(); +} + +Return 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 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 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 RadioImpl::getAvailableNetworks(int32_t serial) { +#if VDBG + RLOGD("getAvailableNetworks: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS); + return Void(); +} + +Return 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 * bands = nullptr; + switch (request.specifiers[i].radioAccessNetwork) { + case V1_1::RadioAccessNetworks::GERAN: + ras_to.bands_length = ras_from.geranBands.size(); + bands = (std::vector *) &ras_from.geranBands; + break; + case V1_1::RadioAccessNetworks::UTRAN: + ras_to.bands_length = ras_from.utranBands.size(); + bands = (std::vector *) &ras_from.utranBands; + break; + case V1_1::RadioAccessNetworks::EUTRAN: + ras_to.bands_length = ras_from.eutranBands.size(); + bands = (std::vector *) &ras_from.eutranBands; + break; + default: + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return Void(); + } + // safe to copy to geran_bands because it's a union member + 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 RadioImpl::stopNetworkScan(int32_t serial) { +#if VDBG + RLOGD("stopNetworkScan: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_NETWORK_SCAN); + return Void(); +} + +Return 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 RadioImpl::stopDtmf(int32_t serial) { +#if VDBG + RLOGD("stopDtmf: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP); + return Void(); +} + +Return RadioImpl::getBasebandVersion(int32_t serial) { +#if VDBG + RLOGD("getBasebandVersion: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION); + return Void(); +} + +Return 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 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 RadioImpl::getMute(int32_t serial) { +#if VDBG + RLOGD("getMute: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE); + return Void(); +} + +Return RadioImpl::getClip(int32_t serial) { +#if VDBG + RLOGD("getClip: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP); + return Void(); +} + +Return RadioImpl::getDataCallList(int32_t serial) { +#if VDBG + RLOGD("getDataCallList: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST); + return Void(); +} + +Return 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 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 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 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 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 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 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 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 RadioImpl::explicitCallTransfer(int32_t serial) { +#if VDBG + RLOGD("explicitCallTransfer: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER); + return Void(); +} + +Return 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 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 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 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 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 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 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 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 RadioImpl::getTTYMode(int32_t serial) { +#if VDBG + RLOGD("getTTYMode: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE); + return Void(); +} + +Return 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 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 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 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, + 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 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 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 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 RadioImpl::setGsmBroadcastConfig(int32_t serial, + const hidl_vec& + 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(); + } + + int num = configInfo.size(); + RIL_GSM_BroadcastSmsConfigInfo gsmBci[num]; + RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num]; + + for (int 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, + num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId); + return Void(); +} + +Return 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 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 RadioImpl::setCdmaBroadcastConfig(int32_t serial, + const hidl_vec& + 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(); + } + + int num = configInfo.size(); + RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num]; + RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num]; + + for (int 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, + num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId); + return Void(); +} + +Return 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 RadioImpl::getCDMASubscription(int32_t serial) { +#if VDBG + RLOGD("getCDMASubscription: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION); + return Void(); +} + +Return 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 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 RadioImpl::getDeviceIdentity(int32_t serial) { +#if VDBG + RLOGD("getDeviceIdentity: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY); + return Void(); +} + +Return 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 RadioImpl::getSmscAddress(int32_t serial) { +#if VDBG + RLOGD("getSmscAddress: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS); + return Void(); +} + +Return 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 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 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 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 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 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, + 2, success ? "1" : "0", ackPdu.c_str()); + return Void(); +} + +Return 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 RadioImpl::getVoiceRadioTechnology(int32_t serial) { +#if VDBG + RLOGD("getVoiceRadioTechnology: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH); + return Void(); +} + +Return 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 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 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 (dataProfileInfo.apn.size() == 0) { + iaa.apn = (char *) calloc(1, sizeof(char)); + if (iaa.apn == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + iaa.apn[0] = '\0'; + } else { + if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) { + return Void(); + } + } + + const hidl_string &protocol = + (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 (dataProfileInfo.apn.size() == 0) { + iaa.apn = (char *) calloc(1, sizeof(char)); + if (iaa.apn == NULL) { + RLOGE("Memory allocation failed for request %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_NO_MEMORY); + return Void(); + } + iaa.apn[0] = '\0'; + } else { + if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) { + return Void(); + } + } + + if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) { + memsetAndFreeStrings(1, iaa.apn); + return Void(); + } + 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 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 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(); + } + + RIL_RadioTechnologyFamily format = (RIL_RadioTechnologyFamily) message.tech; + + if (RADIO_TECH_3GPP == format) { + dispatchImsGsmSms(message, pRI); + } else if (RADIO_TECH_3GPP2 == format) { + dispatchImsCdmaSms(message, pRI); + } else { + RLOGE("sendImsSms: Invalid radio tech %s", + requestToString(pRI->pCI->requestNumber)); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + } + return Void(); +} + +Return 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 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 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 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 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 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 RadioImpl::nvWriteCdmaPrl(int32_t serial, const hidl_vec& prl) { +#if VDBG + RLOGD("nvWriteCdmaPrl: serial %d", serial); +#endif + dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl); + return Void(); +} + +Return 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 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 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 RadioImpl::getHardwareConfig(int32_t serial) { +#if VDBG + RLOGD("getHardwareConfig: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG); + return Void(); +} + +Return 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 +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 RadioImpl::setDataProfile(int32_t serial, const hidl_vec& 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); + + const hidl_string &protocol = + (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol); + + if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI)) { + success = false; + } + + if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, + pRI)) { + 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); + if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol, + pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol, + profiles[i].roamingProtocol, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password, + pRI)) { + success = false; + } + if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData, + profiles[i].mvnoMatchData, pRI)) { + 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 RadioImpl::requestShutdown(int32_t serial) { +#if VDBG + RLOGD("requestShutdown: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN); + return Void(); +} + +Return RadioImpl::getRadioCapability(int32_t serial) { +#if VDBG + RLOGD("getRadioCapability: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY); + return Void(); +} + +Return 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; + strncpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), MAX_UUID_LENGTH); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId); + + return Void(); +} + +Return 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 RadioImpl::stopLceService(int32_t serial) { +#if VDBG + RLOGD("stopLceService: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE); + return Void(); +} + +Return RadioImpl::pullLceData(int32_t serial) { +#if VDBG + RLOGD("pullLceData: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA); + return Void(); +} + +Return RadioImpl::getModemActivityInfo(int32_t serial) { +#if VDBG + RLOGD("getModemActivityInfo: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO); + return Void(); +} + +Return 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 RadioImpl::getAllowedCarriers(int32_t serial) { +#if VDBG + RLOGD("getAllowedCarriers: serial %d", serial); +#endif + dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS); + return Void(); +} + +Return 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 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 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 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 RadioImpl::setCarrierInfoForImsiEncryption(int32_t serial, + const V1_1::ImsiEncryptionInfo& data) { +#if VDBG + RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial); +#endif + RequestInfo *pRI = android::addRequestToList( + serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION); + if (pRI == NULL) { + return Void(); + } + + RIL_CarrierInfoForImsiEncryption imsiEncryption = {}; + + if (!copyHidlStringToRil(&imsiEncryption.mnc, data.mnc, pRI)) { + return Void(); + } + if (!copyHidlStringToRil(&imsiEncryption.mcc, data.mcc, pRI)) { + memsetAndFreeStrings(1, imsiEncryption.mnc); + return Void(); + } + if (!copyHidlStringToRil(&imsiEncryption.keyIdentifier, data.keyIdentifier, pRI)) { + memsetAndFreeStrings(2, imsiEncryption.mnc, imsiEncryption.mcc); + return Void(); + } + int32_t lSize = data.carrierKey.size(); + imsiEncryption.carrierKey = new uint8_t[lSize]; + memcpy(imsiEncryption.carrierKey, data.carrierKey.data(), lSize); + imsiEncryption.expirationTime = data.expirationTime; + CALL_ONREQUEST(pRI->pCI->requestNumber, &imsiEncryption, + sizeof(RIL_CarrierInfoForImsiEncryption), pRI, mSlotId); + delete(imsiEncryption.carrierKey); + return Void(); +} + +Return RadioImpl::startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive) { +#if VDBG + RLOGD("%s(): %d", __FUNCTION__, serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_KEEPALIVE); + if (pRI == NULL) { + return Void(); + } + + RIL_KeepaliveRequest kaReq = {}; + + kaReq.type = static_cast(keepalive.type); + switch(kaReq.type) { + case NATT_IPV4: + if (keepalive.sourceAddress.size() != 4 || + keepalive.destinationAddress.size() != 4) { + RLOGE("Invalid address for keepalive!"); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return Void(); + } + break; + case NATT_IPV6: + if (keepalive.sourceAddress.size() != 16 || + keepalive.destinationAddress.size() != 16) { + RLOGE("Invalid address for keepalive!"); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return Void(); + } + break; + default: + RLOGE("Unknown packet keepalive type!"); + sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS); + return Void(); + } + + ::memcpy(kaReq.sourceAddress, keepalive.sourceAddress.data(), keepalive.sourceAddress.size()); + kaReq.sourcePort = keepalive.sourcePort; + + ::memcpy(kaReq.destinationAddress, + keepalive.destinationAddress.data(), keepalive.destinationAddress.size()); + kaReq.destinationPort = keepalive.destinationPort; + + kaReq.maxKeepaliveIntervalMillis = keepalive.maxKeepaliveIntervalMillis; + kaReq.cid = keepalive.cid; // This is the context ID of the data call + + CALL_ONREQUEST(pRI->pCI->requestNumber, &kaReq, sizeof(RIL_KeepaliveRequest), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::stopKeepalive(int32_t serial, int32_t sessionHandle) { +#if VDBG + RLOGD("%s(): %d", __FUNCTION__, serial); +#endif + RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_STOP_KEEPALIVE); + if (pRI == NULL) { + return Void(); + } + + CALL_ONREQUEST(pRI->pCI->requestNumber, &sessionHandle, sizeof(uint32_t), pRI, mSlotId); + return Void(); +} + +Return RadioImpl::responseAcknowledgement() { + android::releaseWakeLock(); + return Void(); +} + +Return OemHookImpl::setResponseFunctions( + const ::android::sp& oemHookResponseParam, + const ::android::sp& oemHookIndicationParam) { +#if VDBG + RLOGD("OemHookImpl::setResponseFunctions"); +#endif + + pthread_rwlock_t *radioServiceRwlockPtr = radio::getRadioServiceRwlock(mSlotId); + int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + mOemHookResponse = oemHookResponseParam; + mOemHookIndication = oemHookIndicationParam; + mCounterOemHook[mSlotId]++; + + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + + return Void(); +} + +Return OemHookImpl::sendRequestRaw(int32_t serial, const hidl_vec& data) { +#if VDBG + RLOGD("OemHookImpl::sendRequestRaw: serial %d", serial); +#endif + dispatchRaw(serial, mSlotId, RIL_REQUEST_OEM_HOOK_RAW, data); + return Void(); +} + +Return OemHookImpl::sendRequestStrings(int32_t serial, + const hidl_vec& data) { +#if VDBG + RLOGD("OemHookImpl::sendRequestStrings: serial %d", serial); +#endif + dispatchStrings(serial, mSlotId, RIL_REQUEST_OEM_HOOK_STRINGS, data); + return Void(); +} + +/*************************************************************************************************** + * RESPONSE FUNCTIONS + * Functions above are used for requests going from framework to vendor code. The ones below are + * responses for those requests coming back from the vendor code. + **************************************************************************************************/ + +void radio::acknowledgeRequest(int slotId, int serial) { + if (radioService[slotId]->mRadioResponse != NULL) { + Return retStatus = radioService[slotId]->mRadioResponse->acknowledgeRequest(serial); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeRequest: radioService[%d]->mRadioResponse == NULL", slotId); + } +} + +void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e) { + responseInfo.serial = serial; + switch (responseType) { + case RESPONSE_SOLICITED: + responseInfo.type = RadioResponseType::SOLICITED; + break; + case RESPONSE_SOLICITED_ACK_EXP: + responseInfo.type = RadioResponseType::SOLICITED_ACK_EXP; + break; + } + responseInfo.error = (RadioError) e; +} + +int responseIntOrEmpty(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, + void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + int ret = -1; + + if (response == NULL && responseLen == 0) { + // Earlier RILs did not send a response for some cases although the interface + // expected an integer as response. Do not return error if response is empty. Instead + // Return -1 in those cases to maintain backward compatibility. + } else if (response == NULL || responseLen != sizeof(int)) { + RLOGE("responseIntOrEmpty: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *p_int = (int *) response; + ret = p_int[0]; + } + return ret; +} + +int responseInt(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e, + void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + int ret = -1; + + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("responseInt: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *p_int = (int *) response; + ret = p_int[0]; + } + return ret; +} + +int radio::getIccCardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + CardStatus cardStatus = {}; + RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response); + if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6) + || p_cur->gsm_umts_subscription_app_index >= p_cur->num_applications + || p_cur->cdma_subscription_app_index >= p_cur->num_applications + || p_cur->ims_subscription_app_index >= p_cur->num_applications) { + RLOGE("getIccCardStatusResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + cardStatus.cardState = (CardState) p_cur->card_state; + cardStatus.universalPinState = (PinState) p_cur->universal_pin_state; + cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index; + cardStatus.cdmaSubscriptionAppIndex = p_cur->cdma_subscription_app_index; + cardStatus.imsSubscriptionAppIndex = p_cur->ims_subscription_app_index; + + RIL_AppStatus *rilAppStatus = p_cur->applications; + cardStatus.applications.resize(p_cur->num_applications); + AppStatus *appStatus = cardStatus.applications.data(); +#if VDBG + RLOGD("getIccCardStatusResponse: num_applications %d", p_cur->num_applications); +#endif + for (int i = 0; i < p_cur->num_applications; i++) { + appStatus[i].appType = (AppType) rilAppStatus[i].app_type; + appStatus[i].appState = (AppState) rilAppStatus[i].app_state; + appStatus[i].persoSubstate = (PersoSubstate) rilAppStatus[i].perso_substate; + appStatus[i].aidPtr = convertCharPtrToHidlString(rilAppStatus[i].aid_ptr); + appStatus[i].appLabelPtr = convertCharPtrToHidlString( + rilAppStatus[i].app_label_ptr); + appStatus[i].pin1Replaced = rilAppStatus[i].pin1_replaced; + appStatus[i].pin1 = (PinState) rilAppStatus[i].pin1; + appStatus[i].pin2 = (PinState) rilAppStatus[i].pin2; + } + } + + Return retStatus = radioService[slotId]->mRadioResponse-> + getIccCardStatusResponse(responseInfo, cardStatus); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getIccCardStatusResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::supplyIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPinForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPinForAppResponse(responseInfo, ret); + RLOGE("supplyIccPinForAppResponse: amit ret %d", ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPukForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPukForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse->supplyIccPukForAppResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPukForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPin2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPin2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyIccPuk2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyIccPuk2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyIccPuk2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyIccPuk2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::changeIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("changeIccPinForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + changeIccPinForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("changeIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::changeIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("changeIccPin2ForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + changeIccPin2ForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("changeIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::supplyNetworkDepersonalizationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("supplyNetworkDepersonalizationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + supplyNetworkDepersonalizationResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("supplyNetworkDepersonalizationResponse: radioService[%d]->mRadioResponse == " + "NULL", slotId); + } + + return 0; +} + +int radio::getCurrentCallsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCurrentCallsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec calls; + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Call *)) != 0) { + RLOGE("getCurrentCallsResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_Call *); + calls.resize(num); + + for (int i = 0 ; i < num ; i++) { + RIL_Call *p_cur = ((RIL_Call **) response)[i]; + /* each call info */ + calls[i].state = (CallState) p_cur->state; + calls[i].index = p_cur->index; + calls[i].toa = p_cur->toa; + calls[i].isMpty = p_cur->isMpty; + calls[i].isMT = p_cur->isMT; + calls[i].als = p_cur->als; + calls[i].isVoice = p_cur->isVoice; + calls[i].isVoicePrivacy = p_cur->isVoicePrivacy; + calls[i].number = convertCharPtrToHidlString(p_cur->number); + calls[i].numberPresentation = (CallPresentation) p_cur->numberPresentation; + calls[i].name = convertCharPtrToHidlString(p_cur->name); + calls[i].namePresentation = (CallPresentation) p_cur->namePresentation; + if (p_cur->uusInfo != NULL && p_cur->uusInfo->uusData != NULL) { + RIL_UUS_Info *uusInfo = p_cur->uusInfo; + calls[i].uusInfo.resize(1); + calls[i].uusInfo[0].uusType = (UusType) uusInfo->uusType; + calls[i].uusInfo[0].uusDcs = (UusDcs) uusInfo->uusDcs; + // convert uusInfo->uusData to a null-terminated string + char *nullTermStr = strndup(uusInfo->uusData, uusInfo->uusLength); + calls[i].uusInfo[0].uusData = nullTermStr; + free(nullTermStr); + } + } + } + + Return retStatus = radioService[slotId]->mRadioResponse-> + getCurrentCallsResponse(responseInfo, calls); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCurrentCallsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::dialResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("dialResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->dialResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("dialResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getIMSIForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getIMSIForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->getIMSIForAppResponse( + responseInfo, convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getIMSIForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("hangupConnectionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->hangupConnectionResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupConnectionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupWaitingOrBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::hangupForegroundResumeBackgroundResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::switchWaitingOrHoldingAndActiveResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("switchWaitingOrHoldingAndActiveResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->switchWaitingOrHoldingAndActiveResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("switchWaitingOrHoldingAndActiveResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::conferenceResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responseLen) { +#if VDBG + RLOGD("conferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->conferenceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("conferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::rejectCallResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responseLen) { +#if VDBG + RLOGD("rejectCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->rejectCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("rejectCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getLastCallFailCauseResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getLastCallFailCauseResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + LastCallFailCauseInfo info = {}; + info.vendorCause = hidl_string(); + if (response == NULL) { + RLOGE("getCurrentCallsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (responseLen == sizeof(int)) { + int *pInt = (int *) response; + info.causeCode = (LastCallFailCause) pInt[0]; + } else if (responseLen == sizeof(RIL_LastCallFailCauseInfo)) { + RIL_LastCallFailCauseInfo *pFailCauseInfo = (RIL_LastCallFailCauseInfo *) response; + info.causeCode = (LastCallFailCause) pFailCauseInfo->cause_code; + info.vendorCause = convertCharPtrToHidlString(pFailCauseInfo->vendor_cause); + } else { + RLOGE("getCurrentCallsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + + Return retStatus = radioService[slotId]->mRadioResponse->getLastCallFailCauseResponse( + responseInfo, info); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getLastCallFailCauseResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getSignalStrengthResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getSignalStrengthResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + SignalStrength signalStrength = {}; + if (response == NULL || (responseLen != sizeof(RIL_SignalStrength_v10) + && responseLen != sizeof(RIL_SignalStrength_v8))) { + RLOGE("getSignalStrengthResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilSignalStrengthToHal(response, responseLen, signalStrength); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getSignalStrengthResponse( + responseInfo, signalStrength); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getSignalStrengthResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) { + if (rat == NULL) { + return RIL_CELL_INFO_TYPE_NONE; + } + + int radioTech = atoi(rat); + + switch(radioTech) { + + case RADIO_TECH_GPRS: + case RADIO_TECH_EDGE: + case RADIO_TECH_GSM: { + return RIL_CELL_INFO_TYPE_GSM; + } + + case RADIO_TECH_UMTS: + case RADIO_TECH_HSDPA: + case RADIO_TECH_HSUPA: + case RADIO_TECH_HSPA: + case RADIO_TECH_HSPAP: { + return RIL_CELL_INFO_TYPE_WCDMA; + } + + case RADIO_TECH_IS95A: + case RADIO_TECH_IS95B: + case RADIO_TECH_1xRTT: + case RADIO_TECH_EVDO_0: + case RADIO_TECH_EVDO_A: + case RADIO_TECH_EVDO_B: + case RADIO_TECH_EHRPD: { + return RIL_CELL_INFO_TYPE_CDMA; + } + + case RADIO_TECH_LTE: + case RADIO_TECH_LTE_CA: { + return RIL_CELL_INFO_TYPE_LTE; + } + + case RADIO_TECH_TD_SCDMA: { + return RIL_CELL_INFO_TYPE_TD_SCDMA; + } + + default: { + break; + } + } + + return RIL_CELL_INFO_TYPE_NONE; + +} + +void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) { + + cellIdentity.cellIdentityGsm.resize(0); + cellIdentity.cellIdentityWcdma.resize(0); + cellIdentity.cellIdentityCdma.resize(0); + cellIdentity.cellIdentityTdscdma.resize(0); + cellIdentity.cellIdentityLte.resize(0); + cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType; + switch(rilCellIdentity.cellInfoType) { + + case RIL_CELL_INFO_TYPE_GSM: { + cellIdentity.cellIdentityGsm.resize(1); + cellIdentity.cellIdentityGsm[0].mcc = + std::to_string(rilCellIdentity.cellIdentityGsm.mcc); + cellIdentity.cellIdentityGsm[0].mnc = + std::to_string(rilCellIdentity.cellIdentityGsm.mnc); + cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac; + cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid; + cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn; + cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic; + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + cellIdentity.cellIdentityWcdma.resize(1); + cellIdentity.cellIdentityWcdma[0].mcc = + std::to_string(rilCellIdentity.cellIdentityWcdma.mcc); + cellIdentity.cellIdentityWcdma[0].mnc = + std::to_string(rilCellIdentity.cellIdentityWcdma.mnc); + cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac; + cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid; + cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc; + cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn; + break; + } + + case RIL_CELL_INFO_TYPE_CDMA: { + cellIdentity.cellIdentityCdma.resize(1); + cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId; + cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId; + cellIdentity.cellIdentityCdma[0].baseStationId = + rilCellIdentity.cellIdentityCdma.basestationId; + cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude; + cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude; + break; + } + + case RIL_CELL_INFO_TYPE_LTE: { + cellIdentity.cellIdentityLte.resize(1); + cellIdentity.cellIdentityLte[0].mcc = + std::to_string(rilCellIdentity.cellIdentityLte.mcc); + cellIdentity.cellIdentityLte[0].mnc = + std::to_string(rilCellIdentity.cellIdentityLte.mnc); + cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci; + cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci; + cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac; + cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn; + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA: { + cellIdentity.cellIdentityTdscdma.resize(1); + cellIdentity.cellIdentityTdscdma[0].mcc = + std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc); + cellIdentity.cellIdentityTdscdma[0].mnc = + std::to_string(rilCellIdentity.cellIdentityTdscdma.mnc); + cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac; + cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid; + cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid; + break; + } + + default: { + break; + } + } +} + +int convertResponseStringEntryToInt(char **response, int index, int numStrings) { + if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { + return atoi(response[index]); + } + + return -1; +} + +int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) { + const int hexBase = 16; + if ((response != NULL) && (numStrings > index) && (response[index] != NULL)) { + return strtol(response[index], NULL, hexBase); + } + + return -1; +} + +/* Fill Cell Identity info from Voice Registration State Response. + * This fucntion is applicable only for RIL Version < 15. + * Response is a "char **". + * First and Second entries are in hex string format + * and rest are integers represented in ascii format. */ +void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity, + int numStrings, char** response) { + + RIL_CellIdentity_v16 rilCellIdentity; + memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); + + rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); + switch(rilCellIdentity.cellInfoType) { + + case RIL_CELL_INFO_TYPE_GSM: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityGsm.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityGsm.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityWcdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityWcdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + rilCellIdentity.cellIdentityWcdma.psc = + convertResponseStringEntryToInt(response, 14, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA:{ + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityTdscdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityTdscdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_CDMA:{ + rilCellIdentity.cellIdentityCdma.basestationId = + convertResponseStringEntryToInt(response, 4, numStrings); + /* Order of Lat. and Long. swapped between RIL and HIDL interface versions. */ + rilCellIdentity.cellIdentityCdma.latitude = + convertResponseStringEntryToInt(response, 5, numStrings); + rilCellIdentity.cellIdentityCdma.longitude = + convertResponseStringEntryToInt(response, 6, numStrings); + rilCellIdentity.cellIdentityCdma.systemId = + convertResponseStringEntryToInt(response, 8, numStrings); + rilCellIdentity.cellIdentityCdma.networkId = + convertResponseStringEntryToInt(response, 9, numStrings); + break; + } + + case RIL_CELL_INFO_TYPE_LTE:{ + /* valid TAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityLte.tac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityLte.ci = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + + default: { + break; + } + } + + fillCellIdentityResponse(cellIdentity, rilCellIdentity); +} + +/* Fill Cell Identity info from Data Registration State Response. + * This fucntion is applicable only for RIL Version < 15. + * Response is a "char **". + * First and Second entries are in hex string format + * and rest are integers represented in ascii format. */ +void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity, + int numStrings, char** response) { + + RIL_CellIdentity_v16 rilCellIdentity; + memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16)); + + rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]); + switch(rilCellIdentity.cellInfoType) { + case RIL_CELL_INFO_TYPE_GSM: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityGsm.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityGsm.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_WCDMA: { + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityWcdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityWcdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_TD_SCDMA:{ + /* valid LAC are hexstrings in the range 0x0000 - 0xffff */ + rilCellIdentity.cellIdentityTdscdma.lac = + convertResponseHexStringEntryToInt(response, 1, numStrings); + + /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */ + rilCellIdentity.cellIdentityTdscdma.cid = + convertResponseHexStringEntryToInt(response, 2, numStrings); + break; + } + case RIL_CELL_INFO_TYPE_LTE: { + rilCellIdentity.cellIdentityLte.tac = + convertResponseStringEntryToInt(response, 6, numStrings); + rilCellIdentity.cellIdentityLte.pci = + convertResponseStringEntryToInt(response, 7, numStrings); + rilCellIdentity.cellIdentityLte.ci = + convertResponseStringEntryToInt(response, 8, numStrings); + break; + } + default: { + break; + } + } + + fillCellIdentityResponse(cellIdentity, rilCellIdentity); +} + +int radio::getVoiceRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getVoiceRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + VoiceRegStateResult voiceRegResponse = {}; + int numStrings = responseLen / sizeof(char *); + if (response == NULL) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (s_vendorFunctions->version <= 14) { + if (numStrings != 15) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); + voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]); + voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0); + voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]); + voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0); + voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0); + voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0); + fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity, + numStrings, resp); + } + } else { + RIL_VoiceRegistrationStateResponse *voiceRegState = + (RIL_VoiceRegistrationStateResponse *)response; + + if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) { + RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + voiceRegResponse.regState = (RegState) voiceRegState->regState; + voiceRegResponse.rat = voiceRegState->rat;; + voiceRegResponse.cssSupported = voiceRegState->cssSupported; + voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator; + voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl; + voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator; + voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial; + fillCellIdentityResponse(voiceRegResponse.cellIdentity, + voiceRegState->cellIdentity); + } + } + + Return retStatus = + radioService[slotId]->mRadioResponse->getVoiceRegistrationStateResponse( + responseInfo, voiceRegResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getVoiceRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getDataRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getDataRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + DataRegStateResult dataRegResponse = {}; + if (response == NULL) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else if (s_vendorFunctions->version <= 14) { + int numStrings = responseLen / sizeof(char *); + if ((numStrings != 6) && (numStrings != 11)) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4); + dataRegResponse.rat = ATOI_NULL_HANDLED_DEF(resp[3], 0); + dataRegResponse.reasonDataDenied = ATOI_NULL_HANDLED(resp[4]); + dataRegResponse.maxDataCalls = ATOI_NULL_HANDLED_DEF(resp[5], 1); + fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity, + numStrings, resp); + } + } else { + RIL_DataRegistrationStateResponse *dataRegState = + (RIL_DataRegistrationStateResponse *)response; + + if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) { + RLOGE("getDataRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + dataRegResponse.regState = (RegState) dataRegState->regState; + dataRegResponse.rat = dataRegState->rat;; + dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied; + dataRegResponse.maxDataCalls = dataRegState->maxDataCalls; + fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity); + } + } + + Return retStatus = + radioService[slotId]->mRadioResponse->getDataRegistrationStateResponse(responseInfo, + dataRegResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getDataRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getOperatorResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getOperatorResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_string longName; + hidl_string shortName; + hidl_string numeric; + int numStrings = responseLen / sizeof(char *); + if (response == NULL || numStrings != 3) { + RLOGE("getOperatorResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + + } else { + char **resp = (char **) response; + longName = convertCharPtrToHidlString(resp[0]); + shortName = convertCharPtrToHidlString(resp[1]); + numeric = convertCharPtrToHidlString(resp[2]); + } + Return retStatus = radioService[slotId]->mRadioResponse->getOperatorResponse( + responseInfo, longName, shortName, numeric); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getOperatorResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setRadioPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { + RLOGD("setRadioPowerResponse: serial %d", serial); + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->sendDtmfResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendDtmfResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +SendSmsResult makeSendSmsResult(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + SendSmsResult result = {}; + + if (response == NULL || responseLen != sizeof(RIL_SMS_Response)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + result.ackPDU = hidl_string(); + } else { + RIL_SMS_Response *resp = (RIL_SMS_Response *) response; + result.messageRef = resp->messageRef; + result.ackPDU = convertCharPtrToHidlString(resp->ackPDU); + result.errorCode = resp->errorCode; + } + return result; +} + +int radio::sendSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->sendSmsResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendSMSExpectMoreResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendSMSExpectMoreResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->sendSMSExpectMoreResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSMSExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setupDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setupDataCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + SetupDataCallResult result = {}; + + if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + if (response != NULL) { + RLOGE("setupDataCallResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + result.status = DataCallFailCause::ERROR_UNSPECIFIED; + result.type = hidl_string(); + result.ifname = hidl_string(); + result.addresses = hidl_string(); + result.dnses = hidl_string(); + result.gateways = hidl_string(); + result.pcscf = hidl_string(); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v11)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v9)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v9 *) response, result); + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v6)) == 0) { + convertRilDataCallToHal((RIL_Data_Call_Response_v6 *) response, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->setupDataCallResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setupDataCallResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +IccIoResult responseIccIo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + IccIoResult result = {}; + + if (response == NULL || responseLen != sizeof(RIL_SIM_IO_Response)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + result.simResponse = hidl_string(); + } else { + RIL_SIM_IO_Response *resp = (RIL_SIM_IO_Response *) response; + result.sw1 = resp->sw1; + result.sw2 = resp->sw2; + result.simResponse = convertCharPtrToHidlString(resp->simResponse); + } + return result; +} + +int radio::iccIOForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("iccIOForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus = radioService[slotId]->mRadioResponse->iccIOForAppResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccIOForAppResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendUssdResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->sendUssdResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendUssdResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::cancelPendingUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("cancelPendingUssdResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->cancelPendingUssdResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cancelPendingUssdResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getClirResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + int n = -1, m = -1; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getClirResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + n = pInt[0]; + m = pInt[1]; + } + Return retStatus = radioService[slotId]->mRadioResponse->getClirResponse(responseInfo, + n, m); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setClirResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setClirResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setClirResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getCallForwardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCallForwardStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec callForwardInfos; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CallForwardInfo *) != 0) { + RLOGE("getCallForwardStatusResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_CallForwardInfo *); + callForwardInfos.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_CallForwardInfo *resp = ((RIL_CallForwardInfo **) response)[i]; + callForwardInfos[i].status = (CallForwardInfoStatus) resp->status; + callForwardInfos[i].reason = resp->reason; + callForwardInfos[i].serviceClass = resp->serviceClass; + callForwardInfos[i].toa = resp->toa; + callForwardInfos[i].number = convertCharPtrToHidlString(resp->number); + callForwardInfos[i].timeSeconds = resp->timeSeconds; + } + } + + Return retStatus = radioService[slotId]->mRadioResponse->getCallForwardStatusResponse( + responseInfo, callForwardInfos); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCallForwardStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCallForwardResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCallForwardResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setCallForwardResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCallForwardResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCallWaitingResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + int serviceClass = -1; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getCallWaitingResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + serviceClass = pInt[1]; + } + Return retStatus = radioService[slotId]->mRadioResponse->getCallWaitingResponse( + responseInfo, enable, serviceClass); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCallWaitingResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->setCallWaitingResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::acknowledgeLastIncomingGsmSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acknowledgeLastIncomingGsmSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = + radioService[slotId]->mRadioResponse->acknowledgeLastIncomingGsmSmsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeLastIncomingGsmSmsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::acceptCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acceptCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->acceptCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acceptCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::deactivateDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deactivateDataCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->deactivateDataCallResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deactivateDataCallResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getFacilityLockForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse-> + getFacilityLockForAppResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setFacilityLockForAppResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->setFacilityLockForAppResponse(responseInfo, + ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setBarringPasswordResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acceptCallResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setBarringPasswordResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setBarringPasswordResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getNetworkSelectionModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getNetworkSelectionModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool manual = false; + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("getNetworkSelectionModeResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + manual = pInt[0] == 1 ? true : false; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getNetworkSelectionModeResponse( + responseInfo, + manual); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getNetworkSelectionModeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setNetworkSelectionModeAutomaticResponse(int slotId, int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setNetworkSelectionModeAutomaticResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setNetworkSelectionModeAutomaticResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setNetworkSelectionModeAutomaticResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::setNetworkSelectionModeManualResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse " + "== NULL", slotId); + } + + return 0; +} + +int convertOperatorStatusToInt(const char *str) { + if (strncmp("unknown", str, 9) == 0) { + return (int) OperatorStatus::UNKNOWN; + } else if (strncmp("available", str, 9) == 0) { + return (int) OperatorStatus::AVAILABLE; + } else if (strncmp("current", str, 9) == 0) { + return (int) OperatorStatus::CURRENT; + } else if (strncmp("forbidden", str, 9) == 0) { + return (int) OperatorStatus::FORBIDDEN; + } else { + return -1; + } +} + +int radio::getAvailableNetworksResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getAvailableNetworksResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec networks; + if ((response == NULL && responseLen != 0) + || responseLen % (4 * sizeof(char *))!= 0) { + RLOGE("getAvailableNetworksResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + int numStrings = responseLen / sizeof(char *); + networks.resize(numStrings/4); + for (int i = 0, j = 0; i < numStrings; i = i + 4, j++) { + networks[j].alphaLong = convertCharPtrToHidlString(resp[i]); + networks[j].alphaShort = convertCharPtrToHidlString(resp[i + 1]); + networks[j].operatorNumeric = convertCharPtrToHidlString(resp[i + 2]); + int status = convertOperatorStatusToInt(resp[i + 3]); + if (status == -1) { + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + networks[j].status = (OperatorStatus) status; + } + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->getAvailableNetworksResponse(responseInfo, + networks); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAvailableNetworksResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::startDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("startDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->startDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("startDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::stopDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("stopDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->stopDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stopDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getBasebandVersionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getBasebandVersionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->getBasebandVersionResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getBasebandVersionResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::separateConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("separateConnectionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->separateConnectionResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("separateConnectionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setMuteResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setMuteResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getMuteResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("getMuteResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + } + Return retStatus = radioService[slotId]->mRadioResponse->getMuteResponse(responseInfo, + enable); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getClipResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getClipResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus = radioService[slotId]->mRadioResponse->getClipResponse(responseInfo, + (ClipStatus) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getClipResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getDataCallListResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getDataCallListResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec ret; + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + RLOGE("getDataCallListResponse: invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilDataCallListToHal(response, responseLen, ret); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getDataCallListResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getDataCallListResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setSuppServiceNotificationsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSuppServiceNotificationsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setSuppServiceNotificationsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setSuppServiceNotificationsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::deleteSmsOnSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deleteSmsOnSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->deleteSmsOnSimResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deleteSmsOnSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setBandModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setBandModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setBandModeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setBandModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::writeSmsToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("writeSmsToSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->writeSmsToSimResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("writeSmsToSimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getAvailableBandModesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getAvailableBandModesResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec modes; + if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) { + RLOGE("getAvailableBandModesResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + int numInts = responseLen / sizeof(int); + modes.resize(numInts); + for (int i = 0; i < numInts; i++) { + modes[i] = (RadioBandMode) pInt[i]; + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->getAvailableBandModesResponse(responseInfo, + modes); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAvailableBandModesResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendEnvelopeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendEnvelopeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendEnvelopeResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendEnvelopeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendTerminalResponseToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendTerminalResponseToSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendTerminalResponseToSimResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendTerminalResponseToSimResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::handleStkCallSetupRequestFromSimResponse(int slotId, + int responseType, int serial, + RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("handleStkCallSetupRequestFromSimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->handleStkCallSetupRequestFromSimResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("handleStkCallSetupRequestFromSimResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::explicitCallTransferResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("explicitCallTransferResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->explicitCallTransferResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("explicitCallTransferResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setPreferredNetworkTypeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setPreferredNetworkTypeResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + + +int radio::getPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getPreferredNetworkTypeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getPreferredNetworkTypeResponse( + responseInfo, (PreferredNetworkType) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getNeighboringCidsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getNeighboringCidsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec cells; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_NeighboringCell *) != 0) { + RLOGE("getNeighboringCidsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_NeighboringCell *); + cells.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_NeighboringCell *resp = ((RIL_NeighboringCell **) response)[i]; + cells[i].cid = convertCharPtrToHidlString(resp->cid); + cells[i].rssi = resp->rssi; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getNeighboringCidsResponse(responseInfo, + cells); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getNeighboringCidsResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setLocationUpdatesResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setLocationUpdatesResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setLocationUpdatesResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setLocationUpdatesResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaSubscriptionSourceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaSubscriptionSourceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaRoamingPreferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaRoamingPreferenceResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaRoamingPreferenceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaRoamingPreferenceResponse( + responseInfo, (CdmaRoamingType) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setTTYModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setTTYModeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getTTYModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getTTYModeResponse(responseInfo, + (TtyMode) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setPreferredVoicePrivacyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setPreferredVoicePrivacyResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getPreferredVoicePrivacyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool enable = false; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 1) { + RLOGE("getPreferredVoicePrivacyResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + enable = pInt[0] == 1 ? true : false; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getPreferredVoicePrivacyResponse( + responseInfo, enable); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendCDMAFeatureCodeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendCDMAFeatureCodeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendCDMAFeatureCodeResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendCDMAFeatureCodeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendBurstDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendBurstDtmfResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendBurstDtmfResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendBurstDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::sendCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendCdmaSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendCdmaSmsResponse(responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendCdmaSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::acknowledgeLastIncomingCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("acknowledgeLastIncomingCdmaSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->acknowledgeLastIncomingCdmaSmsResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeLastIncomingCdmaSmsResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::getGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getGsmBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec configs; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) { + RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *); + configs.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_GSM_BroadcastSmsConfigInfo *resp = + ((RIL_GSM_BroadcastSmsConfigInfo **) response)[i]; + configs[i].fromServiceId = resp->fromServiceId; + configs[i].toServiceId = resp->toServiceId; + configs[i].fromCodeScheme = resp->fromCodeScheme; + configs[i].toCodeScheme = resp->toCodeScheme; + configs[i].selected = resp->selected == 1 ? true : false; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getGsmBroadcastConfigResponse(responseInfo, + configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setGsmBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setGsmBroadcastConfigResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setGsmBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setGsmBroadcastActivationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setGsmBroadcastActivationResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setGsmBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec configs; + + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) { + RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int num = responseLen / sizeof(RIL_CDMA_BroadcastSmsConfigInfo *); + configs.resize(num); + for (int i = 0 ; i < num; i++) { + RIL_CDMA_BroadcastSmsConfigInfo *resp = + ((RIL_CDMA_BroadcastSmsConfigInfo **) response)[i]; + configs[i].serviceCategory = resp->service_category; + configs[i].language = resp->language; + configs[i].selected = resp->selected == 1 ? true : false; + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaBroadcastConfigResponse(responseInfo, + configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaBroadcastConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaBroadcastConfigResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setCdmaBroadcastActivationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCdmaBroadcastActivationResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCdmaBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCDMASubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCDMASubscriptionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + int numStrings = responseLen / sizeof(char *); + hidl_string emptyString; + if (response == NULL || numStrings != 5) { + RLOGE("getOperatorResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + Return retStatus + = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( + responseInfo, emptyString, emptyString, emptyString, emptyString, emptyString); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + char **resp = (char **) response; + Return retStatus + = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse( + responseInfo, + convertCharPtrToHidlString(resp[0]), + convertCharPtrToHidlString(resp[1]), + convertCharPtrToHidlString(resp[2]), + convertCharPtrToHidlString(resp[3]), + convertCharPtrToHidlString(resp[4])); + radioService[slotId]->checkReturnStatus(retStatus); + } + } else { + RLOGE("getCDMASubscriptionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::writeSmsToRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("writeSmsToRuimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->writeSmsToRuimResponse(responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("writeSmsToRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::deleteSmsOnRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("deleteSmsOnRuimResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->deleteSmsOnRuimResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("deleteSmsOnRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getDeviceIdentityResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getDeviceIdentityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + int numStrings = responseLen / sizeof(char *); + hidl_string emptyString; + if (response == NULL || numStrings != 4) { + RLOGE("getDeviceIdentityResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + Return retStatus + = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, + emptyString, emptyString, emptyString, emptyString); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + char **resp = (char **) response; + Return retStatus + = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo, + convertCharPtrToHidlString(resp[0]), + convertCharPtrToHidlString(resp[1]), + convertCharPtrToHidlString(resp[2]), + convertCharPtrToHidlString(resp[3])); + radioService[slotId]->checkReturnStatus(retStatus); + } + } else { + RLOGE("getDeviceIdentityResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::exitEmergencyCallbackModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("exitEmergencyCallbackModeResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->exitEmergencyCallbackModeResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("exitEmergencyCallbackModeResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getSmscAddressResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->getSmscAddressResponse(responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSmscAddressResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setSmscAddressResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::reportSmsMemoryStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("reportSmsMemoryStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->reportSmsMemoryStatusResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("reportSmsMemoryStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::reportStkServiceIsRunningResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("reportStkServiceIsRunningResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse-> + reportStkServiceIsRunningResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("reportStkServiceIsRunningResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getCdmaSubscriptionSourceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getCdmaSubscriptionSourceResponse( + responseInfo, (CdmaSubscriptionSource) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::requestIsimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestIsimAuthenticationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->requestIsimAuthenticationResponse( + responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestIsimAuthenticationResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::acknowledgeIncomingGsmSmsWithPduResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("acknowledgeIncomingGsmSmsWithPduResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("acknowledgeIncomingGsmSmsWithPduResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::sendEnvelopeWithStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendEnvelopeWithStatusResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendEnvelopeWithStatusResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendEnvelopeWithStatusResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getVoiceRadioTechnologyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getVoiceRadioTechnologyResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->getVoiceRadioTechnologyResponse( + responseInfo, (RadioTechnology) ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getVoiceRadioTechnologyResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getCellInfoListResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("getCellInfoListResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec ret; + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_CellInfo_v12) != 0) { + RLOGE("getCellInfoListResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilCellInfoListToHal(response, responseLen, ret); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getCellInfoListResponse( + responseInfo, ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getCellInfoListResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setCellInfoListRateResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("setCellInfoListRateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setCellInfoListRateResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCellInfoListRateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setInitialAttachApnResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setInitialAttachApnResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getImsRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getImsRegistrationStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + bool isRegistered = false; + int ratFamily = 0; + int numInts = responseLen / sizeof(int); + if (response == NULL || numInts != 2) { + RLOGE("getImsRegistrationStateResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + int *pInt = (int *) response; + isRegistered = pInt[0] == 1 ? true : false; + ratFamily = pInt[1]; + } + Return retStatus + = radioService[slotId]->mRadioResponse->getImsRegistrationStateResponse( + responseInfo, isRegistered, (RadioTechnologyFamily) ratFamily); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getImsRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendImsSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("sendImsSmsResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->sendImsSmsResponse(responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::iccTransmitApduBasicChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccTransmitApduBasicChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->iccTransmitApduBasicChannelResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccTransmitApduBasicChannelResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::iccOpenLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("iccOpenLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + int channelId = -1; + hidl_vec selectResponse; + int numInts = responseLen / sizeof(int); + if (response == NULL || responseLen % sizeof(int) != 0) { + RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL"); + if (response != NULL) { + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } + } else { + int *pInt = (int *) response; + channelId = pInt[0]; + selectResponse.resize(numInts - 1); + for (int i = 1; i < numInts; i++) { + selectResponse[i - 1] = (int8_t) pInt[i]; + } + } + Return retStatus + = radioService[slotId]->mRadioResponse->iccOpenLogicalChannelResponse(responseInfo, + channelId, selectResponse); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccOpenLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::iccCloseLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccCloseLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->iccCloseLogicalChannelResponse( + responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccCloseLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::iccTransmitApduLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("iccTransmitApduLogicalChannelResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->iccTransmitApduLogicalChannelResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("iccTransmitApduLogicalChannelResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::nvReadItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvReadItemResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponse->nvReadItemResponse( + responseInfo, + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvReadItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvWriteItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvWriteItemResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvWriteItemResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvWriteItemResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvWriteCdmaPrlResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvWriteCdmaPrlResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvWriteCdmaPrlResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvWriteCdmaPrlResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::nvResetConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("nvResetConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->nvResetConfigResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nvResetConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setUiccSubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setUiccSubscriptionResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setUiccSubscriptionResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setUiccSubscriptionResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setDataAllowedResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setDataAllowedResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setDataAllowedResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setDataAllowedResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getHardwareConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getHardwareConfigResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + hidl_vec result; + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_HardwareConfig) != 0) { + RLOGE("hardwareConfigChangedInd: invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilHardwareConfigListToHal(response, responseLen, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->getHardwareConfigResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getHardwareConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::requestIccSimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestIccSimAuthenticationResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response, + responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->requestIccSimAuthenticationResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestIccSimAuthenticationResponse: radioService[%d]->mRadioResponse " + "== NULL", slotId); + } + + return 0; +} + +int radio::setDataProfileResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setDataProfileResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setDataProfileResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::requestShutdownResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("requestShutdownResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->requestShutdownResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("requestShutdownResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +void responseRadioCapability(RadioResponseInfo& responseInfo, int serial, + int responseType, RIL_Errno e, void *response, size_t responseLen, RadioCapability& rc) { + populateResponseInfo(responseInfo, serial, responseType, e); + + if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { + RLOGE("responseRadioCapability: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + rc.logicalModemUuid = hidl_string(); + } else { + convertRilRadioCapabilityToHal(response, responseLen, rc); + } +} + +int radio::getRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getRadioCapabilityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + RadioCapability result = {}; + responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, + result); + Return retStatus = radioService[slotId]->mRadioResponse->getRadioCapabilityResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setRadioCapabilityResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + RadioCapability result = {}; + responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen, + result); + Return retStatus = radioService[slotId]->mRadioResponse->setRadioCapabilityResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +LceStatusInfo responseLceStatusInfo(RadioResponseInfo& responseInfo, int serial, int responseType, + RIL_Errno e, void *response, size_t responseLen) { + populateResponseInfo(responseInfo, serial, responseType, e); + LceStatusInfo result = {}; + + if (response == NULL || responseLen != sizeof(RIL_LceStatusInfo)) { + RLOGE("Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_LceStatusInfo *resp = (RIL_LceStatusInfo *) response; + result.lceStatus = (LceStatus) resp->lce_status; + result.actualIntervalMs = (uint8_t) resp->actual_interval_ms; + } + return result; +} + +int radio::startLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("startLceServiceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->startLceServiceResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("startLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::stopLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("stopLceServiceResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e, + response, responseLen); + + Return retStatus + = radioService[slotId]->mRadioResponse->stopLceServiceResponse(responseInfo, + result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stopLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::pullLceDataResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("pullLceDataResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + LceDataInfo result = {}; + if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { + RLOGE("pullLceDataResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilLceDataInfoToHal(response, responseLen, result); + } + + Return retStatus = radioService[slotId]->mRadioResponse->pullLceDataResponse( + responseInfo, result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("pullLceDataResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::getModemActivityInfoResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getModemActivityInfoResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + ActivityStatsInfo info; + if (response == NULL || responseLen != sizeof(RIL_ActivityStatsInfo)) { + RLOGE("getModemActivityInfoResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_ActivityStatsInfo *resp = (RIL_ActivityStatsInfo *)response; + info.sleepModeTimeMs = resp->sleep_mode_time_ms; + info.idleModeTimeMs = resp->idle_mode_time_ms; + for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) { + info.txmModetimeMs[i] = resp->tx_mode_time_ms[i]; + } + info.rxModeTimeMs = resp->rx_mode_time_ms; + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getModemActivityInfoResponse(responseInfo, + info); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getModemActivityInfoResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setAllowedCarriersResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen); + Return retStatus + = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo, + ret); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::getAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("getAllowedCarriersResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + CarrierRestrictions carrierInfo = {}; + bool allAllowed = true; + if (response == NULL) { +#if VDBG + RLOGD("getAllowedCarriersResponse response is NULL: all allowed"); +#endif + carrierInfo.allowedCarriers.resize(0); + carrierInfo.excludedCarriers.resize(0); + } else if (responseLen != sizeof(RIL_CarrierRestrictions)) { + RLOGE("getAllowedCarriersResponse Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response; + if (pCr->len_allowed_carriers > 0 || pCr->len_excluded_carriers > 0) { + allAllowed = false; + } + + carrierInfo.allowedCarriers.resize(pCr->len_allowed_carriers); + for(int i = 0; i < pCr->len_allowed_carriers; i++) { + RIL_Carrier *carrier = pCr->allowed_carriers + i; + carrierInfo.allowedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); + carrierInfo.allowedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); + carrierInfo.allowedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; + carrierInfo.allowedCarriers[i].matchData = + convertCharPtrToHidlString(carrier->match_data); + } + + carrierInfo.excludedCarriers.resize(pCr->len_excluded_carriers); + for(int i = 0; i < pCr->len_excluded_carriers; i++) { + RIL_Carrier *carrier = pCr->excluded_carriers + i; + carrierInfo.excludedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc); + carrierInfo.excludedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc); + carrierInfo.excludedCarriers[i].matchType = (CarrierMatchType) carrier->match_type; + carrierInfo.excludedCarriers[i].matchData = + convertCharPtrToHidlString(carrier->match_data); + } + } + + Return retStatus + = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo, + allAllowed, carrierInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendDeviceStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen) { +#if VDBG + RLOGD("sendDeviceStateResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->sendDeviceStateResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("sendDeviceStateResponse: radioService[%d]->mRadioResponse == NULL", slotId); + } + + return 0; +} + +int radio::setCarrierInfoForImsiEncryptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { + RLOGD("setCarrierInfoForImsiEncryptionResponse: serial %d", serial); + if (radioService[slotId]->mRadioResponseV1_1 != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus = radioService[slotId]->mRadioResponseV1_1-> + setCarrierInfoForImsiEncryptionResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setCarrierInfoForImsiEncryptionResponse: radioService[%d]->mRadioResponseV1_1 == " + "NULL", slotId); + } + return 0; +} + +int radio::setIndicationFilterResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen) { +#if VDBG + RLOGD("setIndicationFilterResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL", + slotId); + } + + return 0; +} + +int radio::setSimCardPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("setSimCardPowerResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponse != NULL + || radioService[slotId]->mRadioResponseV1_1 != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + if (radioService[slotId]->mRadioResponseV1_1 != NULL) { + Return retStatus = radioService[slotId]->mRadioResponseV1_1-> + setSimCardPowerResponse_1_1(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGD("setSimCardPowerResponse: radioService[%d]->mRadioResponseV1_1 == NULL", + slotId); + Return retStatus + = radioService[slotId]->mRadioResponse->setSimCardPowerResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } + } else { + RLOGE("setSimCardPowerResponse: radioService[%d]->mRadioResponse == NULL && " + "radioService[%d]->mRadioResponseV1_1 == NULL", slotId, slotId); + } + return 0; +} + +int radio::startNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("startNetworkScanResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponseV1_1 != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponseV1_1->startNetworkScanResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_1 == NULL", slotId); + } + + return 0; +} + +int radio::stopNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("stopNetworkScanResponse: serial %d", serial); +#endif + + if (radioService[slotId]->mRadioResponseV1_1 != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + Return retStatus + = radioService[slotId]->mRadioResponseV1_1->stopNetworkScanResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stopNetworkScanResponse: radioService[%d]->mRadioResponseV1_1 == NULL", slotId); + } + + return 0; +} + +void convertRilKeepaliveStatusToHal(const RIL_KeepaliveStatus *rilStatus, + V1_1::KeepaliveStatus& halStatus) { + halStatus.sessionHandle = rilStatus->sessionHandle; + halStatus.code = static_cast(rilStatus->code); +} + +int radio::startKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("%s(): %d", __FUNCTION__, serial); +#endif + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + // If we don't have a radio service, there's nothing we can do + if (radioService[slotId]->mRadioResponseV1_1 == NULL) { + RLOGE("%s: radioService[%d]->mRadioResponseV1_1 == NULL", __FUNCTION__, slotId); + return 0; + } + + V1_1::KeepaliveStatus ks = {}; + if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) { + RLOGE("%s: invalid response - %d", __FUNCTION__, static_cast(e)); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + convertRilKeepaliveStatusToHal(static_cast(response), ks); + } + + Return retStatus = + radioService[slotId]->mRadioResponseV1_1->startKeepaliveResponse(responseInfo, ks); + radioService[slotId]->checkReturnStatus(retStatus); + return 0; +} + +int radio::stopKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("%s(): %d", __FUNCTION__, serial); +#endif + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + + // If we don't have a radio service, there's nothing we can do + if (radioService[slotId]->mRadioResponseV1_1 == NULL) { + RLOGE("%s: radioService[%d]->mRadioResponseV1_1 == NULL", __FUNCTION__, slotId); + return 0; + } + + Return retStatus = + radioService[slotId]->mRadioResponseV1_1->stopKeepaliveResponse(responseInfo); + radioService[slotId]->checkReturnStatus(retStatus); + return 0; +} + +int radio::sendRequestRawResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendRequestRawResponse: serial %d", serial); +#endif + + if (oemHookService[slotId]->mOemHookResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec data; + + if (response == NULL) { + RLOGE("sendRequestRawResponse: Invalid response"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + data.setToExternal((uint8_t *) response, responseLen); + } + Return retStatus = oemHookService[slotId]->mOemHookResponse-> + sendRequestRawResponse(responseInfo, data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("sendRequestRawResponse: oemHookService[%d]->mOemHookResponse == NULL", + slotId); + } + + return 0; +} + +int radio::sendRequestStringsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen) { +#if VDBG + RLOGD("sendRequestStringsResponse: serial %d", serial); +#endif + + if (oemHookService[slotId]->mOemHookResponse != NULL) { + RadioResponseInfo responseInfo = {}; + populateResponseInfo(responseInfo, serial, responseType, e); + hidl_vec data; + + if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) { + RLOGE("sendRequestStringsResponse Invalid response: NULL"); + if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE; + } else { + char **resp = (char **) response; + int numStrings = responseLen / sizeof(char *); + data.resize(numStrings); + for (int i = 0; i < numStrings; i++) { + data[i] = convertCharPtrToHidlString(resp[i]); + } + } + Return retStatus + = oemHookService[slotId]->mOemHookResponse->sendRequestStringsResponse( + responseInfo, data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("sendRequestStringsResponse: oemHookService[%d]->mOemHookResponse == " + "NULL", slotId); + } + + return 0; +} + +/*************************************************************************************************** + * INDICATION FUNCTIONS + * The below function handle unsolicited messages coming from the Radio + * (messages for which there is no pending request) + **************************************************************************************************/ + +RadioIndicationType convertIntToRadioIndicationType(int indicationType) { + return indicationType == RESPONSE_UNSOLICITED ? (RadioIndicationType::UNSOLICITED) : + (RadioIndicationType::UNSOLICITED_ACK_EXP); +} + +int radio::radioStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + RadioState radioState = + (RadioState) CALL_ONSTATEREQUEST(slotId); + RLOGD("radioStateChangedInd: radioState %d", radioState); + Return retStatus = radioService[slotId]->mRadioIndication->radioStateChanged( + convertIntToRadioIndicationType(indicationType), radioState); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("radioStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::callStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("callStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->callStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("callStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::networkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("networkStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->networkStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("networkStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +uint8_t hexCharToInt(uint8_t c) { + if (c >= '0' && c <= '9') return (c - '0'); + if (c >= 'A' && c <= 'F') return (c - 'A' + 10); + if (c >= 'a' && c <= 'f') return (c - 'a' + 10); + + return INVALID_HEX_CHAR; +} + +uint8_t * convertHexStringToBytes(void *response, size_t responseLen) { + if (responseLen % 2 != 0) { + return NULL; + } + + uint8_t *bytes = (uint8_t *)calloc(responseLen/2, sizeof(uint8_t)); + if (bytes == NULL) { + RLOGE("convertHexStringToBytes: cannot allocate memory for bytes string"); + return NULL; + } + uint8_t *hexString = (uint8_t *)response; + + for (size_t i = 0; i < responseLen; i += 2) { + uint8_t hexChar1 = hexCharToInt(hexString[i]); + uint8_t hexChar2 = hexCharToInt(hexString[i + 1]); + + if (hexChar1 == INVALID_HEX_CHAR || hexChar2 == INVALID_HEX_CHAR) { + RLOGE("convertHexStringToBytes: invalid hex char %d %d", + hexString[i], hexString[i + 1]); + free(bytes); + return NULL; + } + bytes[i/2] = ((hexChar1 << 4) | hexChar2); + } + + return bytes; +} + +int radio::newSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newSmsInd: invalid response"); + return 0; + } + + uint8_t *bytes = convertHexStringToBytes(response, responseLen); + if (bytes == NULL) { + RLOGE("newSmsInd: convertHexStringToBytes failed"); + return 0; + } + + hidl_vec pdu; + pdu.setToExternal(bytes, responseLen/2); +#if VDBG + RLOGD("newSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSms( + convertIntToRadioIndicationType(indicationType), pdu); + radioService[slotId]->checkReturnStatus(retStatus); + free(bytes); + } else { + RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newSmsStatusReportInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newSmsStatusReportInd: invalid response"); + return 0; + } + + uint8_t *bytes = convertHexStringToBytes(response, responseLen); + if (bytes == NULL) { + RLOGE("newSmsStatusReportInd: convertHexStringToBytes failed"); + return 0; + } + + hidl_vec pdu; + pdu.setToExternal(bytes, responseLen/2); +#if VDBG + RLOGD("newSmsStatusReportInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSmsStatusReport( + convertIntToRadioIndicationType(indicationType), pdu); + radioService[slotId]->checkReturnStatus(retStatus); + free(bytes); + } else { + RLOGE("newSmsStatusReportInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newSmsOnSimInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("newSmsOnSimInd: invalid response"); + return 0; + } + int32_t recordNumber = ((int32_t *) response)[0]; +#if VDBG + RLOGD("newSmsOnSimInd: slotIndex %d", recordNumber); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newSmsOnSim( + convertIntToRadioIndicationType(indicationType), recordNumber); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("newSmsOnSimInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::onUssdInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != 2 * sizeof(char *)) { + RLOGE("onUssdInd: invalid response"); + return 0; + } + char **strings = (char **) response; + char *mode = strings[0]; + hidl_string msg = convertCharPtrToHidlString(strings[1]); + UssdModeType modeType = (UssdModeType) atoi(mode); +#if VDBG + RLOGD("onUssdInd: mode %s", mode); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->onUssd( + convertIntToRadioIndicationType(indicationType), modeType, msg); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("onUssdInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::nitzTimeReceivedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("nitzTimeReceivedInd: invalid response"); + return 0; + } + hidl_string nitzTime = convertCharPtrToHidlString((char *) response); + int64_t timeReceived = android::elapsedRealtime(); +#if VDBG + RLOGD("nitzTimeReceivedInd: nitzTime %s receivedTime %" PRId64, nitzTime.c_str(), + timeReceived); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->nitzTimeReceived( + convertIntToRadioIndicationType(indicationType), nitzTime, timeReceived); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("nitzTimeReceivedInd: radioService[%d]->mRadioIndication == NULL", slotId); + return -1; + } + + return 0; +} + +void convertRilSignalStrengthToHalV8(void *response, size_t responseLen, + SignalStrength& signalStrength) { + RIL_SignalStrength_v8 *rilSignalStrength = (RIL_SignalStrength_v8 *) response; + + // Fixup LTE for backwards compatibility + // signalStrength: -1 -> 99 + if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) { + rilSignalStrength->LTE_SignalStrength.signalStrength = 99; + } + // rsrp: -1 -> INT_MAX all other negative value to positive. + // So remap here + if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX; + } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp; + } + // rsrq: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) { + rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX; + } + // Not remapping rssnr is already using INT_MAX + // cqi: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.cqi == -1) { + rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX; + } + + signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength; + signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate; + signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm; + signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio; + signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm; + signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio; + signalStrength.evdo.signalNoiseRatio = + rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio; + signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength; + signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp; + signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq; + signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr; + signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi; + signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance; + signalStrength.tdScdma.rscp = INT_MAX; +} + +void convertRilSignalStrengthToHalV10(void *response, size_t responseLen, + SignalStrength& signalStrength) { + RIL_SignalStrength_v10 *rilSignalStrength = (RIL_SignalStrength_v10 *) response; + + // Fixup LTE for backwards compatibility + // signalStrength: -1 -> 99 + if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) { + rilSignalStrength->LTE_SignalStrength.signalStrength = 99; + } + // rsrp: -1 -> INT_MAX all other negative value to positive. + // So remap here + if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX; + } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) { + rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp; + } + // rsrq: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) { + rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX; + } + // Not remapping rssnr is already using INT_MAX + // cqi: -1 -> INT_MAX + if (rilSignalStrength->LTE_SignalStrength.cqi == -1) { + rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX; + } + + signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength; + signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate; + signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm; + signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio; + signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm; + signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio; + signalStrength.evdo.signalNoiseRatio = + rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio; + signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength; + signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp; + signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq; + signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr; + signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi; + signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance; + signalStrength.tdScdma.rscp = rilSignalStrength->TD_SCDMA_SignalStrength.rscp; +} + +void convertRilSignalStrengthToHal(void *response, size_t responseLen, + SignalStrength& signalStrength) { + if (responseLen == sizeof(RIL_SignalStrength_v8)) { + convertRilSignalStrengthToHalV8(response, responseLen, signalStrength); + } else { + convertRilSignalStrengthToHalV10(response, responseLen, signalStrength); + } +} + +int radio::currentSignalStrengthInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || (responseLen != sizeof(RIL_SignalStrength_v10) + && responseLen != sizeof(RIL_SignalStrength_v8))) { + RLOGE("currentSignalStrengthInd: invalid response"); + return 0; + } + + SignalStrength signalStrength = {}; + convertRilSignalStrengthToHal(response, responseLen, signalStrength); + +#if VDBG + RLOGD("currentSignalStrengthInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->currentSignalStrength( + convertIntToRadioIndicationType(indicationType), signalStrength); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("currentSignalStrengthInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v6 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = hidl_string(); + dcResult.mtu = 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v9 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf); + dcResult.mtu = 0; +} + +void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse, + SetupDataCallResult& dcResult) { + dcResult.status = (DataCallFailCause) dcResponse->status; + dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime; + dcResult.cid = dcResponse->cid; + dcResult.active = dcResponse->active; + dcResult.type = convertCharPtrToHidlString(dcResponse->type); + dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname); + dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses); + dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses); + dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways); + dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf); + dcResult.mtu = dcResponse->mtu; +} + +void convertRilDataCallListToHal(void *response, size_t responseLen, + hidl_vec& dcResultList) { + int num; + + if ((responseLen % sizeof(RIL_Data_Call_Response_v11)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v11); + RIL_Data_Call_Response_v11 *dcResponse = (RIL_Data_Call_Response_v11 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v9)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v9); + RIL_Data_Call_Response_v9 *dcResponse = (RIL_Data_Call_Response_v9 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } else if ((responseLen % sizeof(RIL_Data_Call_Response_v6)) == 0) { + num = responseLen / sizeof(RIL_Data_Call_Response_v6); + RIL_Data_Call_Response_v6 *dcResponse = (RIL_Data_Call_Response_v6 *) response; + dcResultList.resize(num); + for (int i = 0; i < num; i++) { + convertRilDataCallToHal(&dcResponse[i], dcResultList[i]); + } + } +} + +int radio::dataCallListChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) + || (responseLen % sizeof(RIL_Data_Call_Response_v11) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v9) != 0 + && responseLen % sizeof(RIL_Data_Call_Response_v6) != 0)) { + RLOGE("dataCallListChangedInd: invalid response"); + return 0; + } + hidl_vec dcList; + convertRilDataCallListToHal(response, responseLen, dcList); +#if VDBG + RLOGD("dataCallListChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->dataCallListChanged( + convertIntToRadioIndicationType(indicationType), dcList); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("dataCallListChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::suppSvcNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_SuppSvcNotification)) { + RLOGE("suppSvcNotifyInd: invalid response"); + return 0; + } + + SuppSvcNotification suppSvc = {}; + RIL_SuppSvcNotification *ssn = (RIL_SuppSvcNotification *) response; + suppSvc.isMT = ssn->notificationType; + suppSvc.code = ssn->code; + suppSvc.index = ssn->index; + suppSvc.type = ssn->type; + suppSvc.number = convertCharPtrToHidlString(ssn->number); + +#if VDBG + RLOGD("suppSvcNotifyInd: isMT %d code %d index %d type %d", + suppSvc.isMT, suppSvc.code, suppSvc.index, suppSvc.type); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->suppSvcNotify( + convertIntToRadioIndicationType(indicationType), suppSvc); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("suppSvcNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkSessionEndInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("stkSessionEndInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkSessionEnd( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkSessionEndInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkProactiveCommandInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkProactiveCommandInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkProactiveCommandInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkProactiveCommand( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkProactiveCommandInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkEventNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkEventNotifyInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkEventNotifyInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkEventNotify( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkEventNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkCallSetupInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("stkCallSetupInd: invalid response"); + return 0; + } + int32_t timeout = ((int32_t *) response)[0]; +#if VDBG + RLOGD("stkCallSetupInd: timeout %d", timeout); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkCallSetup( + convertIntToRadioIndicationType(indicationType), timeout); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkCallSetupInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("simSmsStorageFullInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simSmsStorageFull( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simRefreshInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_SimRefreshResponse_v7)) { + RLOGE("simRefreshInd: invalid response"); + return 0; + } + + SimRefreshResult refreshResult = {}; + RIL_SimRefreshResponse_v7 *simRefreshResponse = ((RIL_SimRefreshResponse_v7 *) response); + refreshResult.type = + (V1_0::SimRefreshType) simRefreshResponse->result; + refreshResult.efId = simRefreshResponse->ef_id; + refreshResult.aid = convertCharPtrToHidlString(simRefreshResponse->aid); + +#if VDBG + RLOGD("simRefreshInd: type %d efId %d", refreshResult.type, refreshResult.efId); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simRefresh( + convertIntToRadioIndicationType(indicationType), refreshResult); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simRefreshInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +void convertRilCdmaSignalInfoRecordToHal(RIL_CDMA_SignalInfoRecord *signalInfoRecord, + CdmaSignalInfoRecord& record) { + record.isPresent = signalInfoRecord->isPresent; + record.signalType = signalInfoRecord->signalType; + record.alertPitch = signalInfoRecord->alertPitch; + record.signal = signalInfoRecord->signal; +} + +int radio::callRingInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + bool isGsm; + CdmaSignalInfoRecord record = {}; + if (response == NULL || responseLen == 0) { + isGsm = true; + } else { + isGsm = false; + if (responseLen != sizeof (RIL_CDMA_SignalInfoRecord)) { + RLOGE("callRingInd: invalid response"); + return 0; + } + convertRilCdmaSignalInfoRecordToHal((RIL_CDMA_SignalInfoRecord *) response, record); + } + +#if VDBG + RLOGD("callRingInd: isGsm %d", isGsm); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->callRing( + convertIntToRadioIndicationType(indicationType), isGsm, record); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("callRingInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::simStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("simStatusChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->simStatusChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("simStatusChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaNewSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_SMS_Message)) { + RLOGE("cdmaNewSmsInd: invalid response"); + return 0; + } + + CdmaSmsMessage msg = {}; + RIL_CDMA_SMS_Message *rilMsg = (RIL_CDMA_SMS_Message *) response; + msg.teleserviceId = rilMsg->uTeleserviceID; + msg.isServicePresent = rilMsg->bIsServicePresent; + msg.serviceCategory = rilMsg->uServicecategory; + msg.address.digitMode = + (V1_0::CdmaSmsDigitMode) rilMsg->sAddress.digit_mode; + msg.address.numberMode = + (V1_0::CdmaSmsNumberMode) rilMsg->sAddress.number_mode; + msg.address.numberType = + (V1_0::CdmaSmsNumberType) rilMsg->sAddress.number_type; + msg.address.numberPlan = + (V1_0::CdmaSmsNumberPlan) rilMsg->sAddress.number_plan; + + int digitLimit = MIN((rilMsg->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX); + msg.address.digits.setToExternal(rilMsg->sAddress.digits, digitLimit); + + msg.subAddress.subaddressType = (V1_0::CdmaSmsSubaddressType) + rilMsg->sSubAddress.subaddressType; + msg.subAddress.odd = rilMsg->sSubAddress.odd; + + digitLimit= MIN((rilMsg->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX); + msg.subAddress.digits.setToExternal(rilMsg->sSubAddress.digits, digitLimit); + + digitLimit = MIN((rilMsg->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX); + msg.bearerData.setToExternal(rilMsg->aBearerData, digitLimit); + +#if VDBG + RLOGD("cdmaNewSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaNewSms( + convertIntToRadioIndicationType(indicationType), msg); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaNewSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::newBroadcastSmsInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("newBroadcastSmsInd: invalid response"); + return 0; + } + + hidl_vec data; + data.setToExternal((uint8_t *) response, responseLen); +#if VDBG + RLOGD("newBroadcastSmsInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->newBroadcastSms( + convertIntToRadioIndicationType(indicationType), data); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("newBroadcastSmsInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaRuimSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("cdmaRuimSmsStorageFullInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaRuimSmsStorageFull( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaRuimSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::restrictedStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("restrictedStateChangedInd: invalid response"); + return 0; + } + int32_t state = ((int32_t *) response)[0]; +#if VDBG + RLOGD("restrictedStateChangedInd: state %d", state); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->restrictedStateChanged( + convertIntToRadioIndicationType(indicationType), (PhoneRestrictedState) state); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("restrictedStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::enterEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("enterEmergencyCallbackModeInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->enterEmergencyCallbackMode( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("enterEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaCallWaitingInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_CallWaiting_v6)) { + RLOGE("cdmaCallWaitingInd: invalid response"); + return 0; + } + + CdmaCallWaiting callWaitingRecord = {}; + RIL_CDMA_CallWaiting_v6 *callWaitingRil = ((RIL_CDMA_CallWaiting_v6 *) response); + callWaitingRecord.number = convertCharPtrToHidlString(callWaitingRil->number); + callWaitingRecord.numberPresentation = + (CdmaCallWaitingNumberPresentation) callWaitingRil->numberPresentation; + callWaitingRecord.name = convertCharPtrToHidlString(callWaitingRil->name); + convertRilCdmaSignalInfoRecordToHal(&callWaitingRil->signalInfoRecord, + callWaitingRecord.signalInfoRecord); + callWaitingRecord.numberType = (CdmaCallWaitingNumberType) callWaitingRil->number_type; + callWaitingRecord.numberPlan = (CdmaCallWaitingNumberPlan) callWaitingRil->number_plan; + +#if VDBG + RLOGD("cdmaCallWaitingInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaCallWaiting( + convertIntToRadioIndicationType(indicationType), callWaitingRecord); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaCallWaitingInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaOtaProvisionStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaOtaProvisionStatusInd: invalid response"); + return 0; + } + int32_t status = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaOtaProvisionStatusInd: status %d", status); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaOtaProvisionStatus( + convertIntToRadioIndicationType(indicationType), (CdmaOtaProvisionStatus) status); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaOtaProvisionStatusInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaInfoRecInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_CDMA_InformationRecords)) { + RLOGE("cdmaInfoRecInd: invalid response"); + return 0; + } + + CdmaInformationRecords records = {}; + RIL_CDMA_InformationRecords *recordsRil = (RIL_CDMA_InformationRecords *) response; + + char* string8 = NULL; + int num = MIN(recordsRil->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); + if (recordsRil->numberOfInfoRecs > RIL_CDMA_MAX_NUMBER_OF_INFO_RECS) { + RLOGE("cdmaInfoRecInd: received %d recs which is more than %d, dropping " + "additional ones", recordsRil->numberOfInfoRecs, + RIL_CDMA_MAX_NUMBER_OF_INFO_RECS); + } + records.infoRec.resize(num); + for (int i = 0 ; i < num ; i++) { + CdmaInformationRecord *record = &records.infoRec[i]; + RIL_CDMA_InformationRecord *infoRec = &recordsRil->infoRec[i]; + record->name = (CdmaInfoRecName) infoRec->name; + // All vectors should be size 0 except one which will be size 1. Set everything to + // size 0 initially. + record->display.resize(0); + record->number.resize(0); + record->signal.resize(0); + record->redir.resize(0); + record->lineCtrl.resize(0); + record->clir.resize(0); + record->audioCtrl.resize(0); + switch (infoRec->name) { + case RIL_CDMA_DISPLAY_INFO_REC: + case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: { + if (infoRec->rec.display.alpha_len > CDMA_ALPHA_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d", (int) infoRec->rec.display.alpha_len, + CDMA_ALPHA_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1) * sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.display.alpha_buf, infoRec->rec.display.alpha_len); + string8[(int)infoRec->rec.display.alpha_len] = '\0'; + + record->display.resize(1); + record->display[0].alphaBuf = string8; + free(string8); + string8 = NULL; + break; + } + + case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC: + case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC: + case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: { + if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d", (int) infoRec->rec.number.len, + CDMA_NUMBER_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.number.len + 1) * sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.number.buf, infoRec->rec.number.len); + string8[(int)infoRec->rec.number.len] = '\0'; + + record->number.resize(1); + record->number[0].number = string8; + free(string8); + string8 = NULL; + record->number[0].numberType = infoRec->rec.number.number_type; + record->number[0].numberPlan = infoRec->rec.number.number_plan; + record->number[0].pi = infoRec->rec.number.pi; + record->number[0].si = infoRec->rec.number.si; + break; + } + + case RIL_CDMA_SIGNAL_INFO_REC: { + record->signal.resize(1); + record->signal[0].isPresent = infoRec->rec.signal.isPresent; + record->signal[0].signalType = infoRec->rec.signal.signalType; + record->signal[0].alertPitch = infoRec->rec.signal.alertPitch; + record->signal[0].signal = infoRec->rec.signal.signal; + break; + } + + case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: { + if (infoRec->rec.redir.redirectingNumber.len > + CDMA_NUMBER_INFO_BUFFER_LENGTH) { + RLOGE("cdmaInfoRecInd: invalid display info response length %d " + "expected not more than %d\n", + (int)infoRec->rec.redir.redirectingNumber.len, + CDMA_NUMBER_INFO_BUFFER_LENGTH); + return 0; + } + string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber.len + 1) * + sizeof(char)); + if (string8 == NULL) { + RLOGE("cdmaInfoRecInd: Memory allocation failed for " + "responseCdmaInformationRecords"); + return 0; + } + memcpy(string8, infoRec->rec.redir.redirectingNumber.buf, + infoRec->rec.redir.redirectingNumber.len); + string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0'; + + record->redir.resize(1); + record->redir[0].redirectingNumber.number = string8; + free(string8); + string8 = NULL; + record->redir[0].redirectingNumber.numberType = + infoRec->rec.redir.redirectingNumber.number_type; + record->redir[0].redirectingNumber.numberPlan = + infoRec->rec.redir.redirectingNumber.number_plan; + record->redir[0].redirectingNumber.pi = infoRec->rec.redir.redirectingNumber.pi; + record->redir[0].redirectingNumber.si = infoRec->rec.redir.redirectingNumber.si; + record->redir[0].redirectingReason = + (CdmaRedirectingReason) infoRec->rec.redir.redirectingReason; + break; + } + + case RIL_CDMA_LINE_CONTROL_INFO_REC: { + record->lineCtrl.resize(1); + record->lineCtrl[0].lineCtrlPolarityIncluded = + infoRec->rec.lineCtrl.lineCtrlPolarityIncluded; + record->lineCtrl[0].lineCtrlToggle = infoRec->rec.lineCtrl.lineCtrlToggle; + record->lineCtrl[0].lineCtrlReverse = infoRec->rec.lineCtrl.lineCtrlReverse; + record->lineCtrl[0].lineCtrlPowerDenial = + infoRec->rec.lineCtrl.lineCtrlPowerDenial; + break; + } + + case RIL_CDMA_T53_CLIR_INFO_REC: { + record->clir.resize(1); + record->clir[0].cause = infoRec->rec.clir.cause; + break; + } + + case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: { + record->audioCtrl.resize(1); + record->audioCtrl[0].upLink = infoRec->rec.audioCtrl.upLink; + record->audioCtrl[0].downLink = infoRec->rec.audioCtrl.downLink; + break; + } + + case RIL_CDMA_T53_RELEASE_INFO_REC: + RLOGE("cdmaInfoRecInd: RIL_CDMA_T53_RELEASE_INFO_REC: INVALID"); + return 0; + + default: + RLOGE("cdmaInfoRecInd: Incorrect name value"); + return 0; + } + } + +#if VDBG + RLOGD("cdmaInfoRecInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaInfoRec( + convertIntToRadioIndicationType(indicationType), records); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaInfoRecInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::indicateRingbackToneInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("indicateRingbackToneInd: invalid response"); + return 0; + } + bool start = ((int32_t *) response)[0]; +#if VDBG + RLOGD("indicateRingbackToneInd: start %d", start); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->indicateRingbackTone( + convertIntToRadioIndicationType(indicationType), start); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("indicateRingbackToneInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::resendIncallMuteInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("resendIncallMuteInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->resendIncallMute( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("resendIncallMuteInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::cdmaSubscriptionSourceChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaSubscriptionSourceChangedInd: invalid response"); + return 0; + } + int32_t cdmaSource = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaSubscriptionSourceChangedInd: cdmaSource %d", cdmaSource); +#endif + Return retStatus = radioService[slotId]->mRadioIndication-> + cdmaSubscriptionSourceChanged(convertIntToRadioIndicationType(indicationType), + (CdmaSubscriptionSource) cdmaSource); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaSubscriptionSourceChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::cdmaPrlChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("cdmaPrlChangedInd: invalid response"); + return 0; + } + int32_t version = ((int32_t *) response)[0]; +#if VDBG + RLOGD("cdmaPrlChangedInd: version %d", version); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cdmaPrlChanged( + convertIntToRadioIndicationType(indicationType), version); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cdmaPrlChangedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::exitEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("exitEmergencyCallbackModeInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->exitEmergencyCallbackMode( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("exitEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::rilConnectedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + RLOGD("rilConnectedInd"); + Return retStatus = radioService[slotId]->mRadioIndication->rilConnected( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("rilConnectedInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::voiceRadioTechChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("voiceRadioTechChangedInd: invalid response"); + return 0; + } + int32_t rat = ((int32_t *) response)[0]; +#if VDBG + RLOGD("voiceRadioTechChangedInd: rat %d", rat); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->voiceRadioTechChanged( + convertIntToRadioIndicationType(indicationType), (RadioTechnology) rat); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("voiceRadioTechChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec& records) { + int num = responseLen / sizeof(RIL_CellInfo_v12); + records.resize(num); + + RIL_CellInfo_v12 *rillCellInfo = (RIL_CellInfo_v12 *) response; + for (int i = 0; i < num; i++) { + records[i].cellInfoType = (CellInfoType) rillCellInfo->cellInfoType; + records[i].registered = rillCellInfo->registered; + records[i].timeStampType = (TimeStampType) rillCellInfo->timeStampType; + records[i].timeStamp = rillCellInfo->timeStamp; + // All vectors should be size 0 except one which will be size 1. Set everything to + // size 0 initially. + records[i].gsm.resize(0); + records[i].wcdma.resize(0); + records[i].cdma.resize(0); + records[i].lte.resize(0); + records[i].tdscdma.resize(0); + switch(rillCellInfo->cellInfoType) { + case RIL_CELL_INFO_TYPE_GSM: { + records[i].gsm.resize(1); + CellInfoGsm *cellInfoGsm = &records[i].gsm[0]; + cellInfoGsm->cellIdentityGsm.mcc = + std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc); + cellInfoGsm->cellIdentityGsm.mnc = + std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc); + cellInfoGsm->cellIdentityGsm.lac = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac; + cellInfoGsm->cellIdentityGsm.cid = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.cid; + cellInfoGsm->cellIdentityGsm.arfcn = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.arfcn; + cellInfoGsm->cellIdentityGsm.bsic = + rillCellInfo->CellInfo.gsm.cellIdentityGsm.bsic; + cellInfoGsm->signalStrengthGsm.signalStrength = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.signalStrength; + cellInfoGsm->signalStrengthGsm.bitErrorRate = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.bitErrorRate; + cellInfoGsm->signalStrengthGsm.timingAdvance = + rillCellInfo->CellInfo.gsm.signalStrengthGsm.timingAdvance; + break; + } + + case RIL_CELL_INFO_TYPE_WCDMA: { + records[i].wcdma.resize(1); + CellInfoWcdma *cellInfoWcdma = &records[i].wcdma[0]; + cellInfoWcdma->cellIdentityWcdma.mcc = + std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc); + cellInfoWcdma->cellIdentityWcdma.mnc = + std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc); + cellInfoWcdma->cellIdentityWcdma.lac = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac; + cellInfoWcdma->cellIdentityWcdma.cid = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.cid; + cellInfoWcdma->cellIdentityWcdma.psc = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.psc; + cellInfoWcdma->cellIdentityWcdma.uarfcn = + rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.uarfcn; + cellInfoWcdma->signalStrengthWcdma.signalStrength = + rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.signalStrength; + cellInfoWcdma->signalStrengthWcdma.bitErrorRate = + rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate; + break; + } + + case RIL_CELL_INFO_TYPE_CDMA: { + records[i].cdma.resize(1); + CellInfoCdma *cellInfoCdma = &records[i].cdma[0]; + cellInfoCdma->cellIdentityCdma.networkId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.networkId; + cellInfoCdma->cellIdentityCdma.systemId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.systemId; + cellInfoCdma->cellIdentityCdma.baseStationId = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.basestationId; + cellInfoCdma->cellIdentityCdma.longitude = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.longitude; + cellInfoCdma->cellIdentityCdma.latitude = + rillCellInfo->CellInfo.cdma.cellIdentityCdma.latitude; + cellInfoCdma->signalStrengthCdma.dbm = + rillCellInfo->CellInfo.cdma.signalStrengthCdma.dbm; + cellInfoCdma->signalStrengthCdma.ecio = + rillCellInfo->CellInfo.cdma.signalStrengthCdma.ecio; + cellInfoCdma->signalStrengthEvdo.dbm = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.dbm; + cellInfoCdma->signalStrengthEvdo.ecio = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.ecio; + cellInfoCdma->signalStrengthEvdo.signalNoiseRatio = + rillCellInfo->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio; + break; + } + + case RIL_CELL_INFO_TYPE_LTE: { + records[i].lte.resize(1); + CellInfoLte *cellInfoLte = &records[i].lte[0]; + cellInfoLte->cellIdentityLte.mcc = + std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc); + cellInfoLte->cellIdentityLte.mnc = + std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc); + cellInfoLte->cellIdentityLte.ci = + rillCellInfo->CellInfo.lte.cellIdentityLte.ci; + cellInfoLte->cellIdentityLte.pci = + rillCellInfo->CellInfo.lte.cellIdentityLte.pci; + cellInfoLte->cellIdentityLte.tac = + rillCellInfo->CellInfo.lte.cellIdentityLte.tac; + cellInfoLte->cellIdentityLte.earfcn = + rillCellInfo->CellInfo.lte.cellIdentityLte.earfcn; + cellInfoLte->signalStrengthLte.signalStrength = + rillCellInfo->CellInfo.lte.signalStrengthLte.signalStrength; + cellInfoLte->signalStrengthLte.rsrp = + rillCellInfo->CellInfo.lte.signalStrengthLte.rsrp; + cellInfoLte->signalStrengthLte.rsrq = + rillCellInfo->CellInfo.lte.signalStrengthLte.rsrq; + cellInfoLte->signalStrengthLte.rssnr = + rillCellInfo->CellInfo.lte.signalStrengthLte.rssnr; + cellInfoLte->signalStrengthLte.cqi = + rillCellInfo->CellInfo.lte.signalStrengthLte.cqi; + cellInfoLte->signalStrengthLte.timingAdvance = + rillCellInfo->CellInfo.lte.signalStrengthLte.timingAdvance; + break; + } + + case RIL_CELL_INFO_TYPE_TD_SCDMA: { + records[i].tdscdma.resize(1); + CellInfoTdscdma *cellInfoTdscdma = &records[i].tdscdma[0]; + cellInfoTdscdma->cellIdentityTdscdma.mcc = + std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc); + cellInfoTdscdma->cellIdentityTdscdma.mnc = + std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc); + cellInfoTdscdma->cellIdentityTdscdma.lac = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac; + cellInfoTdscdma->cellIdentityTdscdma.cid = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cid; + cellInfoTdscdma->cellIdentityTdscdma.cpid = + rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cpid; + cellInfoTdscdma->signalStrengthTdscdma.rscp = + rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp; + break; + } + default: { + break; + } + } + rillCellInfo += 1; + } +} + +int radio::cellInfoListInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) { + RLOGE("cellInfoListInd: invalid response"); + return 0; + } + + hidl_vec records; + convertRilCellInfoListToHal(response, responseLen, records); + +#if VDBG + RLOGD("cellInfoListInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->cellInfoList( + convertIntToRadioIndicationType(indicationType), records); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("cellInfoListInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::imsNetworkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { +#if VDBG + RLOGD("imsNetworkStateChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->imsNetworkStateChanged( + convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("imsNetworkStateChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::subscriptionStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("subscriptionStatusChangedInd: invalid response"); + return 0; + } + bool activate = ((int32_t *) response)[0]; +#if VDBG + RLOGD("subscriptionStatusChangedInd: activate %d", activate); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->subscriptionStatusChanged( + convertIntToRadioIndicationType(indicationType), activate); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("subscriptionStatusChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +int radio::srvccStateNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(int)) { + RLOGE("srvccStateNotifyInd: invalid response"); + return 0; + } + int32_t state = ((int32_t *) response)[0]; +#if VDBG + RLOGD("srvccStateNotifyInd: rat %d", state); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->srvccStateNotify( + convertIntToRadioIndicationType(indicationType), (SrvccState) state); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("srvccStateNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +void convertRilHardwareConfigListToHal(void *response, size_t responseLen, + hidl_vec& records) { + int num = responseLen / sizeof(RIL_HardwareConfig); + records.resize(num); + + RIL_HardwareConfig *rilHardwareConfig = (RIL_HardwareConfig *) response; + for (int i = 0; i < num; i++) { + records[i].type = (HardwareConfigType) rilHardwareConfig[i].type; + records[i].uuid = convertCharPtrToHidlString(rilHardwareConfig[i].uuid); + records[i].state = (HardwareConfigState) rilHardwareConfig[i].state; + switch (rilHardwareConfig[i].type) { + case RIL_HARDWARE_CONFIG_MODEM: { + records[i].modem.resize(1); + records[i].sim.resize(0); + HardwareConfigModem *hwConfigModem = &records[i].modem[0]; + hwConfigModem->rat = rilHardwareConfig[i].cfg.modem.rat; + hwConfigModem->maxVoice = rilHardwareConfig[i].cfg.modem.maxVoice; + hwConfigModem->maxData = rilHardwareConfig[i].cfg.modem.maxData; + hwConfigModem->maxStandby = rilHardwareConfig[i].cfg.modem.maxStandby; + break; + } + + case RIL_HARDWARE_CONFIG_SIM: { + records[i].sim.resize(1); + records[i].modem.resize(0); + records[i].sim[0].modemUuid = + convertCharPtrToHidlString(rilHardwareConfig[i].cfg.sim.modemUuid); + break; + } + } + } +} + +int radio::hardwareConfigChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if ((response == NULL && responseLen != 0) + || responseLen % sizeof(RIL_HardwareConfig) != 0) { + RLOGE("hardwareConfigChangedInd: invalid response"); + return 0; + } + + hidl_vec configs; + convertRilHardwareConfigListToHal(response, responseLen, configs); + +#if VDBG + RLOGD("hardwareConfigChangedInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->hardwareConfigChanged( + convertIntToRadioIndicationType(indicationType), configs); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("hardwareConfigChangedInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc) { + RIL_RadioCapability *rilRadioCapability = (RIL_RadioCapability *) response; + rc.session = rilRadioCapability->session; + rc.phase = (V1_0::RadioCapabilityPhase) rilRadioCapability->phase; + rc.raf = rilRadioCapability->rat; + rc.logicalModemUuid = convertCharPtrToHidlString(rilRadioCapability->logicalModemUuid); + rc.status = (V1_0::RadioCapabilityStatus) rilRadioCapability->status; +} + +int radio::radioCapabilityIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) { + RLOGE("radioCapabilityIndicationInd: invalid response"); + return 0; + } + + RadioCapability rc = {}; + convertRilRadioCapabilityToHal(response, responseLen, rc); + +#if VDBG + RLOGD("radioCapabilityIndicationInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->radioCapabilityIndication( + convertIntToRadioIndicationType(indicationType), rc); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("radioCapabilityIndicationInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) { + if ((reqType == SS_INTERROGATION) && + (serType == SS_CFU || + serType == SS_CF_BUSY || + serType == SS_CF_NO_REPLY || + serType == SS_CF_NOT_REACHABLE || + serType == SS_CF_ALL || + serType == SS_CF_ALL_CONDITIONAL)) { + return true; + } + return false; +} + +int radio::onSupplementaryServiceIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_StkCcUnsolSsResponse)) { + RLOGE("onSupplementaryServiceIndicationInd: invalid response"); + return 0; + } + + RIL_StkCcUnsolSsResponse *rilSsResponse = (RIL_StkCcUnsolSsResponse *) response; + StkCcUnsolSsResult ss = {}; + ss.serviceType = (SsServiceType) rilSsResponse->serviceType; + ss.requestType = (SsRequestType) rilSsResponse->requestType; + ss.teleserviceType = (SsTeleserviceType) rilSsResponse->teleserviceType; + ss.serviceClass = rilSsResponse->serviceClass; + ss.result = (RadioError) rilSsResponse->result; + + if (isServiceTypeCfQuery(rilSsResponse->serviceType, rilSsResponse->requestType)) { +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd CF type, num of Cf elements %d", + rilSsResponse->cfData.numValidIndexes); +#endif + if (rilSsResponse->cfData.numValidIndexes > NUM_SERVICE_CLASSES) { + RLOGE("onSupplementaryServiceIndicationInd numValidIndexes is greater than " + "max value %d, truncating it to max value", NUM_SERVICE_CLASSES); + rilSsResponse->cfData.numValidIndexes = NUM_SERVICE_CLASSES; + } + + ss.cfData.resize(1); + ss.ssInfo.resize(0); + + /* number of call info's */ + ss.cfData[0].cfInfo.resize(rilSsResponse->cfData.numValidIndexes); + + for (int i = 0; i < rilSsResponse->cfData.numValidIndexes; i++) { + RIL_CallForwardInfo cf = rilSsResponse->cfData.cfInfo[i]; + CallForwardInfo *cfInfo = &ss.cfData[0].cfInfo[i]; + + cfInfo->status = (CallForwardInfoStatus) cf.status; + cfInfo->reason = cf.reason; + cfInfo->serviceClass = cf.serviceClass; + cfInfo->toa = cf.toa; + cfInfo->number = convertCharPtrToHidlString(cf.number); + cfInfo->timeSeconds = cf.timeSeconds; +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd: " + "Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status, + cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds); +#endif + } + } else { + ss.ssInfo.resize(1); + ss.cfData.resize(0); + + /* each int */ + ss.ssInfo[0].ssInfo.resize(SS_INFO_MAX); + for (int i = 0; i < SS_INFO_MAX; i++) { +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd: Data: %d", + rilSsResponse->ssInfo[i]); +#endif + ss.ssInfo[0].ssInfo[i] = rilSsResponse->ssInfo[i]; + } + } + +#if VDBG + RLOGD("onSupplementaryServiceIndicationInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication-> + onSupplementaryServiceIndication(convertIntToRadioIndicationType(indicationType), + ss); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("onSupplementaryServiceIndicationInd: " + "radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::stkCallControlAlphaNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("stkCallControlAlphaNotifyInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("stkCallControlAlphaNotifyInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->stkCallControlAlphaNotify( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("stkCallControlAlphaNotifyInd: radioService[%d]->mRadioIndication == NULL", + slotId); + } + + return 0; +} + +void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce) { + RIL_LceDataInfo *rilLceDataInfo = (RIL_LceDataInfo *)response; + lce.lastHopCapacityKbps = rilLceDataInfo->last_hop_capacity_kbps; + lce.confidenceLevel = rilLceDataInfo->confidence_level; + lce.lceSuspended = rilLceDataInfo->lce_suspended; +} + +int radio::lceDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) { + RLOGE("lceDataInd: invalid response"); + return 0; + } + + LceDataInfo lce = {}; + convertRilLceDataInfoToHal(response, responseLen, lce); +#if VDBG + RLOGD("lceDataInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->lceData( + convertIntToRadioIndicationType(indicationType), lce); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("lceDataInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::pcoDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen != sizeof(RIL_PCO_Data)) { + RLOGE("pcoDataInd: invalid response"); + return 0; + } + + PcoDataInfo pco = {}; + RIL_PCO_Data *rilPcoData = (RIL_PCO_Data *)response; + pco.cid = rilPcoData->cid; + pco.bearerProto = convertCharPtrToHidlString(rilPcoData->bearer_proto); + pco.pcoId = rilPcoData->pco_id; + pco.contents.setToExternal((uint8_t *) rilPcoData->contents, rilPcoData->contents_length); + +#if VDBG + RLOGD("pcoDataInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->pcoData( + convertIntToRadioIndicationType(indicationType), pco); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("pcoDataInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::modemResetInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("modemResetInd: invalid response"); + return 0; + } +#if VDBG + RLOGD("modemResetInd"); +#endif + Return retStatus = radioService[slotId]->mRadioIndication->modemReset( + convertIntToRadioIndicationType(indicationType), + convertCharPtrToHidlString((char *) response)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("modemResetInd: radioService[%d]->mRadioIndication == NULL", slotId); + } + + return 0; +} + +int radio::networkScanResultInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("networkScanResultInd"); +#endif + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_1 != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("networkScanResultInd: invalid response"); + return 0; + } + RLOGD("networkScanResultInd"); + +#if VDBG + RLOGD("networkScanResultInd"); +#endif + + RIL_NetworkScanResult *networkScanResult = (RIL_NetworkScanResult *) response; + + V1_1::NetworkScanResult result; + result.status = (V1_1::ScanStatus) networkScanResult->status; + result.error = (RadioError) e; + convertRilCellInfoListToHal( + networkScanResult->network_infos, + networkScanResult->network_infos_length * sizeof(RIL_CellInfo_v12), + result.networkInfos); + + Return retStatus = radioService[slotId]->mRadioIndicationV1_1->networkScanResult( + convertIntToRadioIndicationType(indicationType), result); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("networkScanResultInd: radioService[%d]->mRadioIndicationV1_1 == NULL", slotId); + } + return 0; +} + +int radio::carrierInfoForImsiEncryption(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_1 != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("carrierInfoForImsiEncryption: invalid response"); + return 0; + } + RLOGD("carrierInfoForImsiEncryption"); + Return retStatus = radioService[slotId]->mRadioIndicationV1_1-> + carrierInfoForImsiEncryption(convertIntToRadioIndicationType(indicationType)); + radioService[slotId]->checkReturnStatus(retStatus); + } else { + RLOGE("carrierInfoForImsiEncryption: radioService[%d]->mRadioIndicationV1_1 == NULL", + slotId); + } + + return 0; +} + +int radio::keepaliveStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { +#if VDBG + RLOGD("%s(): token=%d", __FUNCTION__, token); +#endif + if (radioService[slotId] == NULL || radioService[slotId]->mRadioIndication == NULL) { + RLOGE("%s: radioService[%d]->mRadioIndication == NULL", __FUNCTION__, slotId); + return 0; + } + + auto ret = V1_1::IRadioIndication::castFrom( + radioService[slotId]->mRadioIndication); + if (!ret.isOk()) { + RLOGE("%s: ret.isOk() == false for radioService[%d]", __FUNCTION__, slotId); + return 0; + } + sp radioIndicationV1_1 = ret; + + if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) { + RLOGE("%s: invalid response", __FUNCTION__); + return 0; + } + + V1_1::KeepaliveStatus ks; + convertRilKeepaliveStatusToHal(static_cast(response), ks); + + Return retStatus = radioIndicationV1_1->keepaliveStatus( + convertIntToRadioIndicationType(indicationType), ks); + radioService[slotId]->checkReturnStatus(retStatus); + return 0; +} + +int radio::oemHookRawInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen) { + if (oemHookService[slotId] != NULL && oemHookService[slotId]->mOemHookIndication != NULL) { + if (response == NULL || responseLen == 0) { + RLOGE("oemHookRawInd: invalid response"); + return 0; + } + + hidl_vec data; + data.setToExternal((uint8_t *) response, responseLen); +#if VDBG + RLOGD("oemHookRawInd"); +#endif + Return retStatus = oemHookService[slotId]->mOemHookIndication->oemHookRaw( + convertIntToRadioIndicationType(indicationType), data); + checkReturnStatus(slotId, retStatus, false); + } else { + RLOGE("oemHookRawInd: oemHookService[%d]->mOemHookIndication == NULL", slotId); + } + + return 0; +} + +void radio::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) { + using namespace android::hardware; + int simCount = 1; + const char *serviceNames[] = { + android::RIL_getServiceName() + #if (SIM_COUNT >= 2) + , RIL2_SERVICE_NAME + #if (SIM_COUNT >= 3) + , RIL3_SERVICE_NAME + #if (SIM_COUNT >= 4) + , RIL4_SERVICE_NAME + #endif + #endif + #endif + }; + + #if (SIM_COUNT >= 2) + simCount = SIM_COUNT; + #endif + + configureRpcThreadpool(1, true /* callerWillJoin */); + for (int i = 0; i < simCount; i++) { + pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i); + int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr); + assert(ret == 0); + + radioService[i] = new RadioImpl; + radioService[i]->mSlotId = i; + oemHookService[i] = new OemHookImpl; + oemHookService[i]->mSlotId = i; + RLOGD("registerService: starting android::hardware::radio::V1_1::IRadio %s", + serviceNames[i]); + android::status_t status = radioService[i]->registerAsService(serviceNames[i]); + status = oemHookService[i]->registerAsService(serviceNames[i]); + + ret = pthread_rwlock_unlock(radioServiceRwlockPtr); + assert(ret == 0); + } + + s_vendorFunctions = callbacks; + s_commands = commands; +} + +void rilc_thread_pool() { + joinRpcThreadpool(); +} + +pthread_rwlock_t * radio::getRadioServiceRwlock(int slotId) { + pthread_rwlock_t *radioServiceRwlockPtr = &radioServiceRwlock; + + #if (SIM_COUNT >= 2) + if (slotId == 2) radioServiceRwlockPtr = &radioServiceRwlock2; + #if (SIM_COUNT >= 3) + if (slotId == 3) radioServiceRwlockPtr = &radioServiceRwlock3; + #if (SIM_COUNT >= 4) + if (slotId == 4) radioServiceRwlockPtr = &radioServiceRwlock4; + #endif + #endif + #endif + + return radioServiceRwlockPtr; +} diff --git a/libril/ril_service.h b/libril/ril_service.h new file mode 100644 index 0000000..2240e2a --- /dev/null +++ b/libril/ril_service.h @@ -0,0 +1,748 @@ +/* + * 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. + */ + +#ifndef RIL_SERVICE_H +#define RIL_SERVICE_H + +#include +#include + +namespace radio { +void registerService(RIL_RadioFunctions *callbacks, android::CommandInfo *commands); + +int getIccCardStatusResponse(int slotId, int responseType, + int token, RIL_Errno e, void *response, size_t responselen); + +int supplyIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPukForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyIccPuk2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int changeIccPinForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int changeIccPin2ForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int supplyNetworkDepersonalizationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCurrentCallsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int dialResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int getIMSIForAppResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int hangupConnectionResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int hangupWaitingOrBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int hangupForegroundResumeBackgroundResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int switchWaitingOrHoldingAndActiveResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int conferenceResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int rejectCallResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int getLastCallFailCauseResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getSignalStrengthResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getVoiceRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDataRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getOperatorResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setRadioPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendSMSExpectMoreResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setupDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responseLen); + +int iccIOForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int cancelPendingUssdResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int setClirResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, size_t responselen); + +int getCallForwardStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCallForwardResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCallWaitingResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeLastIncomingGsmSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acceptCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deactivateDataCallResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setFacilityLockForAppResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setBarringPasswordResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getNetworkSelectionModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setNetworkSelectionModeAutomaticResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setNetworkSelectionModeManualResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getAvailableNetworksResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int startNetworkScanResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int stopNetworkScanResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int startDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int stopDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getBasebandVersionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int separateConnectionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getMuteResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getClipResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDataCallListResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int setSuppServiceNotificationsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int writeSmsToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deleteSmsOnSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setBandModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getAvailableBandModesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendEnvelopeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendTerminalResponseToSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int handleStkCallSetupRequestFromSimResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int explicitCallTransferResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getPreferredNetworkTypeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getNeighboringCidsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setLocationUpdatesResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCdmaRoamingPreferenceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getTTYModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getPreferredVoicePrivacyResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendCDMAFeatureCodeResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendBurstDtmfResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int sendCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeLastIncomingCdmaSmsResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setGsmBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setGsmBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCDMASubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int writeSmsToRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int deleteSmsOnRuimResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getDeviceIdentityResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int exitEmergencyCallbackModeResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int setCdmaBroadcastActivationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setSmscAddressResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int reportSmsMemoryStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int reportStkServiceIsRunningResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getCdmaSubscriptionSourceResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int requestIsimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int acknowledgeIncomingGsmSmsWithPduResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendEnvelopeWithStatusResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + +int getVoiceRadioTechnologyResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getCellInfoListResponse(int slotId, + int responseType, + int serial, RIL_Errno e, void *response, + size_t responseLen); + +int setCellInfoListRateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setInitialAttachApnResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getImsRegistrationStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendImsSmsResponse(int slotId, int responseType, + int serial, RIL_Errno e, void *response, size_t responselen); + +int iccTransmitApduBasicChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int iccOpenLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, void *response, + size_t responselen); + + +int iccCloseLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int iccTransmitApduLogicalChannelResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvReadItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + + +int nvWriteItemResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvWriteCdmaPrlResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int nvResetConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setUiccSubscriptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setDataAllowedResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getHardwareConfigResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int requestIccSimAuthenticationResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setDataProfileResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int requestShutdownResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int setRadioCapabilityResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int startLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int stopLceServiceResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int pullLceDataResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int getModemActivityInfoResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int getAllowedCarriersResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int sendDeviceStateResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setIndicationFilterResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int setSimCardPowerResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int startKeepaliveResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +int stopKeepaliveResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responselen); + +void acknowledgeRequest(int slotId, int serial); + +int radioStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responseLen); + +int callStateChangedInd(int slotId, int indType, int token, + RIL_Errno e, void *response, size_t responselen); + +int networkStateChangedInd(int slotId, int indType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsStatusReportInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newSmsOnSimInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int onUssdInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int nitzTimeReceivedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int currentSignalStrengthInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int dataCallListChangedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int suppSvcNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkSessionEndInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkProactiveCommandInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkEventNotifyInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int stkCallSetupInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simSmsStorageFullInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simRefreshInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int callRingInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int simStatusChangedInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int cdmaNewSmsInd(int slotId, int indicationType, + int token, RIL_Errno e, void *response, size_t responselen); + +int newBroadcastSmsInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaRuimSmsStorageFullInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int restrictedStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int enterEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaCallWaitingInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaOtaProvisionStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaInfoRecInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int oemHookRawInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int indicateRingbackToneInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int resendIncallMuteInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cdmaSubscriptionSourceChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int cdmaPrlChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int exitEmergencyCallbackModeInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int rilConnectedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int voiceRadioTechChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int cellInfoListInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int imsNetworkStateChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int subscriptionStatusChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int srvccStateNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int hardwareConfigChangedInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int radioCapabilityIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int onSupplementaryServiceIndicationInd(int slotId, + int indicationType, int token, RIL_Errno e, + void *response, size_t responselen); + +int stkCallControlAlphaNotifyInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int lceDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int pcoDataInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int modemResetInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int networkScanResultInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int keepaliveStatusInd(int slotId, + int indicationType, int token, RIL_Errno e, void *response, + size_t responselen); + +int sendRequestRawResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int sendRequestStringsResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int setCarrierInfoForImsiEncryptionResponse(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +int carrierInfoForImsiEncryption(int slotId, + int responseType, int serial, RIL_Errno e, + void *response, size_t responseLen); + +pthread_rwlock_t * getRadioServiceRwlock(int slotId); + +} // namespace radio + +#endif // RIL_SERVICE_H diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h new file mode 100644 index 0000000..bd2cf70 --- /dev/null +++ b/libril/ril_unsol_commands.h @@ -0,0 +1,66 @@ +/* //device/libs/telephony/ril_unsol_commands.h +** +** Copyright 2006, 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. +*/ + {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, radio::radioStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, radio::callStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, radio::networkStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS, radio::newSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, radio::newSmsStatusReportInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, radio::newSmsOnSimInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_USSD, radio::onUssdInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_USSD_REQUEST, radio::onUssdInd, DONT_WAKE}, + {RIL_UNSOL_NITZ_TIME_RECEIVED, radio::nitzTimeReceivedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIGNAL_STRENGTH, radio::currentSignalStrengthInd, DONT_WAKE}, + {RIL_UNSOL_DATA_CALL_LIST_CHANGED, radio::dataCallListChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SUPP_SVC_NOTIFICATION, radio::suppSvcNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_SESSION_END, radio::stkSessionEndInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_PROACTIVE_COMMAND, radio::stkProactiveCommandInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_EVENT_NOTIFY, radio::stkEventNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_CALL_SETUP, radio::stkCallSetupInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIM_SMS_STORAGE_FULL, radio::simSmsStorageFullInd, WAKE_PARTIAL}, + {RIL_UNSOL_SIM_REFRESH, radio::simRefreshInd, WAKE_PARTIAL}, + {RIL_UNSOL_CALL_RING, radio::callRingInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, radio::simStatusChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, radio::cdmaNewSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, radio::newBroadcastSmsInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, radio::cdmaRuimSmsStorageFullInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESTRICTED_STATE_CHANGED, radio::restrictedStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, radio::enterEmergencyCallbackModeInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_CALL_WAITING, radio::cdmaCallWaitingInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, radio::cdmaOtaProvisionStatusInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_INFO_REC, radio::cdmaInfoRecInd, WAKE_PARTIAL}, + {RIL_UNSOL_OEM_HOOK_RAW, radio::oemHookRawInd, WAKE_PARTIAL}, + {RIL_UNSOL_RINGBACK_TONE, radio::indicateRingbackToneInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESEND_INCALL_MUTE, radio::resendIncallMuteInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, radio::cdmaSubscriptionSourceChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_CDMA_PRL_CHANGED, radio::cdmaPrlChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, radio::exitEmergencyCallbackModeInd, WAKE_PARTIAL}, + {RIL_UNSOL_RIL_CONNECTED, radio::rilConnectedInd, WAKE_PARTIAL}, + {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, radio::voiceRadioTechChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_CELL_INFO_LIST, radio::cellInfoListInd, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, radio::imsNetworkStateChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, radio::subscriptionStatusChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_SRVCC_STATE_NOTIFY, radio::srvccStateNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, radio::hardwareConfigChangedInd, WAKE_PARTIAL}, + {RIL_UNSOL_DC_RT_INFO_CHANGED, NULL, WAKE_PARTIAL}, + {RIL_UNSOL_RADIO_CAPABILITY, radio::radioCapabilityIndicationInd, WAKE_PARTIAL}, + {RIL_UNSOL_ON_SS, radio::onSupplementaryServiceIndicationInd, WAKE_PARTIAL}, + {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, radio::stkCallControlAlphaNotifyInd, WAKE_PARTIAL}, + {RIL_UNSOL_LCEDATA_RECV, radio::lceDataInd, WAKE_PARTIAL}, + {RIL_UNSOL_PCO_DATA, radio::pcoDataInd, WAKE_PARTIAL}, + {RIL_UNSOL_MODEM_RESTART, radio::modemResetInd, WAKE_PARTIAL}, + {RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, radio::carrierInfoForImsiEncryption, WAKE_PARTIAL}, + {RIL_UNSOL_NETWORK_SCAN_RESULT, radio::networkScanResultInd, WAKE_PARTIAL}, diff --git a/libril/sap_service.cpp b/libril/sap_service.cpp new file mode 100644 index 0000000..52ebd6c --- /dev/null +++ b/libril/sap_service.cpp @@ -0,0 +1,965 @@ +/* + * 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 "RIL_SAP" + +#include + +#include +#include +#include +#include "pb_decode.h" +#include "pb_encode.h" + +using namespace android::hardware::radio::V1_0; +using ::android::hardware::Return; +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; + +struct SapImpl; + +#if (SIM_COUNT >= 2) +sp sapService[SIM_COUNT]; +#else +sp sapService[1]; +#endif + +struct SapImpl : public android::hardware::radio::V1_1::ISap { + int32_t slotId; + sp sapCallback; + RIL_SOCKET_ID rilSocketId; + + Return setCallback(const ::android::sp& sapCallbackParam); + + Return connectReq(int32_t token, int32_t maxMsgSize); + + Return disconnectReq(int32_t token); + + Return apduReq(int32_t token, SapApduType type, const hidl_vec& command); + + Return transferAtrReq(int32_t token); + + Return powerReq(int32_t token, bool state); + + Return resetSimReq(int32_t token); + + Return transferCardReaderStatusReq(int32_t token); + + Return setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol); + + MsgHeader* createMsgHeader(MsgId msgId, int32_t token); + + Return addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, uint8_t *reqPtr); + + void sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...); + + void checkReturnStatus(Return& ret); +}; + +void SapImpl::checkReturnStatus(Return& ret) { + if (ret.isOk() == false) { + RLOGE("checkReturnStatus: unable to call response/indication callback: %s", + ret.description().c_str()); + // Remote process (SapRilReceiver.java) hosting the callback must be dead. Reset the + // callback object; there's no other recovery to be done here. When the client process is + // back up, it will call setCallback() + sapCallback = NULL; + } +} + +Return SapImpl::setCallback(const ::android::sp& sapCallbackParam) { + RLOGD("SapImpl::setCallback for slotId %d", slotId); + sapCallback = sapCallbackParam; + return Void(); +} + +MsgHeader* SapImpl::createMsgHeader(MsgId msgId, int32_t token) { + // Memory for msg will be freed by RilSapSocket::onRequestComplete() + MsgHeader *msg = (MsgHeader *)calloc(1, sizeof(MsgHeader)); + if (msg == NULL) { + return NULL; + } + msg->token = token; + msg->type = MsgType_REQUEST; + msg->id = msgId; + msg->error = Error_RIL_E_SUCCESS; + return msg; +} + +Return SapImpl::addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, + uint8_t *reqPtr) { + pb_bytes_array_t *payload = (pb_bytes_array_t *) malloc(sizeof(pb_bytes_array_t) - 1 + reqLen); + msg->payload = payload; + if (msg->payload == NULL) { + sendFailedResponse(msg->id, msg->token, 2, reqPtr, msg); + return Void(); + } + msg->payload->size = reqLen; + memcpy(msg->payload->bytes, reqPtr, reqLen); + + RilSapSocket *sapSocket = RilSapSocket::getSocketById(rilSocketId); + if (sapSocket) { + RLOGD("SapImpl::addPayloadAndDispatchRequest: calling dispatchRequest"); + sapSocket->dispatchRequest(msg); + } else { + RLOGE("SapImpl::addPayloadAndDispatchRequest: sapSocket is null"); + sendFailedResponse(msg->id, msg->token, 3, msg->payload, reqPtr, msg); + return Void(); + } + free(payload); + free(reqPtr); + return Void(); +} + +void SapImpl::sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...) { + va_list ap; + va_start(ap, numPointers); + for (int i = 0; i < numPointers; i++) { + void *ptr = va_arg(ap, void *); + if (ptr) free(ptr); + } + va_end(ap); + Return retStatus; + switch(msgId) { + case MsgId_RIL_SIM_SAP_CONNECT: + retStatus = sapCallback->connectResponse(token, SapConnectRsp::CONNECT_FAILURE, 0); + break; + + case MsgId_RIL_SIM_SAP_DISCONNECT: + retStatus = sapCallback->disconnectResponse(token); + break; + + case MsgId_RIL_SIM_SAP_APDU: { + hidl_vec apduRsp; + retStatus = sapCallback->apduResponse(token, SapResultCode::GENERIC_FAILURE, apduRsp); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { + hidl_vec atr; + retStatus = sapCallback->transferAtrResponse(token, SapResultCode::GENERIC_FAILURE, + atr); + break; + } + + case MsgId_RIL_SIM_SAP_POWER: + retStatus = sapCallback->powerResponse(token, SapResultCode::GENERIC_FAILURE); + break; + + case MsgId_RIL_SIM_SAP_RESET_SIM: + retStatus = sapCallback->resetSimResponse(token, SapResultCode::GENERIC_FAILURE); + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: + retStatus = sapCallback->transferCardReaderStatusResponse(token, + SapResultCode::GENERIC_FAILURE, 0); + break; + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: + retStatus = sapCallback->transferProtocolResponse(token, SapResultCode::NOT_SUPPORTED); + break; + + default: + return; + } + sapService[slotId]->checkReturnStatus(retStatus); +} + +Return SapImpl::connectReq(int32_t token, int32_t maxMsgSize) { + RLOGD("SapImpl::connectReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_CONNECT, token); + if (msg == NULL) { + RLOGE("SapImpl::connectReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_CONNECT_REQ *****/ + RIL_SIM_SAP_CONNECT_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_CONNECT_REQ)); + req.max_message_size = maxMsgSize; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::connectReq: Error getting encoded size for RIL_SIM_SAP_CONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::connectReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg); + return Void(); + } + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::connectReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::connectReq: Error encoding RIL_SIM_SAP_CONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_CONNECT_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::disconnectReq(int32_t token) { + RLOGD("SapImpl::disconnectReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_DISCONNECT, token); + if (msg == NULL) { + RLOGE("SapImpl::disconnectReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_DISCONNECT_REQ *****/ + RIL_SIM_SAP_DISCONNECT_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_DISCONNECT_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::disconnectReq: Error getting encoded size for RIL_SIM_SAP_DISCONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::disconnectReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::disconnectReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) { + RLOGE("SapImpl::disconnectReq: Error encoding RIL_SIM_SAP_DISCONNECT_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_DISCONNECT_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::apduReq(int32_t token, SapApduType type, const hidl_vec& command) { + RLOGD("SapImpl::apduReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_APDU, token); + if (msg == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_APDU_REQ *****/ + RIL_SIM_SAP_APDU_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_APDU_REQ)); + req.type = (RIL_SIM_SAP_APDU_REQ_Type)type; + + if (command.size() > 0) { + req.command = (pb_bytes_array_t *)malloc(sizeof(pb_bytes_array_t) - 1 + command.size()); + if (req.command == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for req.command"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 1, msg); + return Void(); + } + req.command->size = command.size(); + memcpy(req.command->bytes, command.data(), command.size()); + } + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_APDU_REQ_fields, &req)) { + RLOGE("SapImpl::apduReq: Error getting encoded size for RIL_SIM_SAP_APDU_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::apduReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::apduReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_APDU_REQ_fields, &req)) { + RLOGE("SapImpl::apduReq: Error encoding RIL_SIM_SAP_APDU_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 3, req.command, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_APDU_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::transferAtrReq(int32_t token) { + RLOGD("SapImpl::transferAtrReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token); + if (msg == NULL) { + RLOGE("SapImpl::transferAtrReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ *****/ + RIL_SIM_SAP_TRANSFER_ATR_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_ATR_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { + RLOGE("SapImpl::transferAtrReq: Error getting encoded size for " + "RIL_SIM_SAP_TRANSFER_ATR_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::transferAtrReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::transferAtrReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) { + RLOGE("SapImpl::transferAtrReq: Error encoding RIL_SIM_SAP_TRANSFER_ATR_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::powerReq(int32_t token, bool state) { + RLOGD("SapImpl::powerReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_POWER, token); + if (msg == NULL) { + RLOGE("SapImpl::powerReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_POWER_REQ *****/ + RIL_SIM_SAP_POWER_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_POWER_REQ)); + req.state = state; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_POWER_REQ_fields, &req)) { + RLOGE("SapImpl::powerReq: Error getting encoded size for RIL_SIM_SAP_POWER_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::powerReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::powerReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_POWER_REQ_fields, &req)) { + RLOGE("SapImpl::powerReq: Error encoding RIL_SIM_SAP_POWER_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_POWER_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::resetSimReq(int32_t token) { + RLOGD("SapImpl::resetSimReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_RESET_SIM, token); + if (msg == NULL) { + RLOGE("SapImpl::resetSimReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_RESET_SIM_REQ *****/ + RIL_SIM_SAP_RESET_SIM_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_RESET_SIM_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { + RLOGE("SapImpl::resetSimReq: Error getting encoded size for RIL_SIM_SAP_RESET_SIM_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::resetSimReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::resetSimReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) { + RLOGE("SapImpl::resetSimReq: Error encoding RIL_SIM_SAP_RESET_SIM_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_RESET_SIM_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::transferCardReaderStatusReq(int32_t token) { + RLOGD("SapImpl::transferCardReaderStatusReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token); + if (msg == NULL) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ *****/ + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ)); + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, + &req)) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error getting encoded size for " + "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::transferCardReaderStatusReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, &req)) { + RLOGE("SapImpl::transferCardReaderStatusReq: Error encoding " + "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +Return SapImpl::setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol) { + RLOGD("SapImpl::setTransferProtocolReq"); + MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token); + if (msg == NULL) { + RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for msg"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 0); + return Void(); + } + + /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ *****/ + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ req; + memset(&req, 0, sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ)); + req.protocol = (RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_Protocol)transferProtocol; + + size_t encodedSize = 0; + if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { + RLOGE("SapImpl::setTransferProtocolReq: Error getting encoded size for " + "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); + return Void(); + } + + uint8_t *buffer = (uint8_t *)calloc(1, encodedSize); + if (buffer == NULL) { + RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for buffer"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg); + return Void(); + } + + pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize); + + RLOGD("SapImpl::setTransferProtocolReq calling pb_encode"); + if (!pb_encode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) { + RLOGE("SapImpl::setTransferProtocolReq: Error encoding " + "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ"); + sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 2, buffer, msg); + return Void(); + } + /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ done *****/ + + /* encoded req is payload */ + return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer); +} + +void *sapDecodeMessage(MsgId msgId, MsgType msgType, uint8_t *payloadPtr, size_t payloadLen) { + void *responsePtr = NULL; + pb_istream_t stream; + + /* Create the stream */ + stream = pb_istream_from_buffer((uint8_t *)payloadPtr, payloadLen); + + /* Decode based on the message id */ + switch (msgId) + { + case MsgId_RIL_SIM_SAP_CONNECT: + responsePtr = malloc(sizeof(RIL_SIM_SAP_CONNECT_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_CONNECT_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_CONNECT_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_DISCONNECT: + if (msgType == MsgType_RESPONSE) { + responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_RSP"); + return NULL; + } + } + } else { + responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_IND)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_IND_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_IND"); + return NULL; + } + } + } + break; + + case MsgId_RIL_SIM_SAP_APDU: + responsePtr = malloc(sizeof(RIL_SIM_SAP_APDU_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_APDU_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_APDU_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: + responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_ATR_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_ATR_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_ATR_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_POWER: + responsePtr = malloc(sizeof(RIL_SIM_SAP_POWER_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_POWER_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_POWER_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_RESET_SIM: + responsePtr = malloc(sizeof(RIL_SIM_SAP_RESET_SIM_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_RESET_SIM_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_RESET_SIM_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_STATUS: + responsePtr = malloc(sizeof(RIL_SIM_SAP_STATUS_IND)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_STATUS_IND_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_STATUS_IND"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: + responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_fields, + responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_ERROR_RESP: + responsePtr = malloc(sizeof(RIL_SIM_SAP_ERROR_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_ERROR_RSP_fields, responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_ERROR_RSP"); + return NULL; + } + } + break; + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: + responsePtr = malloc(sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP)); + if (responsePtr) { + if (!pb_decode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_fields, + responsePtr)) { + RLOGE("Error decoding RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP"); + return NULL; + } + } + break; + + default: + break; + } + return responsePtr; +} /* sapDecodeMessage */ + +sp getSapImpl(RilSapSocket *sapSocket) { + switch (sapSocket->getSocketId()) { + case RIL_SOCKET_1: + RLOGD("getSapImpl: returning sapService[0]"); + return sapService[0]; + #if (SIM_COUNT >= 2) + case RIL_SOCKET_2: + return sapService[1]; + #if (SIM_COUNT >= 3) + case RIL_SOCKET_3: + return sapService[2]; + #if (SIM_COUNT >= 4) + case RIL_SOCKET_4: + return sapService[3]; + #endif + #endif + #endif + default: + return NULL; + } +} + +SapResultCode convertApduResponseProtoToHal(RIL_SIM_SAP_APDU_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_NOT_READY: + return SapResultCode::CARD_NOT_ACCESSSIBLE; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertTransferAtrResponseProtoToHal( + RIL_SIM_SAP_TRANSFER_ATR_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: + return SapResultCode::DATA_NOT_AVAILABLE; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertPowerResponseProtoToHal(RIL_SIM_SAP_POWER_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_ON: + return SapResultCode::CARD_ALREADY_POWERED_ON; + default: + return SapResultCode::GENERIC_FAILURE; + } +} + +SapResultCode convertResetSimResponseProtoToHal(RIL_SIM_SAP_RESET_SIM_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ABSENT: + return SapResultCode::CARD_REMOVED; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_NOT_READY: + return SapResultCode::CARD_NOT_ACCESSSIBLE; + case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF: + return SapResultCode::CARD_ALREADY_POWERED_OFF; + } + return SapResultCode::GENERIC_FAILURE; +} + +SapResultCode convertTransferCardReaderStatusResponseProtoToHal( + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response responseProto) { + switch(responseProto) { + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SUCCESS: + return SapResultCode::SUCCESS; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_GENERIC_FAILURE: + return SapResultCode::GENERIC_FAILURE; + case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE: + return SapResultCode::DATA_NOT_AVAILABLE; + } + return SapResultCode::GENERIC_FAILURE; +} + +void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket, MsgType msgType) { + MsgId msgId = rsp->id; + uint8_t *data = rsp->payload->bytes; + size_t dataLen = rsp->payload->size; + + void *messagePtr = sapDecodeMessage(msgId, msgType, data, dataLen); + + sp sapImpl = getSapImpl(sapSocket); + if (sapImpl->sapCallback == NULL) { + RLOGE("processResponse: sapCallback == NULL; msgId = %d; msgType = %d", + msgId, msgType); + return; + } + + if (messagePtr == NULL) { + RLOGE("processResponse: *messagePtr == NULL; msgId = %d; msgType = %d", + msgId, msgType); + sapImpl->sendFailedResponse(msgId, rsp->token, 0); + return; + } + + RLOGD("processResponse: sapCallback != NULL; msgId = %d; msgType = %d", + msgId, msgType); + + Return retStatus; + switch (msgId) { + case MsgId_RIL_SIM_SAP_CONNECT: { + RIL_SIM_SAP_CONNECT_RSP *connectRsp = (RIL_SIM_SAP_CONNECT_RSP *)messagePtr; + RLOGD("processResponse: calling sapCallback->connectResponse %d %d %d", + rsp->token, + connectRsp->response, + connectRsp->max_message_size); + retStatus = sapImpl->sapCallback->connectResponse(rsp->token, + (SapConnectRsp)connectRsp->response, + connectRsp->max_message_size); + break; + } + + case MsgId_RIL_SIM_SAP_DISCONNECT: + if (msgType == MsgType_RESPONSE) { + RLOGD("processResponse: calling sapCallback->disconnectResponse %d", rsp->token); + retStatus = sapImpl->sapCallback->disconnectResponse(rsp->token); + } else { + RIL_SIM_SAP_DISCONNECT_IND *disconnectInd = + (RIL_SIM_SAP_DISCONNECT_IND *)messagePtr; + RLOGD("processResponse: calling sapCallback->disconnectIndication %d %d", + rsp->token, disconnectInd->disconnectType); + retStatus = sapImpl->sapCallback->disconnectIndication(rsp->token, + (SapDisconnectType)disconnectInd->disconnectType); + } + break; + + case MsgId_RIL_SIM_SAP_APDU: { + RIL_SIM_SAP_APDU_RSP *apduRsp = (RIL_SIM_SAP_APDU_RSP *)messagePtr; + SapResultCode apduResponse = convertApduResponseProtoToHal(apduRsp->response); + RLOGD("processResponse: calling sapCallback->apduResponse %d %d", + rsp->token, apduResponse); + hidl_vec apduRspVec; + if (apduRsp->apduResponse != NULL && apduRsp->apduResponse->size > 0) { + apduRspVec.setToExternal(apduRsp->apduResponse->bytes, apduRsp->apduResponse->size); + } + retStatus = sapImpl->sapCallback->apduResponse(rsp->token, apduResponse, apduRspVec); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_ATR: { + RIL_SIM_SAP_TRANSFER_ATR_RSP *transferAtrRsp = + (RIL_SIM_SAP_TRANSFER_ATR_RSP *)messagePtr; + SapResultCode transferAtrResponse = + convertTransferAtrResponseProtoToHal(transferAtrRsp->response); + RLOGD("processResponse: calling sapCallback->transferAtrResponse %d %d", + rsp->token, transferAtrResponse); + hidl_vec transferAtrRspVec; + if (transferAtrRsp->atr != NULL && transferAtrRsp->atr->size > 0) { + transferAtrRspVec.setToExternal(transferAtrRsp->atr->bytes, + transferAtrRsp->atr->size); + } + retStatus = sapImpl->sapCallback->transferAtrResponse(rsp->token, transferAtrResponse, + transferAtrRspVec); + break; + } + + case MsgId_RIL_SIM_SAP_POWER: { + SapResultCode powerResponse = convertPowerResponseProtoToHal( + ((RIL_SIM_SAP_POWER_RSP *)messagePtr)->response); + RLOGD("processResponse: calling sapCallback->powerResponse %d %d", + rsp->token, powerResponse); + retStatus = sapImpl->sapCallback->powerResponse(rsp->token, powerResponse); + break; + } + + case MsgId_RIL_SIM_SAP_RESET_SIM: { + SapResultCode resetSimResponse = convertResetSimResponseProtoToHal( + ((RIL_SIM_SAP_RESET_SIM_RSP *)messagePtr)->response); + RLOGD("processResponse: calling sapCallback->resetSimResponse %d %d", + rsp->token, resetSimResponse); + retStatus = sapImpl->sapCallback->resetSimResponse(rsp->token, resetSimResponse); + break; + } + + case MsgId_RIL_SIM_SAP_STATUS: { + RIL_SIM_SAP_STATUS_IND *statusInd = (RIL_SIM_SAP_STATUS_IND *)messagePtr; + RLOGD("processResponse: calling sapCallback->statusIndication %d %d", + rsp->token, statusInd->statusChange); + retStatus = sapImpl->sapCallback->statusIndication(rsp->token, + (SapStatus)statusInd->statusChange); + break; + } + + case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: { + RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *transferStatusRsp = + (RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *)messagePtr; + SapResultCode transferCardReaderStatusResponse = + convertTransferCardReaderStatusResponseProtoToHal( + transferStatusRsp->response); + RLOGD("processResponse: calling sapCallback->transferCardReaderStatusResponse %d %d %d", + rsp->token, + transferCardReaderStatusResponse, + transferStatusRsp->CardReaderStatus); + retStatus = sapImpl->sapCallback->transferCardReaderStatusResponse(rsp->token, + transferCardReaderStatusResponse, + transferStatusRsp->CardReaderStatus); + break; + } + + case MsgId_RIL_SIM_SAP_ERROR_RESP: { + RLOGD("processResponse: calling sapCallback->errorResponse %d", rsp->token); + retStatus = sapImpl->sapCallback->errorResponse(rsp->token); + break; + } + + case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: { + SapResultCode setTransferProtocolResponse; + if (((RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP *)messagePtr)->response == + RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_Response_RIL_E_SUCCESS) { + setTransferProtocolResponse = SapResultCode::SUCCESS; + } else { + setTransferProtocolResponse = SapResultCode::NOT_SUPPORTED; + } + RLOGD("processResponse: calling sapCallback->transferProtocolResponse %d %d", + rsp->token, setTransferProtocolResponse); + retStatus = sapImpl->sapCallback->transferProtocolResponse(rsp->token, + setTransferProtocolResponse); + break; + } + + default: + return; + } + sapImpl->checkReturnStatus(retStatus); +} + +void sap::processResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { + processResponse(rsp, sapSocket, MsgType_RESPONSE); +} + +void sap::processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket) { + processResponse(rsp, sapSocket, MsgType_UNSOL_RESPONSE); +} + +void sap::registerService(RIL_RadioFunctions *callbacks) { + using namespace android::hardware; + int simCount = 1; + const char *serviceNames[] = { + android::RIL_getServiceName() + #if (SIM_COUNT >= 2) + , RIL2_SERVICE_NAME + #if (SIM_COUNT >= 3) + , RIL3_SERVICE_NAME + #if (SIM_COUNT >= 4) + , RIL4_SERVICE_NAME + #endif + #endif + #endif + }; + + RIL_SOCKET_ID socketIds[] = { + RIL_SOCKET_1 + #if (SIM_COUNT >= 2) + , RIL_SOCKET_2 + #if (SIM_COUNT >= 3) + , RIL_SOCKET_3 + #if (SIM_COUNT >= 4) + , RIL_SOCKET_4 + #endif + #endif + #endif + }; + #if (SIM_COUNT >= 2) + simCount = SIM_COUNT; + #endif + + for (int i = 0; i < simCount; i++) { + sapService[i] = new SapImpl; + sapService[i]->slotId = i; + sapService[i]->rilSocketId = socketIds[i]; + RLOGD("registerService: starting ISap %s for slotId %d", serviceNames[i], i); + android::status_t status = sapService[i]->registerAsService(serviceNames[i]); + RLOGD("registerService: started ISap %s status %d", serviceNames[i], status); + } +} diff --git a/libril/sap_service.h b/libril/sap_service.h new file mode 100644 index 0000000..afed612 --- /dev/null +++ b/libril/sap_service.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef SAP_SERVICE_H +#define SAP_SERVICE_H + +#include +#include +#include +#include + +namespace sap { + +void registerService(RIL_RadioFunctions *callbacks); +void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket); +void processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket); + +} // namespace android + +#endif // RIL_SERVICE_H \ No newline at end of file