diff options
-rw-r--r-- | include/telephony/ril.h | 101 | ||||
-rw-r--r-- | libril/ril.cpp | 73 | ||||
-rw-r--r-- | libril/ril_commands.h | 4 |
3 files changed, 176 insertions, 2 deletions
diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 803d965..2539275 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -28,7 +28,7 @@ extern "C" { #endif -#define RIL_VERSION 9 /* Current version */ +#define RIL_VERSION 10 /* Current version */ #define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ #define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 @@ -57,8 +57,10 @@ typedef enum { 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 + 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_Errno; typedef enum { @@ -320,6 +322,22 @@ typedef struct { 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; @@ -3565,6 +3583,85 @@ typedef struct { */ #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 + * GENERIC_FAILURE + */ +#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). + * + * "data" is const char * and set to AID value, See ETSI 102.221 and 101.220. + * + * "response" is int * + * ((int *)data)[0] contains the session id of the logical channel. + * A value of 0 indicates an invalid session id. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + * MISSING_RESOURCE + * NO_SUCH_ELEMENT + */ +#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 + * GENERIC_FAILURE + */ +#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 + * GENERIC_FAILURE + */ +#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117 + + /***********************************************************************/ diff --git a/libril/ril.cpp b/libril/ril.cpp index 1957939..7ceb8b3 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -199,6 +199,7 @@ static void dispatchStrings (Parcel& p, RequestInfo *pRI); static void dispatchInts (Parcel& p, RequestInfo *pRI); static void dispatchDial (Parcel& p, RequestInfo *pRI); static void dispatchSIM_IO (Parcel& p, RequestInfo *pRI); +static void dispatchSIM_APDU (Parcel& p, RequestInfo *pRI); static void dispatchCallForward(Parcel& p, RequestInfo *pRI); static void dispatchRaw(Parcel& p, RequestInfo *pRI); static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI); @@ -777,6 +778,74 @@ invalid: } /** + * Callee expects const RIL_SIM_APDU * + * Payload is: + * int32_t sessionid + * int32_t cla + * int32_t instruction + * int32_t p1, p2, p3 + * String data + */ +static void +dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) { + int32_t t; + status_t status; + RIL_SIM_APDU apdu; + + memset (&apdu, 0, sizeof(RIL_SIM_APDU)); + + // Note we only check status at the end. Any single failure leads to + // subsequent reads filing. + status = p.readInt32(&t); + apdu.sessionid = (int)t; + + status = p.readInt32(&t); + apdu.cla = (int)t; + + status = p.readInt32(&t); + apdu.instruction = (int)t; + + status = p.readInt32(&t); + apdu.p1 = (int)t; + + status = p.readInt32(&t); + apdu.p2 = (int)t; + + status = p.readInt32(&t); + apdu.p3 = (int)t; + + apdu.data = strdupReadString(p); + + startRequest; + appendPrintBuf("%ssessionid=%d,cla=%d,ins=%d,p1=%d,p2=%d,p3=%d,data=%s", + printBuf, apdu.sessionid, apdu.cla, apdu.instruction, apdu.p1, apdu.p2, + apdu.p3, (char*)apdu.data); + closeRequest; + printRequest(pRI->token, pRI->pCI->requestNumber); + + if (status != NO_ERROR) { + goto invalid; + } + + s_callbacks.onRequest(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI); + +#ifdef MEMSET_FREED + memsetString(apdu.data); +#endif + free(apdu.data); + +#ifdef MEMSET_FREED + memset(&apdu, 0, sizeof(RIL_SIM_APDU)); +#endif + + return; +invalid: + invalidCommandBlock(pRI); + return; +} + + +/** * Callee expects const RIL_CallForwardInfo * * Payload is: * int32_t status/action @@ -3812,6 +3881,10 @@ requestToString(int request) { case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_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_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"; diff --git a/libril/ril_commands.h b/libril/ril_commands.h index 16daa72..7547f7f 100644 --- a/libril/ril_commands.h +++ b/libril/ril_commands.h @@ -128,3 +128,7 @@ {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid}, {RIL_REQUEST_IMS_REGISTRATION_STATE, dispatchVoid, responseInts}, {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, dispatchSIM_APDU, responseSIM_IO}, + {RIL_REQUEST_SIM_OPEN_CHANNEL, dispatchString, responseInts}, + {RIL_REQUEST_SIM_CLOSE_CHANNEL, dispatchInts, responseVoid}, + {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, dispatchSIM_APDU, responseSIM_IO}, |