diff options
author | Etan Cohen <etancohen@google.com> | 2014-06-20 08:28:44 -0700 |
---|---|---|
committer | Etan Cohen <etancohen@google.com> | 2014-06-25 11:55:30 -0700 |
commit | d365219a1873e42d2ff669e13a9fe6ce6973bd51 (patch) | |
tree | b7209ceed4d7bf8b5c186cfe90f68009a132878a /libril/ril.cpp | |
parent | 18fc0f46d6ef4fe3000ddf7928ee19e1e214e2fa (diff) | |
download | android_hardware_ril-d365219a1873e42d2ff669e13a9fe6ce6973bd51.tar.gz android_hardware_ril-d365219a1873e42d2ff669e13a9fe6ce6973bd51.tar.bz2 android_hardware_ril-d365219a1873e42d2ff669e13a9fe6ce6973bd51.zip |
Merge kwd to master
Change-Id: Id33008507cbafc88288b6483c7691d6db34cc5c3
Diffstat (limited to 'libril/ril.cpp')
-rw-r--r-- | libril/ril.cpp | 924 |
1 files changed, 752 insertions, 172 deletions
diff --git a/libril/ril.cpp b/libril/ril.cpp index ec59471..a251b4d 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -57,6 +57,10 @@ namespace android { #define PHONE_PROCESS "radio" #define SOCKET_NAME_RIL "rild" +#define SOCKET2_NAME_RIL "rild2" +#define SOCKET3_NAME_RIL "rild3" +#define SOCKET4_NAME_RIL "rild4" + #define SOCKET_NAME_RIL_DEBUG "rild-debug" #define ANDROID_WAKE_LOCK_NAME "radio-interface" @@ -134,6 +138,7 @@ typedef struct RequestInfo { struct RequestInfo *p_next; char cancelled; char local; // responses to local commands do not go back to command process + RIL_SOCKET_ID socket_id; } RequestInfo; typedef struct UserCallbackInfo { @@ -143,7 +148,25 @@ typedef struct UserCallbackInfo { struct UserCallbackInfo *p_next; } UserCallbackInfo; +typedef struct SocketListenParam { + RIL_SOCKET_ID socket_id; + int fdListen; + int fdCommand; + char* processName; + struct ril_event* commands_event; + struct ril_event* listen_event; + void (*processCommandsCallback)(int fd, short flags, void *param); + RecordStream *p_rs; +} SocketListenParam; + +extern "C" const char * requestToString(int request); +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 rild[MAX_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL; /*******************************************************************/ RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL}; @@ -153,9 +176,8 @@ static pthread_t s_tid_dispatch; static pthread_t s_tid_reader; static int s_started = 0; -static int s_fdListen = -1; -static int s_fdCommand = -1; static int s_fdDebug = -1; +static int s_fdDebug_socket2 = -1; static int s_fdWakeupRead; static int s_fdWakeupWrite; @@ -163,22 +185,55 @@ static int s_fdWakeupWrite; static struct ril_event s_commands_event; static struct ril_event s_wakeupfd_event; static struct ril_event s_listen_event; +static SocketListenParam s_ril_param_socket; + +static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests = NULL; + +#if (SIM_COUNT >= 2) +static struct ril_event s_commands_event_socket2; +static struct ril_event s_listen_event_socket2; +static SocketListenParam s_ril_param_socket2; + +static pthread_mutex_t s_pendingRequestsMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t s_writeMutex_socket2 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket2 = NULL; +#endif + +#if (SIM_COUNT >= 3) +static struct ril_event s_commands_event_socket3; +static struct ril_event s_listen_event_socket3; +static SocketListenParam s_ril_param_socket3; + +static pthread_mutex_t s_pendingRequestsMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t s_writeMutex_socket3 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket3 = NULL; +#endif + +#if (SIM_COUNT >= 4) +static struct ril_event s_commands_event_socket4; +static struct ril_event s_listen_event_socket4; +static SocketListenParam s_ril_param_socket4; + +static pthread_mutex_t s_pendingRequestsMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t s_writeMutex_socket4 = PTHREAD_MUTEX_INITIALIZER; +static RequestInfo *s_pendingRequests_socket4 = NULL; +#endif + static struct ril_event s_wake_timeout_event; static struct ril_event s_debug_event; static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0}; -static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER; -static RequestInfo *s_pendingRequests = NULL; - static RequestInfo *s_toDispatchHead = NULL; static RequestInfo *s_toDispatchTail = NULL; @@ -192,6 +247,7 @@ static size_t s_lastNITZTimeDataSize; #endif /*******************************************************************/ +static int sendResponse (Parcel &p, RIL_SOCKET_ID socket_id); static void dispatchVoid (Parcel& p, RequestInfo *pRI); static void dispatchString (Parcel& p, RequestInfo *pRI); @@ -218,7 +274,7 @@ static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI); static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI); static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI); static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI); - +static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI); static int responseInts(Parcel &p, void *response, size_t responselen); static int responseStrings(Parcel &p, void *response, size_t responselen); static int responseString(Parcel &p, void *response, size_t responselen); @@ -243,20 +299,31 @@ static int responseCdmaSignalInfoRecord(Parcel &p,void *response, size_t respons static int responseCdmaCallWaiting(Parcel &p,void *response, size_t responselen); static int responseSimRefresh(Parcel &p, void *response, size_t responselen); static int responseCellInfoList(Parcel &p, void *response, size_t responselen); +static int responseHardwareConfig(Parcel &p, void *response, size_t responselen); static int decodeVoiceRadioTechnology (RIL_RadioState radioState); static int decodeCdmaSubscriptionSource (RIL_RadioState radioState); static RIL_RadioState processRadioState(RIL_RadioState newRadioState); -extern "C" const char * requestToString(int request); -extern "C" const char * failCauseToString(RIL_Errno); -extern "C" const char * callStateToString(RIL_CallState); -extern "C" const char * radioStateToString(RIL_RadioState); - #ifdef RIL_SHLIB +#if defined(ANDROID_MULTI_SIM) +extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, void *data, + size_t datalen, RIL_SOCKET_ID socket_id); +#else extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, 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)) +#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d), (e)) +#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest(a) +#else +#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c)) +#define CALL_ONREQUEST(a, b, c, d, e) s_callbacks.onRequest((a), (b), (c), (d)) +#define CALL_ONSTATEREQUEST(a) s_callbacks.onStateRequest() +#endif static UserCallbackInfo * internalRequestTimedCallback (RIL_TimedCallback callback, void *param, @@ -291,6 +358,15 @@ int cdmaSubscriptionSource = -1; */ int simRuimStatus = -1; +static char * RIL_getRilSocketName() { + return rild; +} + +extern "C" +void RIL_setRilSocketName(char * s) { + strncpy(rild, s, MAX_SOCKET_NAME_LENGTH); +} + static char * strdupReadString(Parcel &p) { size_t stringlen; @@ -329,40 +405,58 @@ void nullParcelReleaseFunction (const uint8_t* data, size_t dataSize, * is not sent back up to the command process */ static void -issueLocalRequest(int request, void *data, int len) { +issueLocalRequest(int request, void *data, int len, RIL_SOCKET_ID socket_id) { RequestInfo *pRI; int ret; + /* 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; + } +#endif pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); pRI->local = 1; pRI->token = 0xffffffff; // token is not used in this context pRI->pCI = &(s_commands[request]); + pRI->socket_id = socket_id; - ret = pthread_mutex_lock(&s_pendingRequestsMutex); + ret = pthread_mutex_lock(pendingRequestsMutexHook); assert (ret == 0); - pRI->p_next = s_pendingRequests; - s_pendingRequests = pRI; + pRI->p_next = *pendingRequestsHook; + *pendingRequestsHook = pRI; - ret = pthread_mutex_unlock(&s_pendingRequestsMutex); + ret = pthread_mutex_unlock(pendingRequestsMutexHook); assert (ret == 0); RLOGD("C[locl]> %s", requestToString(request)); - s_callbacks.onRequest(request, data, len, pRI); + CALL_ONREQUEST(request, data, len, pRI, pRI->socket_id); } static int -processCommandBuffer(void *buffer, size_t buflen) { +processCommandBuffer(void *buffer, size_t buflen, RIL_SOCKET_ID socket_id) { Parcel p; status_t status; int32_t request; int32_t token; RequestInfo *pRI; int ret; + /* Hook for current context */ + /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */ + pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex; + /* pendingRequestsHook refer to &s_pendingRequests */ + RequestInfo** pendingRequestsHook = &s_pendingRequests; p.setData((uint8_t *) buffer, buflen); @@ -370,14 +464,41 @@ processCommandBuffer(void *buffer, size_t buflen) { status = p.readInt32(&request); status = p.readInt32 (&token); + RLOGD("SOCKET %s REQUEST: %s length:%d", rilSocketIdToString(socket_id), requestToString(request), buflen); + +#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 + if (status != NO_ERROR) { RLOGE("invalid request block"); return 0; } if (request < 1 || request >= (int32_t)NUM_ELEMS(s_commands)) { + Parcel pErr; RLOGE("unsupported request code %d token %d", request, token); // FIXME this should perhaps return a response + pErr.writeInt32 (RESPONSE_SOLICITED); + pErr.writeInt32 (token); + pErr.writeInt32 (RIL_E_GENERIC_FAILURE); + + sendResponse(pErr, socket_id); return 0; } @@ -386,14 +507,15 @@ processCommandBuffer(void *buffer, size_t buflen) { pRI->token = token; pRI->pCI = &(s_commands[request]); + pRI->socket_id = socket_id; - ret = pthread_mutex_lock(&s_pendingRequestsMutex); + ret = pthread_mutex_lock(pendingRequestsMutexHook); assert (ret == 0); - pRI->p_next = s_pendingRequests; - s_pendingRequests = pRI; + pRI->p_next = *pendingRequestsHook; + *pendingRequestsHook = pRI; - ret = pthread_mutex_unlock(&s_pendingRequestsMutex); + ret = pthread_mutex_unlock(pendingRequestsMutexHook); assert (ret == 0); /* sLastDispatchedToken = token; */ @@ -414,7 +536,7 @@ static void dispatchVoid (Parcel& p, RequestInfo *pRI) { clearPrintBuf; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, NULL, 0, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, NULL, 0, pRI, pRI->socket_id); } /** Callee expects const char * */ @@ -432,8 +554,8 @@ dispatchString (Parcel& p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, string8, - sizeof(char *), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, string8, + sizeof(char *), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString(string8); @@ -482,7 +604,7 @@ dispatchStrings (Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, pStrings, datalen, pRI, pRI->socket_id); if (pStrings != NULL) { for (int i = 0 ; i < countStrings ; i++) { @@ -536,8 +658,8 @@ dispatchInts (Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<int *>(pInts), - datalen, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<int *>(pInts), + datalen, pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(pInts, 0, datalen); @@ -581,7 +703,7 @@ dispatchSmsWrite (Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &args, sizeof(args), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &args, sizeof(args), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString (args.pdu); @@ -677,7 +799,7 @@ dispatchDial (Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &dial, sizeOfDial, pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString (dial.address); @@ -756,7 +878,7 @@ dispatchSIM_IO (Parcel &p, RequestInfo *pRI) { } size = (s_callbacks.version < 6) ? sizeof(simIO.v5) : sizeof(simIO.v6); - s_callbacks.onRequest(pRI->pCI->requestNumber, &simIO, size, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &simIO, size, pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString (simIO.v6.path); @@ -830,7 +952,7 @@ dispatchSIM_APDU (Parcel &p, RequestInfo *pRI) { goto invalid; } - s_callbacks.onRequest(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &apdu, sizeof(RIL_SIM_APDU), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString(apdu.data); @@ -902,7 +1024,7 @@ dispatchCallForward(Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &cff, sizeof(cff), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString(cff.number); @@ -946,7 +1068,7 @@ dispatchRaw(Parcel &p, RequestInfo *pRI) { closeRequest; printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, const_cast<void *>(data), len, pRI, pRI->socket_id); return; invalid: @@ -1043,7 +1165,7 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { goto invalid; } - s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(&rcsm, 0, sizeof(rcsm)); @@ -1072,9 +1194,9 @@ dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRe rism.messageRef = messageRef; rism.message.cdmaMessage = &rcsm; - s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) - +sizeof(rcsm),pRI); + +sizeof(rcsm),pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(&rcsm, 0, sizeof(rcsm)); @@ -1133,9 +1255,9 @@ dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef printRequest(pRI->token, pRI->pCI->requestNumber); rism.message.gsmMessage = pStrings; - s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) - +datalen, pRI); + +datalen, pRI, pRI->socket_id); if (pStrings != NULL) { for (int i = 0 ; i < countStrings ; i++) { @@ -1226,7 +1348,7 @@ dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa),pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(&rcsa, 0, sizeof(rcsa)); @@ -1285,10 +1407,10 @@ dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI) { goto invalid; } - s_callbacks.onRequest(pRI->pCI->requestNumber, + CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), - pRI); + pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(gsmBci, 0, num * sizeof(RIL_GSM_BroadcastSmsConfigInfo)); @@ -1341,10 +1463,10 @@ dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI) { goto invalid; } - s_callbacks.onRequest(pRI->pCI->requestNumber, + CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), - pRI); + pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(cdmaBci, 0, num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo)); @@ -1440,7 +1562,7 @@ static void dispatchRilCdmaSmsWriteArgs(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw),pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(&rcsw, 0, sizeof(rcsw)); @@ -1486,7 +1608,7 @@ static void dispatchDataCall(Parcel& p, RequestInfo *pRI) { // When all RILs handle this request, this function can be removed and // the request can be sent directly to the RIL using dispatchVoid. static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) { - RIL_RadioState state = s_callbacks.onStateRequest(); + RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id); if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) { RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); @@ -1513,7 +1635,7 @@ static void dispatchVoiceRadioTech(Parcel& p, RequestInfo *pRI) { // When all RILs handle this request, this function can be removed and // the request can be sent directly to the RIL using dispatchVoid. static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) { - RIL_RadioState state = s_callbacks.onStateRequest(); + RIL_RadioState state = CALL_ONSTATEREQUEST((RIL_SOCKET_ID)pRI->socket_id); if ((RADIO_STATE_UNAVAILABLE == state) || (RADIO_STATE_OFF == state)) { RIL_onRequestComplete(pRI, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0); @@ -1562,7 +1684,7 @@ static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI) if (status != NO_ERROR) { goto invalid; } - s_callbacks.onRequest(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString(pf.apn); @@ -1606,7 +1728,7 @@ static void dispatchNVReadItem(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, pRI->socket_id); #ifdef MEMSET_FREED memset(&nvri, 0, sizeof(nvri)); @@ -1642,7 +1764,7 @@ static void dispatchNVWriteItem(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); - s_callbacks.onRequest(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI); + CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, pRI->socket_id); #ifdef MEMSET_FREED memsetString(nvwi.value); @@ -1662,6 +1784,56 @@ invalid: } +static void dispatchUiccSubscripton(Parcel &p, RequestInfo *pRI) { + RIL_SelectUiccSub uicc_sub; + status_t status; + int32_t t; + memset(&uicc_sub, 0, sizeof(uicc_sub)); + + status = p.readInt32(&t); + if (status != NO_ERROR) { + goto invalid; + } + uicc_sub.slot = (int) t; + + status = p.readInt32(&t); + if (status != NO_ERROR) { + goto invalid; + } + uicc_sub.app_index = (int) t; + + status = p.readInt32(&t); + if (status != NO_ERROR) { + goto invalid; + } + uicc_sub.sub_type = (RIL_SubscriptionType) t; + + status = p.readInt32(&t); + if (status != NO_ERROR) { + goto invalid; + } + uicc_sub.act_status = (RIL_UiccSubActStatus) t; + + startRequest; + appendPrintBuf("slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, uicc_sub.app_index, + uicc_sub.act_status); + RLOGD("dispatchUiccSubscription, slot=%d, app_index=%d, act_status = %d", uicc_sub.slot, + uicc_sub.app_index, uicc_sub.act_status); + closeRequest; + printRequest(pRI->token, pRI->pCI->requestNumber); + + CALL_ONREQUEST(pRI->pCI->requestNumber, &uicc_sub, sizeof(uicc_sub), pRI, pRI->socket_id); + +#ifdef MEMSET_FREED + memset(&uicc_sub, 0, sizeof(uicc_sub)); +#endif + return; + +invalid: + invalidCommandBlock(pRI); + return; +} + static int blockingWrite(int fd, const void *buffer, size_t len) { size_t writeOffset = 0; @@ -1689,12 +1861,33 @@ blockingWrite(int fd, const void *buffer, size_t len) { } static int -sendResponseRaw (const void *data, size_t dataSize) { - int fd = s_fdCommand; +sendResponseRaw (const void *data, size_t dataSize, RIL_SOCKET_ID socket_id) { + int fd = s_ril_param_socket.fdCommand; int ret; uint32_t header; + pthread_mutex_t * writeMutexHook = &s_writeMutex; + + RLOGE("Send Response to %s", rilSocketIdToString(socket_id)); - if (s_fdCommand < 0) { +#if (SIM_COUNT >= 2) + if (socket_id == RIL_SOCKET_2) { + fd = s_ril_param_socket2.fdCommand; + writeMutexHook = &s_writeMutex_socket2; + } +#if (SIM_COUNT >= 3) + else if (socket_id == RIL_SOCKET_3) { + fd = s_ril_param_socket3.fdCommand; + writeMutexHook = &s_writeMutex_socket3; + } +#endif +#if (SIM_COUNT >= 4) + else if (socket_id == RIL_SOCKET_4) { + fd = s_ril_param_socket4.fdCommand; + writeMutexHook = &s_writeMutex_socket4; + } +#endif +#endif + if (fd < 0) { return -1; } @@ -1705,33 +1898,33 @@ sendResponseRaw (const void *data, size_t dataSize) { return -1; } - pthread_mutex_lock(&s_writeMutex); + pthread_mutex_lock(writeMutexHook); header = htonl(dataSize); ret = blockingWrite(fd, (void *)&header, sizeof(header)); if (ret < 0) { - pthread_mutex_unlock(&s_writeMutex); + pthread_mutex_unlock(writeMutexHook); return ret; } ret = blockingWrite(fd, data, dataSize); if (ret < 0) { - pthread_mutex_unlock(&s_writeMutex); + pthread_mutex_unlock(writeMutexHook); return ret; } - pthread_mutex_unlock(&s_writeMutex); + pthread_mutex_unlock(writeMutexHook); return 0; } static int -sendResponse (Parcel &p) { +sendResponse (Parcel &p, RIL_SOCKET_ID socket_id) { printResponse; - return sendResponseRaw(p.data(), p.dataSize()); + return sendResponseRaw(p.data(), p.dataSize(), socket_id); } /** response is an int* pointing to an array of ints */ @@ -1963,6 +2156,52 @@ static int responseDataCallListV4(Parcel &p, void *response, size_t responselen) return 0; } +static int responseDataCallListV6(Parcel &p, void *response, size_t responselen) +{ + if (response == NULL && responselen != 0) { + RLOGE("invalid response: NULL"); + return RIL_ERRNO_INVALID_RESPONSE; + } + + if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) { + RLOGE("invalid response length %d expected multiple of %d", + (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6)); + return RIL_ERRNO_INVALID_RESPONSE; + } + + int num = responselen / sizeof(RIL_Data_Call_Response_v6); + p.writeInt32(num); + + RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response; + startResponse; + int i; + for (i = 0; i < num; i++) { + p.writeInt32((int)p_cur[i].status); + p.writeInt32(p_cur[i].suggestedRetryTime); + p.writeInt32(p_cur[i].cid); + p.writeInt32(p_cur[i].active); + writeStringToParcel(p, p_cur[i].type); + writeStringToParcel(p, p_cur[i].ifname); + writeStringToParcel(p, p_cur[i].addresses); + writeStringToParcel(p, p_cur[i].dnses); + writeStringToParcel(p, p_cur[i].gateways); + appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf, + p_cur[i].status, + p_cur[i].suggestedRetryTime, + p_cur[i].cid, + (p_cur[i].active==0)?"down":"up", + (char*)p_cur[i].type, + (char*)p_cur[i].ifname, + (char*)p_cur[i].addresses, + (char*)p_cur[i].dnses, + (char*)p_cur[i].gateways); + } + removeLastChar; + closeResponse; + + return 0; +} + static int responseDataCallList(Parcel &p, void *response, size_t responselen) { // Write version @@ -1976,16 +2215,21 @@ static int responseDataCallList(Parcel &p, void *response, size_t responselen) return RIL_ERRNO_INVALID_RESPONSE; } - if (responselen % sizeof(RIL_Data_Call_Response_v6) != 0) { + // Support v6 or v9 with new rils + if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) { + return responseDataCallListV6(p, response, responselen); + } + + if (responselen % sizeof(RIL_Data_Call_Response_v9) != 0) { RLOGE("invalid response length %d expected multiple of %d", - (int)responselen, (int)sizeof(RIL_Data_Call_Response_v6)); + (int)responselen, (int)sizeof(RIL_Data_Call_Response_v9)); return RIL_ERRNO_INVALID_RESPONSE; } - int num = responselen / sizeof(RIL_Data_Call_Response_v6); + int num = responselen / sizeof(RIL_Data_Call_Response_v9); p.writeInt32(num); - RIL_Data_Call_Response_v6 *p_cur = (RIL_Data_Call_Response_v6 *) response; + RIL_Data_Call_Response_v9 *p_cur = (RIL_Data_Call_Response_v9 *) response; startResponse; int i; for (i = 0; i < num; i++) { @@ -1998,7 +2242,8 @@ static int responseDataCallList(Parcel &p, void *response, size_t responselen) writeStringToParcel(p, p_cur[i].addresses); writeStringToParcel(p, p_cur[i].dnses); writeStringToParcel(p, p_cur[i].gateways); - appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s],", printBuf, + writeStringToParcel(p, p_cur[i].pcscf); + appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s],", printBuf, p_cur[i].status, p_cur[i].suggestedRetryTime, p_cur[i].cid, @@ -2007,7 +2252,8 @@ static int responseDataCallList(Parcel &p, void *response, size_t responselen) (char*)p_cur[i].ifname, (char*)p_cur[i].addresses, (char*)p_cur[i].dnses, - (char*)p_cur[i].gateways); + (char*)p_cur[i].gateways, + (char*)p_cur[i].pcscf); } removeLastChar; closeResponse; @@ -2348,7 +2594,7 @@ static int responseRilSignalStrength(Parcel &p, } if (responselen >= sizeof (RIL_SignalStrength_v5)) { - RIL_SignalStrength_v6 *p_cur = ((RIL_SignalStrength_v6 *) response); + RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response); p.writeInt32(p_cur->GW_SignalStrength.signalStrength); p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate); @@ -2389,12 +2635,18 @@ static int responseRilSignalStrength(Parcel &p, p.writeInt32(p_cur->LTE_SignalStrength.rsrq); p.writeInt32(p_cur->LTE_SignalStrength.rssnr); p.writeInt32(p_cur->LTE_SignalStrength.cqi); + if (responselen >= sizeof (RIL_SignalStrength_v10)) { + p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp); + } else { + p.writeInt32(INT_MAX); + } } else { p.writeInt32(99); p.writeInt32(INT_MAX); p.writeInt32(INT_MAX); p.writeInt32(INT_MAX); p.writeInt32(INT_MAX); + p.writeInt32(INT_MAX); } startResponse; @@ -2403,7 +2655,7 @@ static int responseRilSignalStrength(Parcel &p, EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\ EVDO_SS.signalNoiseRatio=%d,\ LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\ - LTE_SS.rssnr=%d,LTE_SS.cqi=%d]", + LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]", printBuf, p_cur->GW_SignalStrength.signalStrength, p_cur->GW_SignalStrength.bitErrorRate, @@ -2416,7 +2668,8 @@ static int responseRilSignalStrength(Parcel &p, p_cur->LTE_SignalStrength.rsrp, p_cur->LTE_SignalStrength.rsrq, p_cur->LTE_SignalStrength.rssnr, - p_cur->LTE_SignalStrength.cqi); + p_cur->LTE_SignalStrength.cqi, + p_cur->TD_SCDMA_SignalStrength.rscp); closeResponse; } else { @@ -2665,6 +2918,24 @@ static int responseCellInfoList(Parcel &p, void *response, size_t responselen) p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.timingAdvance); break; } + case RIL_CELL_INFO_TYPE_TD_SCDMA: { + appendPrintBuf("%s TDSCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,cpid=%d,", printBuf, + p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc, + p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc, + p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac, + p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid, + p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); + appendPrintBuf("%s tdscdmaSS: rscp=%d],", printBuf, + p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); + + p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mcc); + p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.mnc); + p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.lac); + p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cid); + p.writeInt32(p_cur->CellInfo.tdscdma.cellIdentityTdscdma.cpid); + p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp); + break; + } } p_cur += 1; } @@ -2674,6 +2945,57 @@ static int responseCellInfoList(Parcel &p, void *response, size_t responselen) return 0; } +static int responseHardwareConfig(Parcel &p, void *response, size_t responselen) +{ + if (response == NULL && responselen != 0) { + RLOGE("invalid response: NULL"); + return RIL_ERRNO_INVALID_RESPONSE; + } + + if (responselen % sizeof(RIL_HardwareConfig) != 0) { + RLOGE("invalid response length %d expected multiple of %d", + (int)responselen, (int)sizeof(RIL_HardwareConfig)); + return RIL_ERRNO_INVALID_RESPONSE; + } + + int num = responselen / sizeof(RIL_HardwareConfig); + int i; + RIL_HardwareConfig *p_cur = (RIL_HardwareConfig *) response; + + p.writeInt32(num); + + startResponse; + for (i = 0; i < num; i++) { + switch (p_cur[i].type) { + case RIL_HARDWARE_CONFIG_MODEM: { + writeStringToParcel(p, p_cur[i].uuid); + p.writeInt32((int)p_cur[i].state); + p.writeInt32(p_cur[i].cfg.modem.rat); + p.writeInt32(p_cur[i].cfg.modem.maxVoice); + p.writeInt32(p_cur[i].cfg.modem.maxData); + p.writeInt32(p_cur[i].cfg.modem.maxStandby); + + appendPrintBuf("%s modem: uuid=%s,state=%d,rat=%08x,maxV=%d,maxD=%d,maxS=%d", printBuf, + p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.modem.rat, + p_cur[i].cfg.modem.maxVoice, p_cur[i].cfg.modem.maxData, p_cur[i].cfg.modem.maxStandby); + break; + } + case RIL_HARDWARE_CONFIG_SIM: { + writeStringToParcel(p, p_cur[i].uuid); + p.writeInt32((int)p_cur[i].state); + writeStringToParcel(p, p_cur[i].cfg.sim.modemUuid); + + appendPrintBuf("%s sim: uuid=%s,state=%d,modem-uuid=%s", printBuf, + p_cur[i].uuid, (int)p_cur[i].state, p_cur[i].cfg.sim.modemUuid); + break; + } + } + } + removeLastChar; + closeResponse; + return 0; +} + static void triggerEvLoop() { int ret; if (!pthread_equal(pthread_self(), s_tid_dispatch)) { @@ -2877,25 +3199,47 @@ static void processWakeupCallback(int fd, short flags, void *param) { } while (ret > 0 || (ret < 0 && errno == EINTR)); } -static void onCommandsSocketClosed() { +static void onCommandsSocketClosed(RIL_SOCKET_ID socket_id) { int ret; RequestInfo *p_cur; - + /* 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 /* mark pending requests as "cancelled" so we dont report responses */ - - ret = pthread_mutex_lock(&s_pendingRequestsMutex); + ret = pthread_mutex_lock(pendingRequestsMutexHook); assert (ret == 0); - p_cur = s_pendingRequests; + p_cur = *pendingRequestsHook; - for (p_cur = s_pendingRequests + for (p_cur = *pendingRequestsHook ; p_cur != NULL ; p_cur = p_cur->p_next ) { p_cur->cancelled = 1; } - ret = pthread_mutex_unlock(&s_pendingRequestsMutex); + ret = pthread_mutex_unlock(pendingRequestsMutexHook); assert (ret == 0); } @@ -2904,10 +3248,11 @@ static void processCommandsCallback(int fd, short flags, void *param) { void *p_record; size_t recordlen; int ret; + SocketListenParam *p_info = (SocketListenParam *)param; - assert(fd == s_fdCommand); + assert(fd == p_info->fdCommand); - p_rs = (RecordStream *)param; + p_rs = p_info->p_rs; for (;;) { /* loop until EAGAIN/EINTR, end of stream, or other error */ @@ -2919,7 +3264,7 @@ static void processCommandsCallback(int fd, short flags, void *param) { } else if (ret < 0) { break; } else if (ret == 0) { /* && p_record != NULL */ - processCommandBuffer(p_record, recordlen); + processCommandBuffer(p_record, recordlen, p_info->socket_id); } } @@ -2931,34 +3276,34 @@ static void processCommandsCallback(int fd, short flags, void *param) { RLOGW("EOS. Closing command socket."); } - close(s_fdCommand); - s_fdCommand = -1; + close(fd); + p_info->fdCommand = -1; - ril_event_del(&s_commands_event); + ril_event_del(p_info->commands_event); record_stream_free(p_rs); /* start listening for new connections again */ rilEventAddWakeup(&s_listen_event); - onCommandsSocketClosed(); + onCommandsSocketClosed(p_info->socket_id); } } -static void onNewCommandConnect() { +static void onNewCommandConnect(RIL_SOCKET_ID socket_id) { // Inform we are connected and the ril version int rilVer = s_callbacks.version; - RIL_onUnsolicitedResponse(RIL_UNSOL_RIL_CONNECTED, - &rilVer, sizeof(rilVer)); + RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED, + &rilVer, sizeof(rilVer), socket_id); // implicit radio state changed - RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, - NULL, 0); + 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) { - sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize); + sendResponseRaw(s_lastNITZTimeData, s_lastNITZTimeDataSize, socket_id); free(s_lastNITZTimeData); s_lastNITZTimeData = NULL; @@ -2982,7 +3327,9 @@ static void listenCallback (int fd, short flags, void *param) { int ret; int err; int is_phone_socket; + int fdCommand = -1; RecordStream *p_rs; + SocketListenParam *p_info = (SocketListenParam *)param; struct sockaddr_un peeraddr; socklen_t socklen = sizeof (peeraddr); @@ -2992,16 +3339,16 @@ static void listenCallback (int fd, short flags, void *param) { struct passwd *pwd = NULL; - assert (s_fdCommand < 0); - assert (fd == s_fdListen); + assert (*p_info->fdCommand < 0); + assert (fd == *p_info->fdListen); - s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen); + fdCommand = accept(fd, (sockaddr *) &peeraddr, &socklen); - if (s_fdCommand < 0 ) { + if (fdCommand < 0 ) { RLOGE("Error on accept() errno:%d", errno); /* start listening for new connections again */ - rilEventAddWakeup(&s_listen_event); - return; + rilEventAddWakeup(p_info->listen_event); + return; } /* check the credential of the other side and only accept socket from @@ -3010,13 +3357,13 @@ static void listenCallback (int fd, short flags, void *param) { errno = 0; is_phone_socket = 0; - err = getsockopt(s_fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); + err = getsockopt(fdCommand, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); if (err == 0 && szCreds > 0) { errno = 0; pwd = getpwuid(creds.uid); if (pwd != NULL) { - if (strcmp(pwd->pw_name, PHONE_PROCESS) == 0) { + if (strcmp(pwd->pw_name, p_info->processName) == 0) { is_phone_socket = 1; } else { RLOGE("RILD can't accept socket from process %s", pwd->pw_name); @@ -3028,36 +3375,40 @@ static void listenCallback (int fd, short flags, void *param) { RLOGD("Error on getsockopt() errno: %d", errno); } - if ( !is_phone_socket ) { - RLOGE("RILD must accept socket from %s", PHONE_PROCESS); + if (!is_phone_socket) { + RLOGE("RILD must accept socket from %s", p_info->processName); - close(s_fdCommand); - s_fdCommand = -1; + close(fdCommand); + fdCommand = -1; - onCommandsSocketClosed(); + onCommandsSocketClosed(p_info->socket_id); /* start listening for new connections again */ - rilEventAddWakeup(&s_listen_event); + rilEventAddWakeup(p_info->listen_event); return; } - ret = fcntl(s_fdCommand, F_SETFL, O_NONBLOCK); + ret = fcntl(fdCommand, F_SETFL, O_NONBLOCK); if (ret < 0) { RLOGE ("Error setting O_NONBLOCK errno:%d", errno); } - RLOGI("libril: new connection"); + RLOGI("libril: new connection to %s", rilSocketIdToString(p_info->socket_id)); + + p_info->fdCommand = fdCommand; + + p_rs = record_stream_new(p_info->fdCommand, MAX_COMMAND_BYTES); - p_rs = record_stream_new(s_fdCommand, MAX_COMMAND_BYTES); + p_info->p_rs = p_rs; - ril_event_set (&s_commands_event, s_fdCommand, 1, - processCommandsCallback, p_rs); + ril_event_set (p_info->commands_event, p_info->fdCommand, 1, + p_info->processCommandsCallback, p_info); - rilEventAddWakeup (&s_commands_event); + rilEventAddWakeup (p_info->commands_event); - onNewCommandConnect(); + onNewCommandConnect(p_info->socket_id); } static void freeDebugCallbackArgs(int number, char **args) { @@ -3081,6 +3432,10 @@ static void debugCallback (int fd, short flags, void *param) { int hangupData[1] = {1}; int number; char **args; + RIL_SOCKET_ID socket_id = RIL_SOCKET_1; + int sim_id = 0; + + RLOGI("debugCallback for socket %s", rilSocketIdToString(socket_id)); acceptFD = accept (fd, (sockaddr *) &peeraddr, &socklen); @@ -3112,25 +3467,59 @@ static void debugCallback (int fd, short flags, void *param) { } char * buf = args[i]; buf[len] = 0; + if ((i+1) == number) { + /* The last argument should be sim id 0(SIM1)~3(SIM4) */ + sim_id = atoi(args[i]); + switch (sim_id) { + case 0: + socket_id = RIL_SOCKET_1; + break; + #if (SIM_COUNT >= 2) + case 1: + socket_id = RIL_SOCKET_2; + break; + #endif + #if (SIM_COUNT >= 3) + case 2: + socket_id = RIL_SOCKET_3; + break; + #endif + #if (SIM_COUNT >= 4) + case 3: + socket_id = RIL_SOCKET_4; + break; + #endif + default: + socket_id = RIL_SOCKET_1; + break; + } + } } switch (atoi(args[0])) { case 0: RLOGI ("Connection on debug port: issuing reset."); - issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0); + issueLocalRequest(RIL_REQUEST_RESET_RADIO, NULL, 0, socket_id); break; case 1: RLOGI ("Connection on debug port: issuing radio power off."); data = 0; - issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int)); + issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id); // Close the socket - close(s_fdCommand); - s_fdCommand = -1; + if (socket_id == RIL_SOCKET_1 && s_ril_param_socket.fdCommand > 0) { + close(s_ril_param_socket.fdCommand); + s_ril_param_socket.fdCommand = -1; + } + #if (SIM_COUNT == 2) + else if (socket_id == RIL_SOCKET_2 && s_ril_param_socket2.fdCommand > 0) { + close(s_ril_param_socket2.fdCommand); + s_ril_param_socket2.fdCommand = -1; + } + #endif break; case 2: RLOGI ("Debug port: issuing unsolicited voice network change."); - RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, - NULL, 0); + RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0, socket_id); break; case 3: RLOGI ("Debug port: QXDM log enable."); @@ -3141,7 +3530,7 @@ static void debugCallback (int fd, short flags, void *param) { qxdm_data[4] = 0; // log_mask qxdm_data[5] = 8; // log_max_fileindex issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data, - 6 * sizeof(int)); + 6 * sizeof(int), socket_id); break; case 4: RLOGI ("Debug port: QXDM log disable."); @@ -3152,41 +3541,41 @@ static void debugCallback (int fd, short flags, void *param) { qxdm_data[4] = 0; qxdm_data[5] = 8; issueLocalRequest(RIL_REQUEST_OEM_HOOK_RAW, qxdm_data, - 6 * sizeof(int)); + 6 * sizeof(int), socket_id); break; case 5: RLOGI("Debug port: Radio On"); data = 1; - issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int)); + issueLocalRequest(RIL_REQUEST_RADIO_POWER, &data, sizeof(int), socket_id); sleep(2); // Set network selection automatic. - issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0); + issueLocalRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, NULL, 0, socket_id); break; case 6: RLOGI("Debug port: Setup Data Call, Apn :%s\n", args[1]); actData[0] = args[1]; issueLocalRequest(RIL_REQUEST_SETUP_DATA_CALL, &actData, - sizeof(actData)); + sizeof(actData), socket_id); break; case 7: RLOGI("Debug port: Deactivate Data Call"); issueLocalRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, &deactData, - sizeof(deactData)); + sizeof(deactData), socket_id); break; case 8: RLOGI("Debug port: Dial Call"); dialData.clir = 0; dialData.address = args[1]; - issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData)); + issueLocalRequest(RIL_REQUEST_DIAL, &dialData, sizeof(dialData), socket_id); break; case 9: RLOGI("Debug port: Answer Call"); - issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0); + issueLocalRequest(RIL_REQUEST_ANSWER, NULL, 0, socket_id); break; case 10: RLOGI("Debug port: End Call"); issueLocalRequest(RIL_REQUEST_HANGUP, &hangupData, - sizeof(hangupData)); + sizeof(hangupData), socket_id); break; default: RLOGE ("Invalid request"); @@ -3283,11 +3672,68 @@ extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) { memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); } +static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) { + int fdListen = -1; + int ret; + char socket_name[10]; + + memset(socket_name, 0, sizeof(char)*10); + + switch(socket_id) { + case RIL_SOCKET_1: + strncpy(socket_name, RIL_getRilSocketName(), 9); + break; + #if (SIM_COUNT >= 2) + case RIL_SOCKET_2: + strncpy(socket_name, SOCKET2_NAME_RIL, 9); + break; + #endif + #if (SIM_COUNT >= 3) + case RIL_SOCKET_3: + strncpy(socket_name, SOCKET3_NAME_RIL, 9); + break; + #endif + #if (SIM_COUNT >= 4) + case RIL_SOCKET_4: + strncpy(socket_name, SOCKET4_NAME_RIL, 9); + break; + #endif + default: + RLOGE("Socket id is wrong!!"); + return; + } + + RLOGI("Start to listen %s", rilSocketIdToString(socket_id)); + + fdListen = android_get_control_socket(socket_name); + if (fdListen < 0) { + RLOGE("Failed to get socket %s", socket_name); + exit(-1); + } + + ret = listen(fdListen, 4); + + if (ret < 0) { + RLOGE("Failed to listen on control socket '%d': %s", + fdListen, strerror(errno)); + exit(-1); + } + socket_listen_p->fdListen = fdListen; + + /* note: non-persistent so we can accept only one connection at a time */ + ril_event_set (socket_listen_p->listen_event, fdListen, false, + listenCallback, socket_listen_p); + + rilEventAddWakeup (socket_listen_p->listen_event); +} + extern "C" void RIL_register (const RIL_RadioFunctions *callbacks) { int ret; int flags; + RLOGI("SIM_COUNT: %d", SIM_COUNT); + if (callbacks == NULL) { RLOGE("RIL_register: RIL_RadioFunctions * null"); return; @@ -3312,8 +3758,61 @@ RIL_register (const RIL_RadioFunctions *callbacks) { memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions)); + /* Initialize socket1 parameters */ + s_ril_param_socket = { + RIL_SOCKET_1, /* socket_id */ + -1, /* fdListen */ + -1, /* fdCommand */ + PHONE_PROCESS, /* processName */ + &s_commands_event, /* commands_event */ + &s_listen_event, /* listen_event */ + processCommandsCallback, /* processCommandsCallback */ + NULL /* p_rs */ + }; + +#if (SIM_COUNT >= 2) + s_ril_param_socket2 = { + RIL_SOCKET_2, /* socket_id */ + -1, /* fdListen */ + -1, /* fdCommand */ + PHONE_PROCESS, /* processName */ + &s_commands_event_socket2, /* commands_event */ + &s_listen_event_socket2, /* listen_event */ + processCommandsCallback, /* processCommandsCallback */ + NULL /* p_rs */ + }; +#endif + +#if (SIM_COUNT >= 3) + s_ril_param_socket3 = { + RIL_SOCKET_3, /* socket_id */ + -1, /* fdListen */ + -1, /* fdCommand */ + PHONE_PROCESS, /* processName */ + &s_commands_event_socket3, /* commands_event */ + &s_listen_event_socket3, /* listen_event */ + processCommandsCallback, /* processCommandsCallback */ + NULL /* p_rs */ + }; +#endif + +#if (SIM_COUNT >= 4) + s_ril_param_socket4 = { + RIL_SOCKET_4, /* socket_id */ + -1, /* fdListen */ + -1, /* fdCommand */ + PHONE_PROCESS, /* processName */ + &s_commands_event_socket4, /* commands_event */ + &s_listen_event_socket4, /* listen_event */ + processCommandsCallback, /* processCommandsCallback */ + NULL /* p_rs */ + }; +#endif + + 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++) { @@ -3332,47 +3831,41 @@ RIL_register (const RIL_RadioFunctions *callbacks) { RIL_startEventLoop(); } - // start listen socket - -#if 0 - ret = socket_local_server (SOCKET_NAME_RIL, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - - if (ret < 0) { - RLOGE("Unable to bind socket errno:%d", errno); - exit (-1); - } - s_fdListen = ret; - -#else - s_fdListen = android_get_control_socket(SOCKET_NAME_RIL); - if (s_fdListen < 0) { - RLOGE("Failed to get socket '" SOCKET_NAME_RIL "'"); - exit(-1); - } + // start listen socket1 + startListen(RIL_SOCKET_1, &s_ril_param_socket); - ret = listen(s_fdListen, 4); +#if (SIM_COUNT >= 2) + // start listen socket2 + startListen(RIL_SOCKET_2, &s_ril_param_socket2); +#endif /* (SIM_COUNT == 2) */ - if (ret < 0) { - RLOGE("Failed to listen on control socket '%d': %s", - s_fdListen, strerror(errno)); - exit(-1); - } -#endif +#if (SIM_COUNT >= 3) + // start listen socket3 + startListen(RIL_SOCKET_3, &s_ril_param_socket3); +#endif /* (SIM_COUNT == 3) */ +#if (SIM_COUNT >= 4) + // start listen socket4 + startListen(RIL_SOCKET_4, &s_ril_param_socket4); +#endif /* (SIM_COUNT == 4) */ - /* note: non-persistent so we can accept only one connection at a time */ - ril_event_set (&s_listen_event, s_fdListen, false, - listenCallback, NULL); - - rilEventAddWakeup (&s_listen_event); #if 1 // start debug interface socket - s_fdDebug = android_get_control_socket(SOCKET_NAME_RIL_DEBUG); + char *inst = NULL; + if (strlen(RIL_getRilSocketName()) >= strlen(SOCKET_NAME_RIL)) { + inst = RIL_getRilSocketName() + strlen(SOCKET_NAME_RIL); + } + + char rildebug[MAX_DEBUG_SOCKET_NAME_LENGTH] = SOCKET_NAME_RIL_DEBUG; + if (inst != NULL) { + strncat(rildebug, inst, MAX_DEBUG_SOCKET_NAME_LENGTH); + } + + s_fdDebug = android_get_control_socket(rildebug); if (s_fdDebug < 0) { - RLOGE("Failed to get socket '" SOCKET_NAME_RIL_DEBUG "' errno:%d", errno); + RLOGE("Failed to get socket : %s errno:%d", rildebug, errno); exit(-1); } @@ -3395,14 +3888,37 @@ RIL_register (const RIL_RadioFunctions *callbacks) { static int checkAndDequeueRequestInfo(struct RequestInfo *pRI) { 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; } - pthread_mutex_lock(&s_pendingRequestsMutex); +#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 = &s_pendingRequests + for(RequestInfo **ppCur = pendingRequestsHook ; *ppCur != NULL ; ppCur = &((*ppCur)->p_next) ) { @@ -3414,7 +3930,7 @@ checkAndDequeueRequestInfo(struct RequestInfo *pRI) { } } - pthread_mutex_unlock(&s_pendingRequestsMutex); + pthread_mutex_unlock(pendingRequestsMutexHook); return ret; } @@ -3424,10 +3940,30 @@ extern "C" void RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) { RequestInfo *pRI; int ret; + int fd = s_ril_param_socket.fdCommand; size_t errorOffset; + RIL_SOCKET_ID socket_id = RIL_SOCKET_1; pRI = (RequestInfo *)t; + socket_id = pRI->socket_id; +#if (SIM_COUNT >= 2) + if (socket_id == RIL_SOCKET_2) { + fd = s_ril_param_socket2.fdCommand; + } +#if (SIM_COUNT >= 3) + if (socket_id == RIL_SOCKET_3) { + fd = s_ril_param_socket3.fdCommand; + } +#endif +#if (SIM_COUNT >= 4) + if (socket_id == RIL_SOCKET_4) { + fd = s_ril_param_socket4.fdCommand; + } +#endif +#endif + RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id)); + if (!checkAndDequeueRequestInfo(pRI)) { RLOGE ("RIL_onRequestComplete: invalid RIL_Token"); return; @@ -3459,6 +3995,7 @@ RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responsel /* if an error occurred, rewind and mark it */ if (ret != 0) { + RLOGE ("responseFunction error, ret %d", ret); p.setDataPosition(errorOffset); p.writeInt32 (ret); } @@ -3468,10 +4005,10 @@ RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responsel appendPrintBuf("%s fails by %s", printBuf, failCauseToString(e)); } - if (s_fdCommand < 0) { + if (fd < 0) { RLOGD ("RIL onRequestComplete: Command channel closed"); } - sendResponse(p); + sendResponse(p, socket_id); } done: @@ -3585,7 +4122,7 @@ static bool is3gpp2(int radioTech) { * returned when telephony framework requests them */ static RIL_RadioState -processRadioState(RIL_RadioState newRadioState) { +processRadioState(RIL_RadioState newRadioState, RIL_SOCKET_ID socket_id) { if((newRadioState > RADIO_STATE_UNAVAILABLE) && (newRadioState < RADIO_STATE_ON)) { int newVoiceRadioTech; @@ -3597,21 +4134,21 @@ processRadioState(RIL_RadioState newRadioState) { newVoiceRadioTech = decodeVoiceRadioTechnology(newRadioState); if(newVoiceRadioTech != voiceRadioTech) { voiceRadioTech = newVoiceRadioTech; - RIL_onUnsolicitedResponse (RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, - &voiceRadioTech, sizeof(voiceRadioTech)); + RIL_UNSOL_RESPONSE(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, + &voiceRadioTech, sizeof(voiceRadioTech), socket_id); } if(is3gpp2(newVoiceRadioTech)) { newCdmaSubscriptionSource = decodeCdmaSubscriptionSource(newRadioState); if(newCdmaSubscriptionSource != cdmaSubscriptionSource) { cdmaSubscriptionSource = newCdmaSubscriptionSource; - RIL_onUnsolicitedResponse (RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, - &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource)); + RIL_UNSOL_RESPONSE(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, + &cdmaSubscriptionSource, sizeof(cdmaSubscriptionSource), socket_id); } } newSimStatus = decodeSimStatus(newRadioState); if(newSimStatus != simRuimStatus) { simRuimStatus = newSimStatus; - RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0); + RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0, socket_id); } /* Send RADIO_ON to telephony */ @@ -3621,15 +4158,28 @@ processRadioState(RIL_RadioState newRadioState) { return newRadioState; } + +#if defined(ANDROID_MULTI_SIM) extern "C" -void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, +void RIL_onUnsolicitedResponse(int unsolResponse, void *data, + size_t datalen, RIL_SOCKET_ID socket_id) +#else +extern "C" +void RIL_onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) +#endif { int unsolResponseIndex; int ret; int64_t timeReceived = 0; bool shouldScheduleTimeout = false; RIL_RadioState newState; + 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 @@ -3686,10 +4236,10 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, // some things get more payload switch(unsolResponse) { case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: - newState = processRadioState(s_callbacks.onStateRequest()); + newState = processRadioState(CALL_ONSTATEREQUEST(soc_id), soc_id); p.writeInt32(newState); appendPrintBuf("%s {%s}", printBuf, - radioStateToString(s_callbacks.onStateRequest())); + radioStateToString(CALL_ONSTATEREQUEST(soc_id))); break; @@ -3703,7 +4253,8 @@ void RIL_onUnsolicitedResponse(int unsolResponse, const void *data, break; } - ret = sendResponse(p); + RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize()); + ret = sendResponse(p, soc_id); if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) { // Unfortunately, NITZ time is not poll/update like everything @@ -3964,6 +4515,9 @@ requestToString(int request) { 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_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_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"; @@ -4001,8 +4555,34 @@ requestToString(int request) { 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 "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 "HARDWARE_CONFIG_CHANGED"; default: return "<unknown request>"; } } +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 */ |