/** * RIL_REQUEST_VOICE_REGISTRATION_STATE * * Request current registration state. */ void requestRegistrationState(int request, void *data, size_t datalen, RIL_Token t) { (void) data; (void) datalen, (void)request; int err = 0; const char resp_size = 15; int response[resp_size]; char *responseStr[resp_size]; ATResponse *cgreg_resp = NULL, *e2reg_resp = NULL; char *line; int commas = 0; int skip, cs_status = 0; int i; /* IMPORTANT: Will take screen state lock here. Make sure to always call releaseScreenStateLock BEFORE returning! */ getScreenStateLock(); if (!getScreenState()) { (void)at_send_command("AT+CREG=2"); /* Ignore the response, not VITAL. */ } /* Setting default values in case values are not returned by AT command */ for (i = 0; i < resp_size; i++) responseStr[i] = NULL; memset(response, 0, sizeof(response)); err = at_send_command_singleline("AT+CREG?", "+CREG:", &cgreg_resp); if (err != AT_NOERROR) goto error; line = cgreg_resp->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* * The solicited version of the CREG response is * +CREG: n, stat, [lac, cid] * and the unsolicited version is * +CREG: stat, [lac, cid] * The <n> parameter is basically "is unsolicited creg on?" * which it should always be. * * Now we should normally get the solicited version here, * but the unsolicited version could have snuck in * so we have to handle both. * * Also since the LAC and CID are only reported when registered, * we can have 1, 2, 3, or 4 arguments here. * * finally, a +CGREG: answer may have a fifth value that corresponds * to the network type, as in; * * +CGREG: n, stat [,lac, cid [,networkType]] */ /* Count number of commas */ err = at_tok_charcounter(line, ',', &commas); if (err < 0) goto error; switch (commas) { case 0: /* +CREG: <stat> */ err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; response[1] = -1; response[2] = -1; break; case 1: /* +CREG: <n>, <stat> */ err = at_tok_nextint(&line, &skip); if (err < 0) goto error; err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; response[1] = -1; response[2] = -1; if (err < 0) goto error; break; case 2: /* +CREG: <stat>, <lac>, <cid> */ err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[1]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); if (err < 0) goto error; break; case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */ case 4: /* +CREG: <n>, <stat>, <lac>, <cid>, <?> */ err = at_tok_nextint(&line, &skip); if (err < 0) goto error; err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[1]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); if (err < 0) goto error; break; default: goto error; } s_registrationDeniedReason = DEFAULT_VALUE; if (response[0] == CGREG_STAT_REG_DENIED) { err = at_send_command_singleline("AT*E2REG?", "*E2REG:", &e2reg_resp); if (err != AT_NOERROR) goto error; line = e2reg_resp->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &skip); if (err < 0) goto error; err = at_tok_nextint(&line, &cs_status); if (err < 0) goto error; response[13] = convertRegistrationDeniedReason(cs_status); s_registrationDeniedReason = response[13]; err = asprintf(&responseStr[13], "%08x", response[13]); if (err < 0) goto error; } err = asprintf(&responseStr[0], "%d", response[0]); if (err < 0) goto error; if (response[1] > 0) err = asprintf(&responseStr[1], "%04x", response[1]); if (err < 0) goto error; if (response[2] > 0) err = asprintf(&responseStr[2], "%08x", response[2]); if (err < 0) goto error; if (response[0] == CGREG_STAT_REG_HOME_NET || response[0] == CGREG_STAT_ROAMING) responseStr[3] = getNetworkType(0); RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, resp_size * sizeof(char *)); finally: if (!getScreenState()) (void)at_send_command("AT+CREG=0"); releaseScreenStateLock(); /* Important! */ for (i = 0; i < resp_size; i++) free(responseStr[i]); at_response_free(cgreg_resp); at_response_free(e2reg_resp); return; error: LOGE("%s() Must never return an error when radio is on", __func__); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS * * Scans for available networks. */ void requestQueryAvailableNetworks(void *data, size_t datalen, RIL_Token t) { #define QUERY_NW_NUM_PARAMS 4 /* * AT+COPS=? * +COPS: [list of supported (<stat>,long alphanumeric <oper> * ,short alphanumeric <oper>,numeric <oper>[,<AcT>])s] * [,,(list of supported <mode>s),(list of supported <format>s)] * * <stat> * 0 = unknown * 1 = available * 2 = current * 3 = forbidden */ (void) data; (void) datalen; int err = 0; ATResponse *atresponse = NULL; const char *statusTable[] = { "unknown", "available", "current", "forbidden" }; char **responseArray = NULL; char *p; int n = 0; int i = 0; err = at_send_command_multiline("AT+COPS=?", "+COPS:", &atresponse); if (err != AT_NOERROR) goto error; p = atresponse->p_intermediates->line; /* count number of '('. */ err = at_tok_charcounter(p, '(', &n); if (err < 0) goto error; /* Allocate array of strings, blocks of 4 strings. */ responseArray = alloca(n * QUERY_NW_NUM_PARAMS * sizeof(char *)); /* Loop and collect response information into the response array. */ for (i = 0; i < n; i++) { int status = 0; char *line = NULL; char *s = NULL; char *longAlphaNumeric = NULL; char *shortAlphaNumeric = NULL; char *numeric = NULL; char *remaining = NULL; s = line = getFirstElementValue(p, "(", ")", &remaining); p = remaining; if (line == NULL) { LOGE("%s() Null pointer while parsing COPS response." "This should not happen.", __func__); break; } /* <stat> */ err = at_tok_nextint(&line, &status); if (err < 0) goto error; /* long alphanumeric <oper> */ err = at_tok_nextstr(&line, &longAlphaNumeric); if (err < 0) goto error; /* short alphanumeric <oper> */ err = at_tok_nextstr(&line, &shortAlphaNumeric); if (err < 0) goto error; /* numeric <oper> */ err = at_tok_nextstr(&line, &numeric); if (err < 0) goto error; responseArray[i * QUERY_NW_NUM_PARAMS + 0] = alloca(strlen(longAlphaNumeric) + 1); strcpy(responseArray[i * QUERY_NW_NUM_PARAMS + 0], longAlphaNumeric); responseArray[i * QUERY_NW_NUM_PARAMS + 1] = alloca(strlen(shortAlphaNumeric) + 1); strcpy(responseArray[i * QUERY_NW_NUM_PARAMS + 1], shortAlphaNumeric); responseArray[i * QUERY_NW_NUM_PARAMS + 2] = alloca(strlen(numeric) + 1); strcpy(responseArray[i * QUERY_NW_NUM_PARAMS + 2], numeric); free(s); /* * Check if modem returned an empty string, and fill it with MNC/MMC * if that's the case. */ if (responseArray[i * QUERY_NW_NUM_PARAMS + 0] && strlen(responseArray[i * QUERY_NW_NUM_PARAMS + 0]) == 0) { responseArray[i * QUERY_NW_NUM_PARAMS + 0] = alloca(strlen(responseArray[i * QUERY_NW_NUM_PARAMS + 2]) + 1); strcpy(responseArray[i * QUERY_NW_NUM_PARAMS + 0], responseArray[i * QUERY_NW_NUM_PARAMS + 2]); } if (responseArray[i * QUERY_NW_NUM_PARAMS + 1] && strlen(responseArray[i * QUERY_NW_NUM_PARAMS + 1]) == 0) { responseArray[i * QUERY_NW_NUM_PARAMS + 1] = alloca(strlen(responseArray[i * QUERY_NW_NUM_PARAMS + 2]) + 1); strcpy(responseArray[i * QUERY_NW_NUM_PARAMS + 1], responseArray[i * QUERY_NW_NUM_PARAMS + 2]); } /* Add status */ responseArray[i * QUERY_NW_NUM_PARAMS + 3] = alloca(strlen(statusTable[status]) + 1); sprintf(responseArray[i * QUERY_NW_NUM_PARAMS + 3], "%s", statusTable[status]); } RIL_onRequestComplete(t, RIL_E_SUCCESS, responseArray, i * QUERY_NW_NUM_PARAMS * sizeof(char *)); finally: at_response_free(atresponse); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_REQUEST_DATA_REGISTRATION_STATE * * Request current GPRS registration state. */ void requestGprsRegistrationState(int request, void *data, size_t datalen, RIL_Token t) { (void)request, (void)data, (void)datalen; int err = 0; const char resp_size = 6; int response[resp_size]; char *responseStr[resp_size]; ATResponse *atresponse = NULL; char *line, *p; int commas = 0; int skip, tmp; int count = 3; getScreenStateLock(); if (!getScreenState()) (void)at_send_command("AT+CGREG=2"); /* Response not vital */ memset(responseStr, 0, sizeof(responseStr)); memset(response, 0, sizeof(response)); response[1] = -1; response[2] = -1; err = at_send_command_singleline("AT+CGREG?", "+CGREG: ", &atresponse); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* * The solicited version of the +CGREG response is * +CGREG: n, stat, [lac, cid [,<AcT>]] * and the unsolicited version is * +CGREG: stat, [lac, cid [,<AcT>]] * The <n> parameter is basically "is unsolicited creg on?" * which it should always be. * * Now we should normally get the solicited version here, * but the unsolicited version could have snuck in * so we have to handle both. * * Also since the LAC, CID and AcT are only reported when registered, * we can have 1, 2, 3, 4 or 5 arguments here. */ /* Count number of commas */ p = line; err = at_tok_charcounter(line, ',', &commas); if (err < 0) { LOGE("%s() at_tok_charcounter failed", __func__); goto error; } switch (commas) { case 0: /* +CGREG: <stat> */ err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; break; case 1: /* +CGREG: <n>, <stat> */ err = at_tok_nextint(&line, &skip); if (err < 0) goto error; err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; break; case 2: /* +CGREG: <stat>, <lac>, <cid> */ err = at_tok_nextint(&line, &response[0]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[1]); if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); if (err < 0) goto error; break; case 3: /* +CGREG: <n>, <stat>, <lac>, <cid> */ /* +CGREG: <stat>, <lac>, <cid>, <AcT> */ err = at_tok_nextint(&line, &tmp); if (err < 0) goto error; /* We need to check if the second parameter is <lac> */ if (*(line) == '"') { response[0] = tmp; /* <stat> */ err = at_tok_nexthexint(&line, &response[1]); /* <lac> */ if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); /* <cid> */ if (err < 0) goto error; err = at_tok_nextint(&line, &response[3]); /* <AcT> */ if (err < 0) goto error; count = 4; } else { err = at_tok_nextint(&line, &response[0]); /* <stat> */ if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[1]); /* <lac> */ if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); /* <cid> */ if (err < 0) goto error; } break; case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <AcT> */ err = at_tok_nextint(&line, &skip); /* <n> */ if (err < 0) goto error; err = at_tok_nextint(&line, &response[0]); /* <stat> */ if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[1]); /* <lac> */ if (err < 0) goto error; err = at_tok_nexthexint(&line, &response[2]); /* <cid> */ if (err < 0) goto error; err = at_tok_nextint(&line, &response[3]); /* <AcT> */ if (err < 0) goto error; count = 4; break; default: LOGE("%s() Invalid input", __func__); goto error; } if (response[0] == CGREG_STAT_REG_HOME_NET || response[0] == CGREG_STAT_ROAMING) responseStr[3] = getNetworkType(response[3]); /* Converting to stringlist for Android */ asprintf(&responseStr[0], "%d", response[0]); /* state */ if (response[1] >= 0) asprintf(&responseStr[1], "%04x", response[1]); /* LAC */ else responseStr[1] = NULL; if (response[2] >= 0) asprintf(&responseStr[2], "%08x", response[2]); /* CID */ else responseStr[2] = NULL; responseStr[5] = "1"; RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, resp_size * sizeof(char *)); finally: if (!getScreenState()) (void)at_send_command("AT+CGREG=0"); releaseScreenStateLock(); /* Important! */ if (responseStr[0]) free(responseStr[0]); if (responseStr[1]) free(responseStr[1]); if (responseStr[2]) free(responseStr[2]); if (responseStr[3]) free(responseStr[3]); at_response_free(atresponse); return; error: LOGE("%s Must never return an error when radio is on", __func__); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_UNSOL_SIM_REFRESH * * Indicate when SIM issue a REFRESH proactive command to applications. */ void onStkSimRefresh(const char *s) { int commas = 0; char *line = NULL; char *tok = NULL; int i, skip; int err = -1; int response[2]; /* *ESIMRF: <cmdnumber>,<type>[[,< fileid>,<pathid>][…]] */ tok = line = strdup(s); err = at_tok_charcounter(tok, ',', &commas); if (err < 0) commas = 0; else commas -= 1; err = at_tok_start(&tok); if (err < 0) goto error; err = at_tok_nextint(&tok, &(s_refeshStatus.cmdNumber)); if (err < 0) goto error; err = at_tok_nextint(&tok, &(s_refeshStatus.cmdQualifier)); if (err < 0) goto error; switch(s_refeshStatus.cmdQualifier) { case SAT_SIM_INITIALIZATION_AND_FULL_FILE_CHANGE_NOTIFICATION: case SAT_SIM_INITIALIZATION_AND_FILE_CHANGE_NOTIFICATION: case SAT_SIM_INITIALIZATION: case SAT_NAA_APPLICATION_RESET: /* SIM initialized. All files should be re-read. */ response[0] = SIM_INIT; s_refeshStatus.Result = 3; /* success, EFs read */ break; case SAT_FILE_CHANGE_NOTIFICATION: /* one or more files on SIM has been updated */ response[0] = SIM_FILE_UPDATE; s_refeshStatus.Result = 3; /* success, EFs read */ break; case SAT_SIM_RESET: /* SIM reset. All files should be re-read. */ response[0] = SIM_RESET; break; case SAT_NAA_SESSION_RESET: /* one or more files on SIM has been updated */ response[0] = SIM_FILE_UPDATE; s_refeshStatus.Result = 3; /* success, EFs read */ break; case SAT_STEERING_OF_ROAMING: /* not set in Terminal Profile for Android, should never happen */ default: goto error; break; } if (response[0] != SIM_FILE_UPDATE) { response[1] = 0; RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_REFRESH, response, sizeof(response)); goto finally; } for (i = 0; i < commas; i += 2) { err = at_tok_nextint(&tok, &(response[1])); if (err < 0) { /* check if response is already sent to Android */ if (i > 0) goto finally; else goto error; } /* <pathid> is not used by Android */ err = at_tok_nextint(&tok, &skip); if (err < 0) { /* check if response is already sent to Android */ if (i > 0) goto finally; else goto error; } RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_REFRESH, response, sizeof(response)); } finally: #ifndef USE_U8500_RIL if (response[0] != SIM_RESET) { // AT commands cannot be sent from the at reader thread enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, sendRefreshTerminalResponse, NULL, NULL); } #endif free(line); return; error: ALOGE("%s: failed to parse %s, default to SIM_INITIALIZATION", __func__, s); if (s_refeshStatus.cmdNumber < 0) s_refeshStatus.cmdNumber = 1; if (s_refeshStatus.cmdQualifier < 0) s_refeshStatus.cmdQualifier = SAT_SIM_INITIALIZATION; if (s_refeshStatus.Result < 0) s_refeshStatus.Result = 2; /* command performed with missing information */ response[0] = SIM_INIT; response[1] = 0; RIL_onUnsolicitedResponse(RIL_UNSOL_SIM_REFRESH, response, sizeof(response)); goto finally; }
void onConnectionStateChanged(const char *s) { int m_state = -1, m_cause = -1, err; int commas; err = at_tok_start((char **) &s); if (err < 0) return; /* Count number of commas */ err = at_tok_charcounter((char *) s, ',', &commas); if (err < 0) return; err = at_tok_nextint((char **) &s, &m_state); if (err < 0 || m_state < E2NAP_ST_DISCONNECTED || m_state > E2NAP_ST_CONNECTED) { m_state = -1; return; } err = at_tok_nextint((char **) &s, &m_cause); /* The <cause> will only be indicated/considered when <state> * is disconnected */ if (err < 0 || m_cause < E2NAP_C_SUCCESS || m_cause > E2NAP_C_MAXIMUM || m_state != E2NAP_ST_DISCONNECTED) m_cause = -1; if (commas == 3) { int m_state2 = -1, m_cause2 = -1; err = at_tok_nextint((char **) &s, &m_state2); if (err < 0 || m_state2 < E2NAP_ST_DISCONNECTED || m_state2 > E2NAP_ST_CONNECTED) { m_state = -1; return; } if (m_state2 == E2NAP_ST_DISCONNECTED) { err = at_tok_nextint((char **) &s, &m_cause2); if (err < 0 || m_cause2 < E2NAP_C_SUCCESS || m_cause2 > E2NAP_C_MAXIMUM) { m_cause2 = -1; } } if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) LOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); if (m_state == E2NAP_ST_CONNECTING || m_state2 == E2NAP_ST_CONNECTING) { s_e2napState = E2NAP_ST_CONNECTING; } else if (m_state == E2NAP_ST_CONNECTED) { s_e2napCause = m_cause2; s_e2napState = E2NAP_ST_CONNECTED; } else if (m_state2 == E2NAP_ST_CONNECTED) { s_e2napCause = m_cause; s_e2napState = E2NAP_ST_CONNECTED; } else { s_e2napCause = m_cause; s_e2napState = E2NAP_ST_DISCONNECTED; } if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) LOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } else { if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) LOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); s_e2napState = m_state; s_e2napCause = m_cause; if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) LOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } LOGD("%s() %s", e2napStateToString(m_state), __func__); if (m_state != E2NAP_ST_CONNECTING) enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, onPDPContextListChanged, NULL, NULL); /* Make system request network information. This will allow RIL to report any new * technology made available from connection. */ if (E2NAP_ST_CONNECTED == m_state) RIL_onUnsolicitedResponse( RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0); mbm_check_error_cause(); }
static int parse_ip_information(char** addresses, char** gateways, char** dnses, in_addr_t* addr, in_addr_t* gateway) { ATResponse* p_response = NULL; int err = -1; int number_of_entries = 0; int iterator = 0; int dnscnt = 0; char *intermediate_line = NULL; char *line_origin = NULL; *addresses = NULL; *gateways = NULL; *dnses = NULL; enum { IP = 1, GATEWAY, DNS }; /* *E2IPCFG: * (1,"10.155.68.129")(2,"10.155.68.131")(3,"80.251.192.244")(3,"80.251.192.245") */ err = at_send_command_singleline("AT*E2IPCFG?", "*E2IPCFG:", &p_response); if (err != AT_NOERROR) return -1; err = at_tok_charcounter(p_response->p_intermediates->line, '(', &number_of_entries); if (err < 0 || number_of_entries == 0) { LOGE("%s() Syntax error. Could not parse output", __func__); goto error; } intermediate_line = p_response->p_intermediates->line; /* Loop and collect information */ for (iterator = 0; iterator < number_of_entries; iterator++) { int stat = 0; char *line_tok = NULL; char *address = NULL; char *remaining_intermediate_line = NULL; char* tmp_pointer = NULL; line_origin = line_tok = getFirstElementValue(intermediate_line, "(", ")", &remaining_intermediate_line); intermediate_line = remaining_intermediate_line; if (line_tok == NULL) { LOGD("%s: No more connection info", __func__); break; } /* <stat> */ err = at_tok_nextint(&line_tok, &stat); if (err < 0) { goto error; } /* <address> */ err = at_tok_nextstr(&line_tok, &address); if (err < 0) { goto error; } switch (stat % 10) { case IP: if (!*addresses) *addresses = strdup(address); else { tmp_pointer = realloc(*addresses, strlen(address) + strlen(*addresses) + 1); if (NULL == tmp_pointer) { LOGE("%s() Failed to allocate memory for addresses", __func__); goto error; } *addresses = tmp_pointer; sprintf(*addresses, "%s %s", *addresses, address); } LOGD("%s() IP Address: %s", __func__, address); if (inet_pton(AF_INET, address, addr) <= 0) { LOGE("%s() inet_pton() failed for %s!", __func__, address); goto error; } break; case GATEWAY: if (!*gateways) *gateways = strdup(address); else { tmp_pointer = realloc(*gateways, strlen(address) + strlen(*gateways) + 1); if (NULL == tmp_pointer) { LOGE("%s() Failed to allocate memory for gateways", __func__); goto error; } *gateways = tmp_pointer; sprintf(*gateways, "%s %s", *gateways, address); } LOGD("%s() GW: %s", __func__, address); if (inet_pton(AF_INET, address, gateway) <= 0) { LOGE("%s() Failed inet_pton for gw %s!", __func__, address); goto error; } break; case DNS: dnscnt++; LOGD("%s() DNS%d: %s", __func__, dnscnt, address); if (dnscnt == 1) *dnses = strdup(address); else if (dnscnt == 2) { tmp_pointer = realloc(*dnses, strlen(address) + strlen(*dnses) + 1); if (NULL == tmp_pointer) { LOGE("%s() Failed to allocate memory for dnses", __func__); goto error; } *dnses = tmp_pointer; sprintf(*dnses, "%s %s", *dnses, address); } break; } free(line_origin); line_origin = NULL; } at_response_free(p_response); return 0; error: free(line_origin); free(*addresses); free(*gateways); free(*dnses); at_response_free(p_response); *gateways = NULL; *addresses = NULL; *dnses = NULL; return -1; }
void onConnectionStateChanged(const char *s) { int m_state = -1, m_cause = -1, err; int commas; err = at_tok_start((char **) &s); if (err < 0) return; /* Count number of commas */ err = at_tok_charcounter((char *) s, ',', &commas); if (err < 0) return; err = at_tok_nextint((char **) &s, &m_state); if (err < 0 || m_state < E2NAP_STATE_DISCONNECTED || m_state > E2NAP_STATE_CONNECTING) { m_state = -1; return; } err = at_tok_nextint((char **) &s, &m_cause); /* The <cause> will only be indicated/considered when <state> * is disconnected */ if (err < 0 || m_cause < E2NAP_CAUSE_SUCCESS || m_cause > E2NAP_CAUSE_MAXIMUM || m_state != E2NAP_STATE_DISCONNECTED) m_cause = -1; if (commas == 3) { int m_state2 = -1, m_cause2 = -1; err = at_tok_nextint((char **) &s, &m_state2); if (err < 0 || m_state2 < E2NAP_STATE_DISCONNECTED || m_state2 > E2NAP_STATE_CONNECTED) { m_state = -1; return; } if (m_state2 == E2NAP_STATE_DISCONNECTED) { err = at_tok_nextint((char **) &s, &m_cause2); if (err < 0 || m_cause2 < E2NAP_CAUSE_SUCCESS || m_cause2 > E2NAP_CAUSE_MAXIMUM) { m_cause2 = -1; } } if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); if (m_state == E2NAP_STATE_CONNECTING || m_state2 == E2NAP_STATE_CONNECTING) { s_e2napState = E2NAP_STATE_CONNECTING; } else if (m_state == E2NAP_STATE_CONNECTED) { s_e2napCause = m_cause2; s_e2napState = E2NAP_STATE_CONNECTED; } else if (m_state2 == E2NAP_STATE_CONNECTED) { s_e2napCause = m_cause; s_e2napState = E2NAP_STATE_CONNECTED; } else { s_e2napCause = m_cause; s_e2napState = E2NAP_STATE_DISCONNECTED; } if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } else { if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); s_e2napState = m_state; s_e2napCause = m_cause; if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } mbm_check_error_cause(); if (m_state == E2NAP_STATE_DISCONNECTED) { /* Bring down the interface as well. */ if (!(ifc_init())) { ifc_down(ril_iface); ifc_close(); } else ALOGE("%s() Failed to set up ifc!", __func__); } if ((m_state == E2NAP_STATE_DISCONNECTED) && (s_DeactCalled == 0)) { enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, onPDPContextListChanged, NULL, NULL); } s_DeactCalled = 0; }