/** * RIL_REQUEST_QUERY_FACILITY_LOCK * * Query the status of a facility lock state. */ void requestQueryFacilityLock(void *data, size_t datalen, RIL_Token t) { int err, response; ATResponse *atresponse = NULL; char *line = NULL; char *facility_string = NULL; char *facility_password = NULL; char *facility_class = NULL; (void) datalen; if (datalen < 3 * sizeof(char **)) { ALOGE("%s() bad data length!", __func__); goto error; } facility_string = ((char **) data)[0]; facility_password = ((char **) data)[1]; facility_class = ((char **) data)[2]; err = at_send_command_singleline("AT+CLCK=\"%s\",2,\"%s\",%s", "+CLCK:", &atresponse, facility_string, facility_password, facility_class); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &response); if (err < 0) goto error; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int)); at_response_free(atresponse); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); at_response_free(atresponse); }
void* onPgpsUrlReceived(void *data) { GpsCtrlContext *context = get_gpsctrl_context(); int err; int ignore; int id; char *url; char *cmd; char *line = (char *) data; err = at_tok_start(&line); if (err < 0) { MBMLOGE("%s error parsing data", __FUNCTION__); return NULL; } /* Ignore 1 integer from line */ err = at_tok_nextint(&line, &ignore); if (err < 0) { MBMLOGE("%s error parsing data", __FUNCTION__); return NULL; } err = at_tok_nextint(&line, &id); if (err < 0) { MBMLOGE("%s error parsing data", __FUNCTION__); return NULL; } err = at_tok_nextstr(&line, &url); if (err < 0) { MBMLOGW("%s error parsing pgps url", __FUNCTION__); return NULL; } err = asprintf(&cmd, "%d\n%s", id, url); if (err < 0) { MBMLOGE("%s error allocating cmd string", __FUNCTION__); return NULL; } service_handler_send_message(CMD_DOWNLOAD_PGPS_DATA, cmd); return NULL; }
/** * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE * * Query current network selectin mode. */ void requestQueryNetworkSelectionMode(void *data, size_t datalen, RIL_Token t) { (void) data; (void) datalen; int err; ATResponse *atresponse = NULL; int response = 0; char *line; err = at_send_command_singleline("AT+COPS?", "+COPS:", &atresponse); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &response); if (err < 0) goto error; /* * Android accepts 0(automatic) and 1(manual). * Modem may return mode 4(Manual/automatic). * Convert it to 1(Manual) as android expects. */ if (response == 4) response = 1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int)); finally: at_response_free(atresponse); return; error: LOGE("%s() Must never return error when radio is on", __func__); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
void onNetworkStatusChanged(const char *s) { int err; int skip; int cs_status, ps_status; int resp; char *line = NULL, *tok = NULL; cs_status = ps_status = 0; tok = line = strdup(s); if (tok == NULL) goto error; at_tok_start(&tok); err = at_tok_nextint(&tok, &skip); if (err < 0) goto error; err = at_tok_nextint(&tok, &cs_status); if (err < 0) goto error; err = at_tok_nextint(&tok, &ps_status); if (err < 0) goto error; resp = RIL_RESTRICTED_STATE_NONE; if (cs_status == E2REG_ACCESS_CLASS_BARRED) resp |= RIL_RESTRICTED_STATE_CS_ALL; if (ps_status == E2REG_ACCESS_CLASS_BARRED) resp |= RIL_RESTRICTED_STATE_PS_ALL; RIL_onUnsolicitedResponse(RIL_UNSOL_RESTRICTED_STATE_CHANGED, &resp, sizeof(int *)); /* If registered, poll signal strength for faster update of signal bar */ if ((cs_status == E2REG_REGISTERED) || (ps_status == E2REG_REGISTERED)) enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, pollSignalStrength, (void *)-1, NULL); error: free(line); }
static AT_Error at_get_error(const ATResponse *p_response) { int ret; int err; char *p_cur; if (p_response == NULL) return merror(GENERIC_ERROR, GENERIC_ERROR_UNSPECIFIED); if (p_response->success > 0) { return AT_NOERROR; } if (p_response->finalResponse == NULL) return AT_ERROR_INVALID_RESPONSE; if (isFinalResponseSuccess(p_response->finalResponse)) return AT_NOERROR; p_cur = p_response->finalResponse; err = at_tok_start(&p_cur); if (err < 0) return merror(GENERIC_ERROR, GENERIC_ERROR_UNSPECIFIED); err = at_tok_nextint(&p_cur, &ret); if (err < 0) return merror(GENERIC_ERROR, GENERIC_ERROR_UNSPECIFIED); if(strStartsWith(p_response->finalResponse, "+CME ERROR:")) return merror(CME_ERROR, ret); else if (strStartsWith(p_response->finalResponse, "+CMS ERROR:")) return merror(CMS_ERROR, ret); else if (strStartsWith(p_response->finalResponse, "ERROR:")) return merror(GENERIC_ERROR, GENERIC_ERROR_RESPONSE); else if (strStartsWith(p_response->finalResponse, "+NO CARRIER:")) return merror(GENERIC_ERROR, GENERIC_NO_CARRIER_RESPONSE); else if (strStartsWith(p_response->finalResponse, "+NO ANSWER:")) return merror(GENERIC_ERROR, GENERIC_NO_ANSWER_RESPONSE); else if (strStartsWith(p_response->finalResponse, "+NO DIALTONE:")) return merror(GENERIC_ERROR, GENERIC_NO_DIALTONE_RESPONSE); else return merror(GENERIC_ERROR, GENERIC_ERROR_UNSPECIFIED); }
static int onMessageListing(char* s, char* sms_pdu) { int* index = malloc(sizeof(int)); int stat = -1; char* line = NULL; line = strdup(s); at_tok_start(&line); at_tok_nextint(&line, index); at_tok_nextint(&line, &stat); RIL_requestTimedCallback (deleteMessageByIndex, index, NULL); if(stat == 0){ RIL_onUnsolicitedResponse ( RIL_UNSOL_RESPONSE_NEW_SMS, sms_pdu, strlen(sms_pdu)); } free(line); return UNSOLICITED_SUCCESSED; }
void _requestSignalStrengthWCDMA(void *data, size_t datalen, RIL_Token t) { ATResponse *p_response = NULL; int err; RIL_SignalStrength_v6 resp; char *line; memset(&resp,0,sizeof(resp)); err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response); if (err < 0 || p_response->success == 0) { RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto error; } line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &(resp.GW_SignalStrength.signalStrength)); if (err < 0) goto error; err = at_tok_nextint(&line, &(resp.GW_SignalStrength.bitErrorRate)); if (err < 0) goto error; resp.LTE_SignalStrength.signalStrength = -1; resp.LTE_SignalStrength.rsrp = -1; resp.LTE_SignalStrength.rsrq = -1; resp.LTE_SignalStrength.rssnr = -1; resp.LTE_SignalStrength.cqi = -1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &resp, sizeof(resp)); at_response_free(p_response); return; error: LOGE("requestSignalStrength must never return an error when radio is on"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); at_response_free(p_response); }
static int getNetworkType() { int err; ATResponse *p_response = NULL; int type = 0; char *line; err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response); if (err < 0 || p_response->success == 0) { return type; } line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) { goto out; } err = at_tok_nextint(&line, &type); err = at_tok_nextint(&line, &type); err = at_tok_nextint(&line, &type); err = at_tok_nextint(&line, &type); switch(type){ case 0: case 1: type = 2; break; case 2: type = 3; break; default: type = 3; break; } out: at_response_free(p_response); return type; }
/** * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND * * Requests to send a SAT/USAT envelope command to SIM. * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111. */ void requestStkSendEnvelopeCommand(void *data, size_t datalen, RIL_Token t) { char *cmd; char *line; char *stkResponse; int err; ATResponse *atresponse = NULL; const char *ec = (const char *) data; asprintf(&cmd, "AT*STKE=\"%s\"", ec); err = at_send_command_singleline(cmd, "*STKE:", &atresponse); free(cmd); if (err < 0 || atresponse->success == 0) goto error; if (atresponse->p_intermediates) { line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextstr(&line, &stkResponse); if (err < 0) goto error; RIL_onRequestComplete(t, RIL_E_SUCCESS, stkResponse, sizeof(char *)); } else RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); finally: at_response_free(atresponse); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
static int simIOSelectFile(unsigned short fileid) { int err = 0; unsigned short lc = simIOGetLogicalChannel(); ATResponse *atresponse = NULL; char *line; char *resp; int resplen; if (lc == 0) return -EIO; err = at_send_command_singleline("AT+CGLA=%d,14,\"00A4000C02%.4X\"", "+CGLA:", &atresponse, lc, fileid); if (at_get_error_type(err) == AT_ERROR) return err; if (err != AT_NOERROR) return -EINVAL; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &resplen); if (err < 0) goto finally; err = at_tok_nextstr(&line, &resp); if (err < 0) goto finally; /* Std resp code: "9000" */ if (resplen != 4 || strcmp(resp, "9000") != 0) { err = -EIO; goto finally; } finally: at_response_free(atresponse); return err; }
int eng_linuxcmd_atdiag(char *req, char *rsp) { int len, ret; char tmp[3]; char *data = req; char *ptr = NULL; ENG_LOG("Call %s", __FUNCTION__); if (strstr(req, "DEVT")) ret = test_dev(req, rsp); else { memset(g_buffer, 0, sizeof(g_buffer)); at_tok_start(&data); at_tok_nextstr(&data, &ptr); len = eng_ascii2hex(ptr, g_buffer, strlen(ptr)); ret = eng_atdiag_hdlr(g_buffer, len, rsp); } return ret; }
void onStkEventNotify(const char *s) { char *str; char *line; char *tok; int err; tok = line = strdup(s); err = at_tok_start(&tok); if (err < 0) goto error; err = at_tok_nextstr(&tok, &str); if (err < 0) goto error; RIL_onUnsolicitedResponse(RIL_UNSOL_STK_EVENT_NOTIFY, str, sizeof(char *)); error: free(line); }
/** * RIL_UNSOL_STK_PROACTIVE_COMMAND * * Indicate when SIM issue a STK proactive command to applications. * */ void onStkProactiveCommand(const char *s) { char *str; char *line; char *tok; int err; tok = line = strdup(s); err = at_tok_start(&tok); if (err < 0) goto error; err = at_tok_nextstr(&tok, &str); if (err < 0) goto error; RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND, str, sizeof(char *)); error: free(line); }
/** * RIL_REQUEST_STK_GET_PROFILE * * Requests the profile of SIM tool kit. * The profile indicates the SAT/USAT features supported by ME. * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111. */ void requestStkGetProfile(void *data, size_t datalen, RIL_Token t) { ATResponse *atresponse = NULL; char *line; char *response; int err = 0; int activated = 0; err = at_send_command_singleline("AT*STKC?", "*STKC:", &atresponse); if (err < 0 || atresponse->success == 0) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &activated); if (err < 0) goto error; err = at_tok_nextstr(&line, &response); if (err < 0) goto error; RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(char *)); finally: at_response_free(atresponse); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE * * Query current network selectin mode. ok */ void requestQueryNetworkSelectionMode( void *data, size_t datalen, RIL_Token t) { int err; ATResponse *p_response = NULL; int response = 0; char *line; err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response); if (err < 0 || p_response->success == 0) { goto error; } line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) { goto error; } err = at_tok_nextint(&line, &response); if (err < 0) { goto error; } RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int)); at_response_free(p_response); return; error: at_response_free(p_response); LOGE("requestQueryNetworkSelectionMode must never return error when radio is on"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); }
static int forwardFromCCFCLine(char *line, RIL_CallForwardInfo *p_forward) { int err; int state; int mode; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &(p_forward->status)); if (err < 0) goto error; err = at_tok_nextint(&line, &(p_forward->serviceClass)); if (err < 0) goto error; if (at_tok_hasmore(&line)) { err = at_tok_nextstr(&line, &(p_forward->number)); /* tolerate null here */ if (err < 0) return 0; if (p_forward->number != NULL && 0 == strspn(p_forward->number, "+0123456789") ) { p_forward->number = NULL; } err = at_tok_nextint(&line, &p_forward->toa); if (err < 0) goto error; } return 0; error: LOGE("invalid CCFC line\n"); return -1; }
void onSuppServiceNotification(const char *s, int type) { RIL_SuppSvcNotification ssnResponse; char *line; char *tok; int err; line = tok = strdup(s); memset(&ssnResponse, 0, sizeof(ssnResponse)); ssnResponse.notificationType = type; err = at_tok_start(&tok); if (err < 0) goto error; err = at_tok_nextint(&tok, &ssnResponse.code); if (err < 0) goto error; if (ssnResponse.code == 16 || (type == 0 && ssnResponse.code == 4) || (type == 1 && ssnResponse.code == 1)) { err = at_tok_nextint(&tok, &ssnResponse.index); if (err < 0) goto error; } /* RIL_SuppSvcNotification has two more members that we won't get from the +CSSI/+CSSU. Where do we get them, if we ever do? */ RIL_onUnsolicitedResponse(RIL_UNSOL_SUPP_SVC_NOTIFICATION, &ssnResponse, sizeof(ssnResponse)); error: free(line); }
void onNewSmsOnSIM(const char *s) { char *line; char *mem; char *tok; int err = 0; int index = -1; tok = line = strdup(s); err = at_tok_start(&tok); if (err < 0) goto error; err = at_tok_nextstr(&tok, &mem); if (err < 0) goto error; if (strncmp(mem, "SM", 2) != 0) goto error; err = at_tok_nextint(&tok, &index); if (err < 0) goto error; RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, &index, sizeof(int *)); finally: free(line); return; error: LOGE("Failed to parse +CMTI."); goto finally; }
static char *getCharEncoding(void) { int err; char *line, *chSet; char *result = NULL; ATResponse *p_response = NULL; err = at_send_command_singleline("AT+CSCS?", "+CSCS:", &p_response); if (err != AT_NOERROR) { LOGE("%s() Failed to read AT+CSCS?", __func__); return NULL; } line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) { at_response_free(p_response); return NULL; } err = at_tok_nextstr(&line, &chSet); if (err < 0) { at_response_free(p_response); return NULL; } /* If not any of the listed below, assume UCS-2 */ if (!strcmp(chSet, "GSM") || !strcmp(chSet, "IRA") || !strncmp(chSet, "8859", 4) || !strcmp(chSet, "UTF-8")) { result = strdup(chSet); } else result = strdup("UCS-2"); at_response_free(p_response); return result; }
/** * RIL_REQUEST_GET_CLIR * * Gets current CLIR status. ok */ void requestGetCLIR(void *data, size_t datalen, RIL_Token t) { ATResponse *p_response; p_response = NULL; int response[2] = {1, 1}; int err = at_send_command_singleline("AT+CLIR?", "+CLIR: ", &p_response); if (err >= 0 && p_response->success) { char *line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err >= 0) { err = at_tok_nextint(&line, &response[0]); if (err >= 0) err = at_tok_nextint(&line, &response[1]); } } RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); at_response_free(p_response); }
void onStkEventDownloadCall(char* urc, RILChannelCtx* p_channel) { RIL_SOCKET_ID rid = getRILIdByChannelCtx(p_channel); int err, i = 0; char *p_cur = (char *)urc; int response[NUM_EVDL_CALL]={0}; //RIL_EVDLCall response = NULL; /* * +EVDLCALL: <status>,<ti>,<is_mt_call>,<is_far_end>,<cause_len>,<cause> */ for(i = 0; i < NUM_EVDL_CALL-1; i++) { response[i] = 0xff; } err = at_tok_start(&p_cur); if (err < 0) goto error; for(i = 0; i < NUM_EVDL_CALL-1; i++) { err = at_tok_nextint(&p_cur, &(response[i])); if(err < 0) { response[i] = 0xFF; LOGE("There is something wrong with item [%d]",i);}//goto error; } err = at_tok_nexthexint(&p_cur, &(response[i])); if(err < 0) { LOGE("There is something wrong with item [%d]",i);//goto error; } RIL_onUnsolicitedResponse( RIL_UNSOL_STK_EVDL_CALL, response, NUM_EVDL_CALL * sizeof(int), rid); return; error: LOGE("There is something wrong with the +EVDLCALL"); }
char *getNetworkType(int def){ int network = def; int err; int gsm_rinfo, umts_rinfo, skip; int ul, dl; int networkType; char *line; ATResponse *p_response; err = at_send_command_singleline("AT*ERINFO?", "*ERINFO:", &p_response); if (err != AT_NOERROR) return NULL; line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &skip); if (err < 0) goto finally; err = at_tok_nextint(&line, &gsm_rinfo); if (err < 0) goto finally; err = at_tok_nextint(&line, &umts_rinfo); if (err < 0) goto finally; at_response_free(p_response); if (umts_rinfo > ERINFO_UMTS_NO_UMTS_HSDPA && getE2napState() == E2NAP_ST_CONNECTED) { err = at_send_command_singleline("AT+CGEQNEG=%d", "+CGEQNEG:", &p_response, RIL_CID_IP); if (err != AT_NOERROR) LOGE("%s() Allocation for, or sending, CGEQNEG failed." "Using default value specified by calling function", __func__); else { line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &skip); if (err < 0) goto finally; err = at_tok_nextint(&line, &skip); if (err < 0) goto finally; err = at_tok_nextint(&line, &ul); if (err < 0) goto finally; err = at_tok_nextint(&line, &dl); if (err < 0) goto finally; at_response_free(p_response); LOGI("Max speed %i/%i, UL/DL", ul, dl); network = CGREG_ACT_UTRAN; if (dl > 384) network = CGREG_ACT_UTRAN_HSDPA; if (ul > 384) network = CGREG_ACT_UTRAN_HSUPA_HSDPA; if (dl > 14400) network = CGREG_ACT_UTRAN_HSPAP; } } else if (gsm_rinfo) { LOGD("%s() Using 2G info: %d", __func__, gsm_rinfo); if (gsm_rinfo == 1) network = CGREG_ACT_GSM; else network = CGREG_ACT_GSM_EGPRS; } switch (network) { case CGREG_ACT_GSM: networkType = RADIO_TECH_GPRS; break; case CGREG_ACT_UTRAN: networkType = RADIO_TECH_UMTS; break; case CGREG_ACT_GSM_EGPRS: networkType = RADIO_TECH_EDGE; break; case CGREG_ACT_UTRAN_HSDPA: networkType = RADIO_TECH_HSDPA; break; case CGREG_ACT_UTRAN_HSUPA: networkType = RADIO_TECH_HSUPA; /* Note: Not used */ break; case CGREG_ACT_UTRAN_HSUPA_HSDPA: networkType = RADIO_TECH_HSPA; break; case CGREG_ACT_UTRAN_HSPAP: networkType = RADIO_TECH_HSPAP; break; default: networkType = RADIO_TECH_UNKNOWN; break; } char *resp; asprintf(&resp, "%d", networkType); return resp; finally: at_response_free(p_response); return NULL; }
void requestLastCallFailCause(void *data, size_t datalen, RIL_Token t) { /* MTK proprietary start */ int callFailCause; char *line; int ret; ATResponse *p_response = NULL; //Solve [ALPS00242104]Invalid number show but cannot call drop when dial VT call in 2G network //mtk04070, 2012.02.24 if (bUseLocalCallFailCause == 1) { callFailCause = dialLastError; LOGD("Use local call fail cause = %d", callFailCause); } else { ret = at_send_command_singleline("AT+CEER", "+CEER:", &p_response, CC_CHANNEL_CTX); if (ret < 0 || p_response->success == 0) goto error; line = p_response->p_intermediates->line; ret = at_tok_start(&line); if (ret < 0) goto error; ret = at_tok_nextint(&line, &callFailCause); if (ret < 0) goto error; LOGD("MD fail cause = %d", callFailCause); } /*if there are more causes need to be translated in the future, * discussing with APP owner to implement this in upper layer. * For the hard coded value, please refer to modem code.*/ if (callFailCause == 10 || callFailCause == 8) callFailCause = CALL_FAIL_CALL_BARRED; else if (callFailCause == 2600) callFailCause = CALL_FAIL_FDN_BLOCKED; else if (callFailCause == 2052) callFailCause = CALL_FAIL_IMSI_UNKNOWN_IN_VLR; else if (callFailCause == 2053) callFailCause = CALL_FAIL_IMEI_NOT_ACCEPTED; else if ((callFailCause > 127 && callFailCause != 2165) || callFailCause <= 0) callFailCause = CALL_FAIL_ERROR_UNSPECIFIED; LOGD("RIL fail cause = %d", callFailCause); RIL_onRequestComplete(t, RIL_E_SUCCESS, &callFailCause, sizeof(int)); if (NULL != p_response) { at_response_free(p_response); } return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); if (NULL != p_response) { at_response_free(p_response); } /* MTK proprietary end */ }
/** * 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_SET_NETWORK_SELECTION_AUTOMATIC * * Specify that the network should be selected automatically. */ void requestSetNetworkSelectionAutomatic(void *data, size_t datalen, RIL_Token t) { (void) data; (void) datalen; int err = 0; ATResponse *atresponse = NULL; int mode = 0; int skip; char *line; char *operator = NULL; struct operatorPollParams *poll_params = NULL; poll_params = malloc(sizeof(struct operatorPollParams)); if (NULL == poll_params) goto error; /* First check if we are already scanning or in manual mode */ err = at_send_command_singleline("AT+COPS=3,2;+COPS?", "+COPS:", &atresponse); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* Read network selection mode */ err = at_tok_nextint(&line, &mode); if (err < 0) goto error; /* If we're unregistered, we may just get a "+COPS: 0" response. */ if (!at_tok_hasmore(&line)) { if (mode == 1) { LOGD("%s() Changing manual to automatic network mode", __func__); goto do_auto; } else goto check_reg; } err = at_tok_nextint(&line, &skip); if (err < 0) goto error; /* A "+COPS: 0, n" response is also possible. */ if (!at_tok_hasmore(&line)) { if (mode == 1) { LOGD("%s() Changing manual to automatic network mode", __func__); goto do_auto; } else goto check_reg; } /* Read numeric operator */ err = at_tok_nextstr(&line, &operator); if (err < 0) goto error; /* If operator is found then do a new scan, else let it continue the already pending scan */ if (operator && strlen(operator) == 0) { if (mode == 1) { LOGD("%s() Changing manual to automatic network mode", __func__); goto do_auto; } else goto check_reg; } /* Operator found */ if (mode == 1) { LOGD("%s() Changing manual to automatic network mode", __func__); goto do_auto; } else { LOGD("%s() Already in automatic mode with known operator, trigger a new network scan", __func__); goto do_auto; } /* Check if module is scanning, if not then trigger a rescan */ check_reg: at_response_free(atresponse); atresponse = NULL; /* Check CS domain first */ err = at_send_command_singleline("AT+CREG?", "+CREG:", &atresponse); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* Read registration unsolicited mode */ err = at_tok_nextint(&line, &mode); if (err < 0) goto error; /* Read registration status */ err = at_tok_nextint(&line, &mode); if (err < 0) goto error; /* If scanning has stopped, then perform a new scan */ if (mode == 0) { LOGD("%s() Already in automatic mode, but not currently scanning on CS," "trigger a new network scan", __func__); goto do_auto; } /* Now check PS domain */ at_response_free(atresponse); atresponse = NULL; 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; /* Read registration unsolicited mode */ err = at_tok_nextint(&line, &mode); if (err < 0) goto error; /* Read registration status */ err = at_tok_nextint(&line, &mode); if (err < 0) goto error; /* If scanning has stopped, then perform a new scan */ if (mode == 0) { LOGD("%s() Already in automatic mode, but not currently scanning on PS," "trigger a new network scan", __func__); goto do_auto; } else { LOGD("%s() Already in automatic mode and scanning", __func__); goto finish_scan; } do_auto: at_response_free(atresponse); atresponse = NULL; /* This command does two things, one it sets automatic mode, two it starts a new network scan! */ err = at_send_command("AT+COPS=0"); if (err != AT_NOERROR) goto error; finish_scan: at_response_free(atresponse); atresponse = NULL; poll_params->loopcount = 0; poll_params->t = t; enqueueRILEvent(RIL_EVENT_QUEUE_NORMAL, pollOperatorSelected, poll_params, &TIMEVAL_OPERATOR_SELECT_POLL); return; error: free(poll_params); at_response_free(atresponse); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; }
int getSignalStrength(RIL_SignalStrength_v6 *signalStrength){ ATResponse *atresponse = NULL; int err; char *line; int ber; int rssi; memset(signalStrength, 0, sizeof(RIL_SignalStrength_v6)); signalStrength->LTE_SignalStrength.signalStrength = -1; signalStrength->LTE_SignalStrength.rsrp = -1; signalStrength->LTE_SignalStrength.rsrq = -1; signalStrength->LTE_SignalStrength.rssnr = -1; signalStrength->LTE_SignalStrength.cqi = -1; err = at_send_command_singleline("AT+CSQ", "+CSQ:", &atresponse); if (err != AT_NOERROR) goto cind; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto cind; err = at_tok_nextint(&line,&rssi); if (err < 0) goto cind; signalStrength->GW_SignalStrength.signalStrength = rssi; err = at_tok_nextint(&line, &ber); if (err < 0) goto cind; signalStrength->GW_SignalStrength.bitErrorRate = ber; at_response_free(atresponse); atresponse = NULL; /* * If we get 99 as signal strength. Try AT+CIND to give * some indication on what signal strength we got. * * Android calculates rssi and dBm values from this value, so the dBm * value presented in android will be wrong, but this is an error on * android's end. */ if (rssi == 99) { cind: at_response_free(atresponse); atresponse = NULL; err = at_send_command_singleline("AT+CIND?", "+CIND:", &atresponse); if (err != AT_NOERROR) goto error; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* discard the first value */ err = at_tok_nextint(&line, &signalStrength->GW_SignalStrength.signalStrength); if (err < 0) goto error; err = at_tok_nextint(&line, &signalStrength->GW_SignalStrength.signalStrength); if (err < 0) goto error; signalStrength->GW_SignalStrength.bitErrorRate = 99; /* Convert CIND value so Android understands it correctly */ if (signalStrength->GW_SignalStrength.signalStrength > 0) { signalStrength->GW_SignalStrength.signalStrength *= 4; signalStrength->GW_SignalStrength.signalStrength--; } } at_response_free(atresponse); return 0; error: at_response_free(atresponse); return -1; }
/** * WCDMA Network (UTMS, 3G) Neighborhood Cell IDs */ void Get_WCDMA_NCIs(RIL_Token t) { int err = 0; char *p = NULL; int n = 0; ATLine *tmp = NULL; ATResponse *wnci_resp = NULL; RIL_NeighboringCell *ptr_cells[MAX_NUM_NEIGHBOR_CELLS]; err = at_send_command_multiline("AT*EWNCI", "*EWNCI:", &wnci_resp); if (err < 0 || wnci_resp->success == 0) goto error; tmp = wnci_resp->p_intermediates; while (tmp) { if (n > MAX_NUM_NEIGHBOR_CELLS) goto error; p = tmp->line; if (*p == '*') { char *line = p; int uarfcn = 0; int psc = 0; int rscp = 0; int ecno = 0; int pathloss = 0; err = at_tok_start(&line); if (err < 0) goto error; /* UARFCN */ err = at_tok_nextint(&line, &uarfcn); if (err < 0) goto error; /* PSC */ err = at_tok_nextint(&line, &psc); if (err < 0) goto error; /* RSCP */ err = at_tok_nextint(&line, &rscp); if (err < 0) goto error; /* ECNO */ err = at_tok_nextint(&line, &ecno); if (err < 0) goto error; /* PathLoss */ err = at_tok_nextint(&line, &pathloss); if (err < 0) goto error; /* process data for each cell */ ptr_cells[n] = alloca(sizeof(RIL_NeighboringCell)); ptr_cells[n]->rssi = rscp; ptr_cells[n]->cid = alloca(9 * sizeof(char)); sprintf(ptr_cells[n]->cid, "%08x", psc); n++; } tmp = tmp->p_next; } RIL_onRequestComplete(t, RIL_E_SUCCESS, ptr_cells, n * sizeof(RIL_NeighboringCell *)); finally: at_response_free(wnci_resp); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * GSM Network (GPRS, 2G) Neighborhood Cell IDs */ void Get_GSM_NCIs(RIL_Token t) { int err = 0; char *p = NULL; int n = 0; ATLine *tmp = NULL; ATResponse *gnci_resp = NULL; RIL_NeighboringCell *ptr_cells[MAX_NUM_NEIGHBOR_CELLS]; err = at_send_command_multiline("AT*EGNCI", "*EGNCI:", &gnci_resp); if (err < 0 || gnci_resp->success == 0 || gnci_resp->p_intermediates == NULL) goto error; tmp = gnci_resp->p_intermediates; while (tmp) { if (n > MAX_NUM_NEIGHBOR_CELLS) goto error; p = tmp->line; if (*p == '*') { char *line = p; char *plmn = NULL; char *lac = NULL; char *cid = NULL; int arfcn = 0; int bsic = 0; int rxlvl = 0; int ilac = 0; int icid = 0; err = at_tok_start(&line); if (err < 0) goto error; /* PLMN */ err = at_tok_nextstr(&line, &plmn); if (err < 0) goto error; /* LAC */ err = at_tok_nextstr(&line, &lac); if (err < 0) goto error; /* CellID */ err = at_tok_nextstr(&line, &cid); if (err < 0) goto error; /* ARFCN */ err = at_tok_nextint(&line, &arfcn); if (err < 0) goto error; /* BSIC */ err = at_tok_nextint(&line, &bsic); if (err < 0) goto error; /* RxLevel */ err = at_tok_nextint(&line, &rxlvl); if (err < 0) goto error; /* process data for each cell */ ptr_cells[n] = alloca(sizeof(RIL_NeighboringCell)); ptr_cells[n]->rssi = rxlvl; ptr_cells[n]->cid = alloca(9 * sizeof(char)); sscanf(lac,"%x",&ilac); sscanf(cid,"%x",&icid); sprintf(ptr_cells[n]->cid, "%08x", ((ilac << 16) + icid)); n++; } tmp = tmp->p_next; } RIL_onRequestComplete(t, RIL_E_SUCCESS, ptr_cells, n * sizeof(RIL_NeighboringCell *)); finally: at_response_free(gnci_resp); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_REQUEST_NEIGHBORINGCELL_IDS */ void requestNeighboringCellIDs(void *data, size_t datalen, RIL_Token t) { (void) data; (void) datalen; int network = -1; int dummy = 0; char *dummyStr = NULL; int err = 0; ATResponse *cops_resp = NULL; char *line = NULL; /* Determine network radio access technology (AcT) */ err = at_send_command_singleline("AT+COPS?", "+COPS:", &cops_resp); if (err < 0 || cops_resp->success == 0) goto error; line = cops_resp->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; /* Mode */ err = at_tok_nextint(&line, &dummy); if (err < 0) goto error; /* Check to see if not registered */ if (!at_tok_hasmore(&line)) { No_NCIs(t); goto finally; } /* Format */ err = at_tok_nextint(&line, &dummy); if (err < 0) goto error; /* Operator */ err = at_tok_nextstr(&line, &dummyStr); if (err < 0) goto error; /* Network */ err = at_tok_nextint(&line, &network); if (err < 0) goto error; switch (network) { case 0: /* GSM (GPRS,2G)*/ case 3: /* GSM w/EGPRS (EDGE, 2.75G)*/ Get_GSM_NCIs(t); break; case 1: /* GSM Compact (Not supported)*/ goto error; break; case 2: /* UTRAN (WCDMA/UMTS, 3G)*/ case 4: /* UTRAN w/HSDPA (HSDPA,3G)*/ case 5: /* UTRAN w/HSUPA (HSUPA,3G)*/ case 6: /* UTRAN w/HSDPA and HSUPA (HSPA,3G)*/ Get_WCDMA_NCIs(t); break; default: goto error; } finally: at_response_free(cops_resp); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }
/** * RIL_REQUEST_OPERATOR * * Request current operator ONS or EONS. */ void requestOperator(void *data, size_t datalen, RIL_Token t) { (void) data; (void) datalen; int err; int i; int skip; ATLine *cursor; static const int num_resp_lines = 3; char *response[num_resp_lines]; ATResponse *atresponse = NULL; memset(response, 0, sizeof(response)); err = at_send_command_multiline ("AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", "+COPS:", &atresponse); if (err != AT_NOERROR) goto error; /* We expect 3 lines here: * +COPS: 0,0,"T - Mobile" * +COPS: 0,1,"TMO" * +COPS: 0,2,"310170" */ for (i = 0, cursor = atresponse->p_intermediates; cursor != NULL && i < num_resp_lines; cursor = cursor->p_next, i++) { char *line = cursor->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &skip); if (err < 0) goto error; /* If we're unregistered, we may just get a "+COPS: 0" response. */ if (!at_tok_hasmore(&line)) { response[i] = NULL; continue; } err = at_tok_nextint(&line, &skip); if (err < 0) goto error; /* A "+COPS: 0, n" response is also possible. */ if (!at_tok_hasmore(&line)) { response[i] = NULL; continue; } err = at_tok_nextstr(&line, &(response[i])); if (err < 0) goto error; } if (i != num_resp_lines) goto error; /* * Check if modem returned an empty string, and fill it with MNC/MMC * if that's the case. */ if (response[2] && response[0] && strlen(response[0]) == 0) { response[0] = alloca(strlen(response[2]) + 1); strcpy(response[0], response[2]); } if (response[2] && response[1] && strlen(response[1]) == 0) { response[1] = alloca(strlen(response[2]) + 1); strcpy(response[1], response[2]); } RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); finally: at_response_free(atresponse); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); goto finally; }