#include <cutils/jstring.h>
#include <sys/types.h>
#include <sys/limits.h>
+#include <sys/system_properties.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
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 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"
/* 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
/* Negative values for private RIL errno's */
#define RIL_ERRNO_INVALID_RESPONSE -1
// request, response, and unsolicited msg print macro
#define PRINTBUF_SIZE 8096
+// Enable verbose logging
+#define VDBG 0
+
// Enable RILC log
#define RILC_LOG 0
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 UserCallbackInfo {
static int s_fdWakeupRead;
static int s_fdWakeupWrite;
+int s_wakelock_count = 0;
+
static struct ril_event s_commands_event;
static struct ril_event s_wakeupfd_event;
static struct ril_event s_listen_event;
static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t s_writeMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER;
static RequestInfo *s_pendingRequests = NULL;
#if (SIM_COUNT >= 2)
static struct ril_event s_debug_event;
-static const struct timeval TIMEVAL_WAKE_TIMEOUT = {1,0};
+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 void dispatchDataProfile(Parcel &p, RequestInfo *pRI);
static void dispatchRadioCapability(Parcel &p, RequestInfo *pRI);
static int responseInts(Parcel &p, void *response, size_t responselen);
+static int responseFailCause(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);
static int responseVoid(Parcel &p, void *response, size_t responselen);
static int responseSSData(Parcel &p, void *response, size_t responselen);
static int responseLceStatus(Parcel &p, void *response, size_t responselen);
static int responseLceData(Parcel &p, void *response, size_t responselen);
+static int responseActivityData(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);
+static void grabPartialWakeLock();
+static void releaseWakeLock();
+static void wakeTimeoutCallback(void *);
static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
+static bool isDebuggable();
+
#ifdef RIL_SHLIB
#if defined(ANDROID_MULTI_SIM)
extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
return 0;
}
+ // Received an Ack for the previous result sent to RIL.java,
+ // so release wakelock and exit
+ if (request == RIL_RESPONSE_ACKNOWLEDGEMENT) {
+ releaseWakeLock();
+ return 0;
+ }
+
pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
int size;
status_t status;
+#if VDBG
RLOGD("dispatchSIM_IO");
+#endif
memset (&simIO, 0, sizeof(simIO));
// note we only check status at the end
status_t status;
RIL_SIM_APDU apdu;
+#if VDBG
RLOGD("dispatchSIM_APDU");
+#endif
memset (&apdu, 0, sizeof(RIL_SIM_APDU));
// Note we only check status at the end. Any single failure leads to
uint8_t uct;
status_t status;
int32_t digitCount;
+ int32_t digitLimit;
memset(&rcsw, 0, sizeof(rcsw));
status = p.read(&uct,sizeof(uct));
rcsw.message.sAddress.number_of_digits = (uint8_t) uct;
- for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_ADDRESS_MAX; digitCount ++) {
+ digitLimit = MIN((rcsw.message.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+
+ for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
status = p.read(&uct,sizeof(uct));
rcsw.message.sAddress.digits[digitCount] = (uint8_t) uct;
}
status = p.read(&uct,sizeof(uct));
rcsw.message.sSubAddress.number_of_digits = (uint8_t) uct;
- for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_SUBADDRESS_MAX; digitCount ++) {
+ digitLimit = MIN((rcsw.message.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+
+ for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
status = p.read(&uct,sizeof(uct));
rcsw.message.sSubAddress.digits[digitCount] = (uint8_t) uct;
}
status = p.readInt32(&t);
rcsw.message.uBearerDataLen = (int) t;
- for(digitCount = 0 ; digitCount < RIL_CDMA_SMS_BEARER_DATA_MAX; digitCount ++) {
+ digitLimit = MIN((rcsw.message.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+
+ for(digitCount = 0 ; digitCount < digitLimit; digitCount ++) {
status = p.read(&uct, sizeof(uct));
rcsw.message.aBearerData[digitCount] = (uint8_t) uct;
}
startRequest;
appendPrintBuf("%s [version:%d, session:%d, phase:%d, rat:%d, \
- logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session
+ logicalModemUuid:%s, status:%d", printBuf, rc.version, rc.session,
rc.phase, rc.rat, rc.logicalModemUuid, rc.session);
closeRequest;
return -1;
}
}
+#if VDBG
RLOGE("RIL Response bytes written:%d", writeOffset);
+#endif
return 0;
}
uint32_t header;
pthread_mutex_t * writeMutexHook = &s_writeMutex;
+#if VDBG
RLOGE("Send Response to %s", rilSocketIdToString(socket_id));
+#endif
#if (SIM_COUNT >= 2)
if (socket_id == RIL_SOCKET_2) {
return 0;
}
+// Response is an int or RIL_LastCallFailCauseInfo.
+// Currently, only Shamu plans to use RIL_LastCallFailCauseInfo.
+// TODO(yjl): Let all implementations use RIL_LastCallFailCauseInfo.
+static int responseFailCause(Parcel &p, void *response, size_t responselen) {
+ if (response == NULL && responselen != 0) {
+ RLOGE("invalid response: NULL");
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
+
+ if (responselen == sizeof(int)) {
+ startResponse;
+ int *p_int = (int *) response;
+ appendPrintBuf("%s%d,", printBuf, p_int[0]);
+ p.writeInt32(p_int[0]);
+ removeLastChar;
+ closeResponse;
+ } else if (responselen == sizeof(RIL_LastCallFailCauseInfo)) {
+ startResponse;
+ RIL_LastCallFailCauseInfo *p_fail_cause_info = (RIL_LastCallFailCauseInfo *) response;
+ appendPrintBuf("%s[cause_code=%d,vendor_cause=%s]", printBuf, p_fail_cause_info->cause_code,
+ p_fail_cause_info->vendor_cause);
+ p.writeInt32(p_fail_cause_info->cause_code);
+ writeStringToParcel(p, p_fail_cause_info->vendor_cause);
+ removeLastChar;
+ closeResponse;
+ } else {
+ RLOGE("responseFailCause: invalid response length %d expected an int or "
+ "RIL_LastCallFailCauseInfo", (int)responselen);
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
+
+ return 0;
+}
+
/** response is a char **, pointing to an array of char *'s
The parcel will begin with the version */
static int responseStringsWithVersion(int version, Parcel &p, void *response, size_t responselen) {
return 0;
}
+static int responseDataCallListV11(Parcel &p, void *response, size_t responselen) {
+ if (response == NULL && responselen != 0) {
+ RLOGE("invalid response: NULL");
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
-static int responseDataCallList(Parcel &p, void *response, size_t responselen)
-{
- if (s_callbacks.version < 5) {
- RLOGD("responseDataCallList: v4");
- return responseDataCallListV4(p, response, responselen);
- } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
- return responseDataCallListV6(p, response, responselen);
- } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
- return responseDataCallListV9(p, response, responselen);
- } else {
- if (response == NULL && responselen != 0) {
- RLOGE("invalid response: NULL");
- return RIL_ERRNO_INVALID_RESPONSE;
- }
-
- if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
- RLOGE("invalid response length %d expected multiple of %d",
- (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
- return RIL_ERRNO_INVALID_RESPONSE;
- }
+ if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+ RLOGE("invalid response length %d expected multiple of %d",
+ (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
- // Write version
- p.writeInt32(11);
+ // Write version
+ p.writeInt32(11);
- int num = responselen / sizeof(RIL_Data_Call_Response_v11);
- p.writeInt32(num);
+ int num = responselen / sizeof(RIL_Data_Call_Response_v11);
+ p.writeInt32(num);
- RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) 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);
- writeStringToParcel(p, p_cur[i].pcscf);
- p.writeInt32(p_cur[i].mtu);
- appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", 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,
- (char*)p_cur[i].pcscf,
- p_cur[i].mtu);
- }
- removeLastChar;
- closeResponse;
+ RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) 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);
+ writeStringToParcel(p, p_cur[i].pcscf);
+ p.writeInt32(p_cur[i].mtu);
+ appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", 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,
+ (char*)p_cur[i].pcscf,
+ p_cur[i].mtu);
}
+ removeLastChar;
+ closeResponse;
return 0;
}
+static int responseDataCallList(Parcel &p, void *response, size_t responselen)
+{
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (s_callbacks.version < 5) {
+ RLOGD("responseDataCallList: v4");
+ return responseDataCallListV4(p, response, responselen);
+ } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
+ return responseDataCallListV6(p, response, responselen);
+ } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
+ return responseDataCallListV9(p, response, responselen);
+ } else {
+ return responseDataCallListV11(p, response, responselen);
+ }
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+ RLOGE("Data structure expected is RIL_Data_Call_Response_v11");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
+ return responseDataCallListV11(p, response, responselen);
+ }
+}
+
static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
{
if (s_callbacks.version < 5) {
return 0;
}
+static void responseRilSignalStrengthV5(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+ p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
+ p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
+ p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
+ p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
+ p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
+ p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
+ p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
+}
+
+static void responseRilSignalStrengthV6Extra(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+ /*
+ * Fixup LTE for backwards compatibility
+ */
+ // signalStrength: -1 -> 99
+ if (p_cur->LTE_SignalStrength.signalStrength == -1) {
+ p_cur->LTE_SignalStrength.signalStrength = 99;
+ }
+ // rsrp: -1 -> INT_MAX all other negative value to positive.
+ // So remap here
+ if (p_cur->LTE_SignalStrength.rsrp == -1) {
+ p_cur->LTE_SignalStrength.rsrp = INT_MAX;
+ } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
+ p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
+ }
+ // rsrq: -1 -> INT_MAX
+ if (p_cur->LTE_SignalStrength.rsrq == -1) {
+ p_cur->LTE_SignalStrength.rsrq = INT_MAX;
+ }
+ // Not remapping rssnr is already using INT_MAX
+
+ // cqi: -1 -> INT_MAX
+ if (p_cur->LTE_SignalStrength.cqi == -1) {
+ p_cur->LTE_SignalStrength.cqi = INT_MAX;
+ }
+
+ p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
+ p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
+ p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
+ p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
+ p.writeInt32(p_cur->LTE_SignalStrength.cqi);
+}
+
+static void responseRilSignalStrengthV10(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+ responseRilSignalStrengthV5(p, p_cur);
+ responseRilSignalStrengthV6Extra(p, p_cur);
+ p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+}
+
static int responseRilSignalStrength(Parcel &p,
void *response, size_t responselen) {
if (response == NULL && responselen != 0) {
return RIL_ERRNO_INVALID_RESPONSE;
}
- if (responselen >= sizeof (RIL_SignalStrength_v5)) {
- RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (responselen >= sizeof (RIL_SignalStrength_v5)) {
+ RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
- p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
- p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
- p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
- p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
- p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
- p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
- p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
- if (responselen >= sizeof (RIL_SignalStrength_v6)) {
- /*
- * Fixup LTE for backwards compatibility
- */
- if (s_callbacks.version <= 6) {
- // signalStrength: -1 -> 99
- if (p_cur->LTE_SignalStrength.signalStrength == -1) {
- p_cur->LTE_SignalStrength.signalStrength = 99;
- }
- // rsrp: -1 -> INT_MAX all other negative value to positive.
- // So remap here
- if (p_cur->LTE_SignalStrength.rsrp == -1) {
- p_cur->LTE_SignalStrength.rsrp = INT_MAX;
- } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
- p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
- }
- // rsrq: -1 -> INT_MAX
- if (p_cur->LTE_SignalStrength.rsrq == -1) {
- p_cur->LTE_SignalStrength.rsrq = INT_MAX;
- }
- // Not remapping rssnr is already using INT_MAX
+ responseRilSignalStrengthV5(p, p_cur);
- // cqi: -1 -> INT_MAX
- if (p_cur->LTE_SignalStrength.cqi == -1) {
- p_cur->LTE_SignalStrength.cqi = INT_MAX;
+ if (responselen >= sizeof (RIL_SignalStrength_v6)) {
+ responseRilSignalStrengthV6Extra(p, p_cur);
+ if (responselen >= sizeof (RIL_SignalStrength_v10)) {
+ p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+ } else {
+ p.writeInt32(INT_MAX);
}
- }
- p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
- p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
- 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(99);
+ p.writeInt32(INT_MAX);
+ p.writeInt32(INT_MAX);
+ p.writeInt32(INT_MAX);
+ p.writeInt32(INT_MAX);
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);
+ RLOGE("invalid response length");
+ return RIL_ERRNO_INVALID_RESPONSE;
}
-
- startResponse;
- appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
- CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
- 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,TDSCDMA_SS.rscp=%d]",
- printBuf,
- p_cur->GW_SignalStrength.signalStrength,
- p_cur->GW_SignalStrength.bitErrorRate,
- p_cur->CDMA_SignalStrength.dbm,
- p_cur->CDMA_SignalStrength.ecio,
- p_cur->EVDO_SignalStrength.dbm,
- p_cur->EVDO_SignalStrength.ecio,
- p_cur->EVDO_SignalStrength.signalNoiseRatio,
- p_cur->LTE_SignalStrength.signalStrength,
- p_cur->LTE_SignalStrength.rsrp,
- p_cur->LTE_SignalStrength.rsrq,
- p_cur->LTE_SignalStrength.rssnr,
- p_cur->LTE_SignalStrength.cqi,
- p_cur->TD_SCDMA_SignalStrength.rscp);
- closeResponse;
-
- } else {
- RLOGE("invalid response length");
- return RIL_ERRNO_INVALID_RESPONSE;
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_SignalStrength_v10) != 0) {
+ RLOGE("Data structure expected is RIL_SignalStrength_v10");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
+ RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+ responseRilSignalStrengthV10(p, p_cur);
}
-
+ startResponse;
+ appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
+ CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
+ 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,TDSCDMA_SS.rscp=%d]",
+ printBuf,
+ p_cur->GW_SignalStrength.signalStrength,
+ p_cur->GW_SignalStrength.bitErrorRate,
+ p_cur->CDMA_SignalStrength.dbm,
+ p_cur->CDMA_SignalStrength.ecio,
+ p_cur->EVDO_SignalStrength.dbm,
+ p_cur->EVDO_SignalStrength.ecio,
+ p_cur->EVDO_SignalStrength.signalNoiseRatio,
+ p_cur->LTE_SignalStrength.signalStrength,
+ p_cur->LTE_SignalStrength.rsrp,
+ p_cur->LTE_SignalStrength.rsrq,
+ p_cur->LTE_SignalStrength.rssnr,
+ p_cur->LTE_SignalStrength.cqi,
+ p_cur->TD_SCDMA_SignalStrength.rscp);
+ closeResponse;
return 0;
}
writeStringToParcel(p, p_cur->name);
marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
- if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
+ p.writeInt32(p_cur->number_type);
+ p.writeInt32(p_cur->number_plan);
+ } else {
+ p.writeInt32(0);
+ p.writeInt32(0);
+ }
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_CDMA_CallWaiting_v6) != 0) {
+ RLOGE("Data structure expected is RIL_CDMA_CallWaiting_v6");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
p.writeInt32(p_cur->number_type);
p.writeInt32(p_cur->number_plan);
- } else {
- p.writeInt32(0);
- p.writeInt32(0);
}
startResponse;
return 0;
}
+static void responseSimRefreshV7(Parcel &p, void *response) {
+ RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
+ p.writeInt32(p_cur->result);
+ p.writeInt32(p_cur->ef_id);
+ writeStringToParcel(p, p_cur->aid);
+
+ appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
+ printBuf,
+ p_cur->result,
+ p_cur->ef_id,
+ p_cur->aid);
+
+}
+
static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
if (response == NULL && responselen != 0) {
RLOGE("responseSimRefresh: invalid response: NULL");
}
startResponse;
- if (s_callbacks.version == 7) {
- RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
- p.writeInt32(p_cur->result);
- p.writeInt32(p_cur->ef_id);
- writeStringToParcel(p, p_cur->aid);
-
- appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
- printBuf,
- p_cur->result,
- p_cur->ef_id,
- p_cur->aid);
- } else {
- int *p_cur = ((int *) response);
- p.writeInt32(p_cur[0]);
- p.writeInt32(p_cur[1]);
- writeStringToParcel(p, NULL);
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (s_callbacks.version >= 7) {
+ responseSimRefreshV7(p, response);
+ } else {
+ int *p_cur = ((int *) response);
+ p.writeInt32(p_cur[0]);
+ p.writeInt32(p_cur[1]);
+ writeStringToParcel(p, NULL);
+
+ appendPrintBuf("%sresult=%d, ef_id=%d",
+ printBuf,
+ p_cur[0],
+ p_cur[1]);
+ }
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_SimRefreshResponse_v7) != 0) {
+ RLOGE("Data structure expected is RIL_SimRefreshResponse_v7");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
+ responseSimRefreshV7(p, response);
- appendPrintBuf("%sresult=%d, ef_id=%d",
- printBuf,
- p_cur[0],
- p_cur[1]);
}
closeResponse;
return 0;
}
-static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
-{
+static int responseCellInfoListV6(Parcel &p, void *response, size_t responselen) {
if (response == NULL && responselen != 0) {
RLOGE("invalid response: NULL");
return RIL_ERRNO_INVALID_RESPONSE;
return 0;
}
+static int responseCellInfoListV12(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_CellInfo_v12) != 0) {
+ RLOGE("responseCellInfoList: invalid response length %d expected multiple of %d",
+ (int)responselen, (int)sizeof(RIL_CellInfo_v12));
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
+
+ int num = responselen / sizeof(RIL_CellInfo_v12);
+ p.writeInt32(num);
+
+ RIL_CellInfo_v12 *p_cur = (RIL_CellInfo_v12 *) response;
+ startResponse;
+ int i;
+ for (i = 0; i < num; i++) {
+ appendPrintBuf("%s[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", printBuf, i,
+ p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
+ RLOGE("[%d: type=%d,registered=%d,timeStampType=%d,timeStamp=%lld", i,
+ p_cur->cellInfoType, p_cur->registered, p_cur->timeStampType, p_cur->timeStamp);
+ p.writeInt32((int)p_cur->cellInfoType);
+ p.writeInt32(p_cur->registered);
+ p.writeInt32(p_cur->timeStampType);
+ p.writeInt64(p_cur->timeStamp);
+ switch(p_cur->cellInfoType) {
+ case RIL_CELL_INFO_TYPE_GSM: {
+ appendPrintBuf("%s GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,arfcn=%d,bsic=%x", printBuf,
+ p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
+ p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
+ p_cur->CellInfo.gsm.cellIdentityGsm.lac,
+ p_cur->CellInfo.gsm.cellIdentityGsm.cid,
+ p_cur->CellInfo.gsm.cellIdentityGsm.arfcn,
+ p_cur->CellInfo.gsm.cellIdentityGsm.bsic);
+ RLOGE("GSM id: mcc=%d,mnc=%d,lac=%d,cid=%d,arfcn=%d,bsic=%x",
+ p_cur->CellInfo.gsm.cellIdentityGsm.mcc,
+ p_cur->CellInfo.gsm.cellIdentityGsm.mnc,
+ p_cur->CellInfo.gsm.cellIdentityGsm.lac,
+ p_cur->CellInfo.gsm.cellIdentityGsm.cid,
+ p_cur->CellInfo.gsm.cellIdentityGsm.arfcn,
+ p_cur->CellInfo.gsm.cellIdentityGsm.bsic);
+ RLOGE("gsmSS: ss=%d,ber=%d, ta=%d],",
+ p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
+ p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate,
+ p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance);
+ appendPrintBuf("%s gsmSS: ss=%d,ber=%d, ta=%d],", printBuf,
+ p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength,
+ p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate,
+ p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance);
+
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mcc);
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.mnc);
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.lac);
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.cid);
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.arfcn);
+ p.writeInt32(p_cur->CellInfo.gsm.cellIdentityGsm.bsic);
+ p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.signalStrength);
+ p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.bitErrorRate);
+ p.writeInt32(p_cur->CellInfo.gsm.signalStrengthGsm.timingAdvance);
+ break;
+ }
+ case RIL_CELL_INFO_TYPE_WCDMA: {
+ RLOGE("WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,uarfcn=%d",
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.psc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn);
+ RLOGE("wcdmaSS: ss=%d,ber=%d],",
+ p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
+ p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+ appendPrintBuf("%s WCDMA id: mcc=%d,mnc=%d,lac=%d,cid=%d,psc=%d,uarfcn=%d", printBuf,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.lac,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.cid,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.psc,
+ p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn);
+ appendPrintBuf("%s wcdmaSS: ss=%d,ber=%d],", printBuf,
+ p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
+ p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mcc);
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.mnc);
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.lac);
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.cid);
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.psc);
+ p.writeInt32(p_cur->CellInfo.wcdma.cellIdentityWcdma.uarfcn);
+ p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
+ p.writeInt32(p_cur->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
+ break;
+ }
+ case RIL_CELL_INFO_TYPE_CDMA: {
+ RLOGE("CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d",
+ p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
+ p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
+
+ appendPrintBuf("%s CDMA id: nId=%d,sId=%d,bsId=%d,long=%d,lat=%d", printBuf,
+ p_cur->CellInfo.cdma.cellIdentityCdma.networkId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.systemId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.basestationId,
+ p_cur->CellInfo.cdma.cellIdentityCdma.longitude,
+ p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
+
+ p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.networkId);
+ p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.systemId);
+ p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.basestationId);
+ p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.longitude);
+ p.writeInt32(p_cur->CellInfo.cdma.cellIdentityCdma.latitude);
+
+ RLOGE("cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d",
+ p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
+ p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+
+ appendPrintBuf("%s cdmaSS: dbm=%d ecio=%d evdoSS: dbm=%d,ecio=%d,snr=%d", printBuf,
+ p_cur->CellInfo.cdma.signalStrengthCdma.dbm,
+ p_cur->CellInfo.cdma.signalStrengthCdma.ecio,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.dbm,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.ecio,
+ p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+
+ p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.dbm);
+ p.writeInt32(p_cur->CellInfo.cdma.signalStrengthCdma.ecio);
+ p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.dbm);
+ p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.ecio);
+ p.writeInt32(p_cur->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio);
+ break;
+ }
+ case RIL_CELL_INFO_TYPE_LTE: {
+ RLOGE("LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,earfcn=%d",
+ p_cur->CellInfo.lte.cellIdentityLte.mcc,
+ p_cur->CellInfo.lte.cellIdentityLte.mnc,
+ p_cur->CellInfo.lte.cellIdentityLte.ci,
+ p_cur->CellInfo.lte.cellIdentityLte.pci,
+ p_cur->CellInfo.lte.cellIdentityLte.tac,
+ p_cur->CellInfo.lte.cellIdentityLte.earfcn);
+
+ appendPrintBuf("%s LTE id: mcc=%d,mnc=%d,ci=%d,pci=%d,tac=%d,earfcn=%d", printBuf,
+ p_cur->CellInfo.lte.cellIdentityLte.mcc,
+ p_cur->CellInfo.lte.cellIdentityLte.mnc,
+ p_cur->CellInfo.lte.cellIdentityLte.ci,
+ p_cur->CellInfo.lte.cellIdentityLte.pci,
+ p_cur->CellInfo.lte.cellIdentityLte.tac,
+ p_cur->CellInfo.lte.cellIdentityLte.earfcn);
+
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mcc);
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.mnc);
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.ci);
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.pci);
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.tac);
+ p.writeInt32(p_cur->CellInfo.lte.cellIdentityLte.earfcn);
+
+ RLOGE("lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d",
+ p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
+ p_cur->CellInfo.lte.signalStrengthLte.rsrp,
+ p_cur->CellInfo.lte.signalStrengthLte.rsrq,
+ p_cur->CellInfo.lte.signalStrengthLte.rssnr,
+ p_cur->CellInfo.lte.signalStrengthLte.cqi,
+ p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
+ appendPrintBuf("%s lteSS: ss=%d,rsrp=%d,rsrq=%d,rssnr=%d,cqi=%d,ta=%d", printBuf,
+ p_cur->CellInfo.lte.signalStrengthLte.signalStrength,
+ p_cur->CellInfo.lte.signalStrengthLte.rsrp,
+ p_cur->CellInfo.lte.signalStrengthLte.rsrq,
+ p_cur->CellInfo.lte.signalStrengthLte.rssnr,
+ p_cur->CellInfo.lte.signalStrengthLte.cqi,
+ p_cur->CellInfo.lte.signalStrengthLte.timingAdvance);
+ p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.signalStrength);
+ p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrp);
+ p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rsrq);
+ p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.rssnr);
+ p.writeInt32(p_cur->CellInfo.lte.signalStrengthLte.cqi);
+ 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;
+ }
+ removeLastChar;
+ closeResponse;
+ return 0;
+}
+
+static int responseCellInfoList(Parcel &p, void *response, size_t responselen)
+{
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (s_callbacks.version < 12) {
+ RLOGD("responseCellInfoList: v6");
+ return responseCellInfoListV6(p, response, responselen);
+ } else {
+ RLOGD("responseCellInfoList: v12");
+ return responseCellInfoListV12(p, response, responselen);
+ }
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_CellInfo_v12) != 0) {
+ RLOGE("Data structure expected is RIL_CellInfo_v12");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
+ return responseCellInfoListV12(p, response, responselen);
+ }
+
+ return 0;
+}
+
static int responseHardwareConfig(Parcel &p, void *response, size_t responselen)
{
if (response == NULL && responselen != 0) {
closeResponse;
}
+static void responseSimStatusV5(Parcel &p, void *response) {
+ RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
+
+ p.writeInt32(p_cur->card_state);
+ p.writeInt32(p_cur->universal_pin_state);
+ p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+ p.writeInt32(p_cur->cdma_subscription_app_index);
+
+ sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+}
+
+static void responseSimStatusV6(Parcel &p, void *response) {
+ RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+
+ p.writeInt32(p_cur->card_state);
+ p.writeInt32(p_cur->universal_pin_state);
+ p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+ p.writeInt32(p_cur->cdma_subscription_app_index);
+ p.writeInt32(p_cur->ims_subscription_app_index);
+
+ sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+}
+
static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
int i;
return RIL_ERRNO_INVALID_RESPONSE;
}
- if (responselen == sizeof (RIL_CardStatus_v6)) {
- RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
-
- p.writeInt32(p_cur->card_state);
- p.writeInt32(p_cur->universal_pin_state);
- p.writeInt32(p_cur->gsm_umts_subscription_app_index);
- p.writeInt32(p_cur->cdma_subscription_app_index);
- p.writeInt32(p_cur->ims_subscription_app_index);
-
- sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
- } else if (responselen == sizeof (RIL_CardStatus_v5)) {
- RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
-
- p.writeInt32(p_cur->card_state);
- p.writeInt32(p_cur->universal_pin_state);
- p.writeInt32(p_cur->gsm_umts_subscription_app_index);
- p.writeInt32(p_cur->cdma_subscription_app_index);
- p.writeInt32(-1);
-
- sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
- } else {
- RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
- return RIL_ERRNO_INVALID_RESPONSE;
+ if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+ if (responselen == sizeof (RIL_CardStatus_v6)) {
+ responseSimStatusV6(p, response);
+ } else if (responselen == sizeof (RIL_CardStatus_v5)) {
+ responseSimStatusV5(p, response);
+ } else {
+ RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
+ } else { // RIL version >= 13
+ if (responselen % sizeof(RIL_CardStatus_v6) != 0) {
+ RLOGE("Data structure expected is RIL_CardStatus_v6");
+ if (!isDebuggable()) {
+ return RIL_ERRNO_INVALID_RESPONSE;
+ } else {
+ assert(0);
+ }
+ }
+ responseSimStatusV6(p, response);
}
return 0;
return 0;
}
+static int responseActivityData(Parcel &p, void *response, size_t responselen) {
+ if (response == NULL || responselen != sizeof(RIL_ActivityStatsInfo)) {
+ if (response == NULL) {
+ RLOGE("invalid response: NULL");
+ }
+ else {
+ RLOGE("responseActivityData: invalid response length %d expecting len: d%",
+ sizeof(RIL_ActivityStatsInfo), responselen);
+ }
+ return RIL_ERRNO_INVALID_RESPONSE;
+ }
+
+ RIL_ActivityStatsInfo *p_cur = (RIL_ActivityStatsInfo *)response;
+ p.writeInt32(p_cur->sleep_mode_time_ms);
+ p.writeInt32(p_cur->idle_mode_time_ms);
+ for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
+ p.writeInt32(p_cur->tx_mode_time_ms[i]);
+ }
+ p.writeInt32(p_cur->rx_mode_time_ms);
+
+ startResponse;
+ appendPrintBuf("Modem activity info received: sleep_mode_time_ms %d idle_mode_time_ms %d
+ tx_mode_time_ms %d %d %d %d %d and rx_mode_time_ms %d",
+ p_cur->sleep_mode_time_ms, p_cur->idle_mode_time_ms, p_cur->tx_mode_time_ms[0],
+ p_cur->tx_mode_time_ms[1], p_cur->tx_mode_time_ms[2], p_cur->tx_mode_time_ms[3],
+ p_cur->tx_mode_time_ms[4], p_cur->rx_mode_time_ms);
+ closeResponse;
+
+ return 0;
+}
+
/**
* 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
callbacks->version, RIL_VERSION_MIN);
return;
}
- if (callbacks->version > RIL_VERSION) {
- RLOGE("RIL_register: version %d is too new, max version is %d",
- callbacks->version, RIL_VERSION);
- return;
- }
+
RLOGE("RIL_register: RIL version %d", callbacks->version);
if (s_registerCalled > 0) {
}
}
+// Check and remove RequestInfo if its a response and not just ack sent back
static int
-checkAndDequeueRequestInfo(struct RequestInfo *pRI) {
+checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) {
int ret = 0;
/* Hook for current context
pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
) {
if (pRI == *ppCur) {
ret = 1;
-
- *ppCur = (*ppCur)->p_next;
+ 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;
}
}
return ret;
}
+static int findFd(int socket_id) {
+ int fd = s_ril_param_socket.fdCommand;
+#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
+ return fd;
+}
+
+extern "C" void
+RIL_onRequestAck(RIL_Token t) {
+ RequestInfo *pRI;
+ int ret, fd;
+
+ size_t errorOffset;
+ 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;
+ fd = findFd(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) {
+ Parcel p;
+
+ p.writeInt32 (RESPONSE_SOLICITED_ACK);
+ p.writeInt32 (pRI->token);
+
+ if (fd < 0) {
+ RLOGD ("RIL onRequestComplete: Command channel closed");
+ }
+
+ sendResponse(p, socket_id);
+ }
+}
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;
+ int fd;
size_t errorOffset;
RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
pRI = (RequestInfo *)t;
- if (!checkAndDequeueRequestInfo(pRI)) {
+ if (!checkAndDequeueRequestInfoIfAck(pRI, false)) {
RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
return;
}
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
+ fd = findFd(socket_id);
+
+#if VDBG
RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
+#endif
if (pRI->local > 0) {
// Locally issued command...void only!
if (pRI->cancelled == 0) {
Parcel p;
- p.writeInt32 (RESPONSE_SOLICITED);
+ 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.
+ p.writeInt32 (RESPONSE_SOLICITED_ACK_EXP);
+ grabPartialWakeLock();
+ } else {
+ p.writeInt32 (RESPONSE_SOLICITED);
+ }
p.writeInt32 (pRI->token);
errorOffset = p.dataPosition();
free(pRI);
}
-
static void
grabPartialWakeLock() {
- acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+ 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);
+ s_wakelock_count++;
+ if (s_last_wake_timeout_info != NULL) {
+ s_last_wake_timeout_info->userParam = (void *)1;
+ }
+
+ s_last_wake_timeout_info
+ = internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT);
+
+ ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+ assert(ret == 0);
+ } else {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+ }
}
static void
releaseWakeLock() {
- release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+ 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);
+ }
}
/**
static void
wakeTimeoutCallback (void *param) {
// We're using "param != NULL" as a cancellation mechanism
- if (param == NULL) {
- releaseWakeLock();
+ 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();
+ }
}
}
appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
Parcel p;
-
- p.writeInt32 (RESPONSE_UNSOLICITED);
+ if (s_callbacks.version >= 13
+ && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) {
+ p.writeInt32 (RESPONSE_UNSOLICITED_ACK_EXP);
+ } else {
+ p.writeInt32 (RESPONSE_UNSOLICITED);
+ }
p.writeInt32 (unsolResponse);
ret = s_unsolResponses[unsolResponseIndex]
break;
}
+#if VDBG
RLOGI("%s UNSOLICITED: %s length:%d", rilSocketIdToString(soc_id), requestToString(unsolResponse), p.dataSize());
+#endif
ret = sendResponse(p, soc_id);
if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
memcpy(s_lastNITZTimeData, p.data(), p.dataSize());
}
- // For now, we automatically go back to sleep after TIMEVAL_WAKE_TIMEOUT
- // FIXME The java code should handshake here to release wake lock
+ if (s_callbacks.version < 13) {
+ if (shouldScheduleTimeout) {
+ // Cancel the previous request
+ if (s_last_wake_timeout_info != NULL) {
+ s_last_wake_timeout_info->userParam = (void *)1;
+ }
- if (shouldScheduleTimeout) {
- // Cancel the previous request
- if (s_last_wake_timeout_info != NULL) {
- s_last_wake_timeout_info->userParam = (void *)1;
+ s_last_wake_timeout_info
+ = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
+ &TIMEVAL_WAKE_TIMEOUT);
}
-
- s_last_wake_timeout_info
- = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
- &TIMEVAL_WAKE_TIMEOUT);
}
// Normal exit
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: "E_EMPTY_RECORD";
+ 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 "<unknown error>";
}
}
case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
+ case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
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 "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
+ 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_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY";
+ case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RIL_RESPONSE_ACKNOWLEDGEMENT";
default: return "<unknown request>";
}
}
}
}
+/*
+ * Returns true for a debuggable build.
+ */
+static bool isDebuggable() {
+ char debuggable[PROP_VALUE_MAX];
+ property_get("ro.debuggable", debuggable, "0");
+ if (strcmp(debuggable, "1") == 0) {
+ return true;
+ }
+ return false;
+}
+
} /* namespace android */
void rilEventAddWakeup_helper(struct ril_event *ev) {