/** * RIL_UNSOL_NITZ_TIME_RECEIVED * * Called when radio has received a NITZ time message. * * "data" is const char * pointing to NITZ time string * */ void onNetworkTimeReceived(const char *s) { /* Special handling of DST for Android framework Module does not include DST correction in NITZ, but Android expects it */ char *line, *tok, *response, *time, *timestamp; int tz, dst; tok = line = strdup(s); if (NULL == tok) { LOGE("%s() Failed to allocate memory", __func__); return; } at_tok_start(&tok); LOGD("%s() Got nitz: %s", __func__, s); if (at_tok_nextint(&tok, &tz) != 0) LOGE("%s() Failed to parse NITZ tz %s", __func__, s); else if (at_tok_nextstr(&tok, &time) != 0) LOGE("%s() Failed to parse NITZ time %s", __func__, s); else if (at_tok_nextstr(&tok, ×tamp) != 0) LOGE("%s() Failed to parse NITZ timestamp %s", __func__, s); else { if (at_tok_nextint(&tok, &dst) != 0) { dst = 0; LOGE("%s() Failed to parse NITZ dst, fallbacking to dst=0 %s", __func__, s); } if (!(asprintf(&response, "%s%+03d,%02d", time + 2, tz + (dst * 4), dst))) { free(line); LOGE("%s() Failed to allocate string", __func__); return; } if (strncmp(response, last_nitz_time, strlen(response)) != 0) { RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, response, sizeof(char *)); strncpy(last_nitz_time, response, strlen(response)); } else LOGD("%s() Discarding NITZ since it hasn't changed since last update", __func__); free(response); enqueueRILEvent(RIL_EVENT_QUEUE_NORMAL, sendTime, NULL, NULL); } free(line); }
static int get_phone_book(int index, phone_book_t* pb) { int ret = -1, err; char* cmd = NULL; char* line = NULL; char* buffer = NULL; ATResponse *p_response = NULL; asprintf(&cmd,"AT+CPBR=%d", index); at_send_command("AT+CSCS=\"UCS2\"", NULL); err = at_send_command_singleline(cmd,"+CPBR:",&p_response); if (err < 0 || !p_response || p_response->success == 0) goto error; if (p_response && p_response->p_intermediates) { line=p_response->p_intermediates->line; err=at_tok_start(&line); if (err < 0) goto error; err=at_tok_nextint(&line,&(pb->index)); if (err < 0) goto error; err=at_tok_nextstr(&line,&buffer); if (err < 0) goto error; strcpy(pb->number, buffer); err=at_tok_nextint(&line,&(pb->code)); if (err < 0) goto error; err=at_tok_nextstr(&line,&buffer); if (err < 0) goto error; strcpy(pb->alpha, buffer); } ret = 0; error: at_response_free(p_response); free(cmd); return ret; }
static char *getCharEncoding(void) { int err; char *line, *chSet; ATResponse *p_response = NULL; err = at_send_command_singleline("AT+CSCS?", "+CSCS:", &p_response); if (err < 0) { LOGE("requestSetupDefaultPDP: Failed to read AT+CSCS?"); return NULL; } line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) return NULL; err = at_tok_nextstr(&line, &chSet); if (err < 0) 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")) { return strdup(chSet); } else { return strdup("UCS-2"); } at_response_free(p_response); }
void requestGetSMSCAddress(void *data, size_t datalen, RIL_Token t) { ATResponse *atresponse = NULL; int err; char *line; char *response; err = at_send_command_singleline("AT+CSCA?", "+CSCA:", &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_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; }
static int onNewMesssageByIndex(char* s, char* sms_pdu) { char *line = NULL; int err; /* can't issue AT commands here -- call on main thread */ int index; char *response = NULL; line = strdup(s); at_tok_start(&line); err = at_tok_nextstr(&line, &response); if (err < 0) { LOGD("sms request fail"); goto out; } if (strcmp(response, "SM")) { LOGD("sms request arrive but it is not a new sms"); goto out; } /* Read the memory location of the sms */ err = at_tok_nextint(&line, &index); if (err < 0) { LOGD("error parse location"); goto out; } out: free(line); RIL_requestTimedCallback (readMessageByIndex, (void *)index, NULL); return UNSOLICITED_SUCCESSED; }
void onStkCallControl(char* urc, RILChannelCtx* p_channel) { RIL_SOCKET_ID rid = getRILIdByChannelCtx(p_channel); int err, i = 0; char *p_cur = (char *)urc; char *responseStr[NUM_STK_CALL_CTRL] = {0}; LOGD("onStkCallControl URC = %s", urc); /** * +STKCTRL: <mmi_info_type>,"<alphs_id>","<address>or<ss string>or<ussd string>" **/ err = at_tok_start(&p_cur); if (err < 0) goto error; for (i = 0; i < NUM_STK_CALL_CTRL; i++) { err = at_tok_nextstr(&p_cur, &(responseStr[i])); if (err < 0) { //responseStr[i] = 0xFF; LOGE("There is something wrong with item [%d]",i); }//goto error; } RIL_onUnsolicitedResponse( RIL_UNSOL_STK_CALL_CTRL, responseStr, sizeof(responseStr), rid); return; error: LOGE("There is something wrong with the +STKCTRL"); }
static int simIOGetLogicalChannel(void) { ATResponse *atresponse = NULL; static int g_lc = 0; int err; if (g_lc == 0) { struct tlv tlvApp, tlvAppId; char *line; char *resp; err = at_send_command_singleline("AT+CUAD", "+CUAD:", &atresponse); if (err != AT_NOERROR) return g_lc; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextstr(&line, &resp); if (err < 0) goto finally; err = parseTlv(resp, &resp[strlen(resp)], &tlvApp); if (err < 0) goto finally; if (tlvApp.tag != 0x61) { /* Application */ err = -EINVAL; goto finally; } err = parseTlv(tlvApp.data, tlvApp.end, &tlvAppId); if (err < 0) goto finally; if (tlvAppId.tag != 0x4F) { /* Application ID */ err = -EINVAL; goto finally; } at_response_free(atresponse); err = at_send_command_singleline("AT+CCHO=\"%.*s\"", "+CCHO:", &atresponse, tlvAppId.end - tlvAppId.data, tlvAppId.data); if (err != AT_NOERROR) return g_lc; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &g_lc); if (err < 0) goto finally; } finally: at_response_free(atresponse); return g_lc; }
int sendSimIOCmdICC(const RIL_SIM_IO_v6 *ioargs, ATResponse **atresponse, RIL_SIM_IO_Response *sr) { int err; char *fmt; char *arg6; char *arg7; char *line; /* FIXME Handle pin2. */ memset(sr, 0, sizeof(*sr)); arg6 = ioargs->data; arg7 = ioargs->path; if (arg7 && arg6) { fmt = "AT+CRSM=%d,%d,%d,%d,%d,\"%s\",\"%s\""; } else if (arg7) { fmt = "AT+CRSM=%d,%d,%d,%d,%d,,\"%s\""; arg6 = arg7; } else if (arg6) { fmt = "AT+CRSM=%d,%d,%d,%d,%d,\"%s\""; } else { fmt = "AT+CRSM=%d,%d,%d,%d,%d"; } err = at_send_command_singleline(fmt, "+CRSM:", atresponse,ioargs->command, ioargs->fileid, ioargs->p1, ioargs->p2, ioargs->p3, arg6, arg7); if (err != AT_NOERROR) return err; line = (*atresponse)->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &(sr->sw1)); if (err < 0) goto finally; err = at_tok_nextint(&line, &(sr->sw2)); if (err < 0) goto finally; if (at_tok_hasmore(&line)) { err = at_tok_nextstr(&line, &(sr->simResponse)); if (err < 0) goto finally; } finally: return err; }
/** * Note: directly modified line and has *p_call point directly into * modified line */ static int callFromCLCCLine(char *line, RIL_Call *p_call) { //+CLCC: 1,0,2,0,0,\"+18005551212\",145 // index,isMT,state,mode,isMpty(,number,TOA)? int err; int state; int mode; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &(p_call->index)); if (err < 0) goto error; err = at_tok_nextbool(&line, &(p_call->isMT)); if (err < 0) goto error; err = at_tok_nextint(&line, &state); if (err < 0) goto error; err = clccStateToRILState(state, &(p_call->state)); if (err < 0) goto error; err = at_tok_nextint(&line, &mode); if (err < 0) goto error; p_call->isVoice = (mode == 0); err = at_tok_nextbool(&line, &(p_call->isMpty)); if (err < 0) goto error; if (at_tok_hasmore(&line)) { err = at_tok_nextstr(&line, &(p_call->number)); /* tolerate null here */ if (err < 0) return 0; // Some lame implementations return strings // like "NOT AVAILABLE" in the CLCC line if (p_call->number != NULL && 0 == strspn(p_call->number, "+0123456789")) p_call->number = NULL; err = at_tok_nextint(&line, &p_call->toa); if (err < 0) goto error; } p_call->uusInfo = NULL; return 0; error: LOGE("invalid CLCC line\n"); return -1; }
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; }
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; }
/** * 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; }
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; }
/** * 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); }
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); }
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; }
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; }
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 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; }
/** * 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; }
/** * 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_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; }
/** * 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; }
void _requestOperatorWCDMA(void *data, size_t datalen, RIL_Token t) { int err; int i; int skip; ATLine *p_cur; char *response[3]; memset(response, 0, sizeof(response)); ATResponse *p_response = NULL; err = at_send_command_multiline( "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", "+COPS:", &p_response); /* we expect 3 lines here: * +COPS: 0,0,"T - Mobile" * +COPS: 0,1,"TMO" * +COPS: 0,2,"310170" */ if (err != 0) goto error; for (i = 0, p_cur = p_response->p_intermediates ; p_cur != NULL ; p_cur = p_cur->p_next, i++ ) { char *line = p_cur->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 != 3) { /* expect 3 lines exactly */ goto error; } RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response)); at_response_free(p_response); return; error: LOGE("requestOperator must not return error when radio is on"); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); at_response_free(p_response); }
/** * 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; }
void* onSuplNiRequest(void *data) { int err; int ignore; char *line; GpsCtrlSuplNiRequest ni_request; GpsCtrlContext *context = get_context(); line = (char *) data; LOGD("%s, %s", __FUNCTION__, line); err = at_tok_start(&line); if (err < 0) { LOGE("%s error parsing data", __FUNCTION__); return NULL; } err = at_tok_nextint(&line, &ignore); if (err < 0) { LOGE("%s error parsing data", __FUNCTION__); return NULL; } err = at_tok_nextint(&line, &ni_request.message_id); if (err < 0) { LOGE("%s error parsing data message id", __FUNCTION__); return NULL; } err = at_tok_nextint(&line, &ni_request.message_type); if (err < 0) { LOGE("%s error parsing data message type", __FUNCTION__); return NULL; } err = at_tok_nextint(&line, &ni_request.requestor_id_type); if (err < 0) { LOGW("%s error parsing data requestor id type", __FUNCTION__); ni_request.requestor_id_type = -1; } err = at_tok_nextstr(&line, &ni_request.requestor_id_text); if (err < 0) { LOGW("%s error parsing data requestor id text", __FUNCTION__); ni_request.requestor_id_text = ""; } err = at_tok_nextint(&line, &ni_request.client_name_type); if (err < 0) { LOGW("%s error parsing data client name type", __FUNCTION__); ni_request.client_name_type = -1; } err = at_tok_nextstr(&line, &ni_request.client_name_text); if (err < 0) { LOGW("%s error parsing data clien name text", __FUNCTION__); ni_request.client_name_text = ""; } context->supl_ni_callback(&ni_request); return NULL; }
void requestOrSendPDPContextList(RIL_Token *token) { ATResponse *atresponse = NULL; RIL_Data_Call_Response_v6 response; int e2napState = getE2napState(); int err; int cid; char *line, *apn, *type; char* addresses = NULL; char* dnses = NULL; char* gateways = NULL; in_addr_t addr; in_addr_t gateway; memset(&response, 0, sizeof(response)); response.ifname = ril_iface; err = at_send_command_multiline("AT+CGDCONT?", "+CGDCONT:", &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, &cid); if (err < 0) goto error; response.cid = cid; if (e2napState == E2NAP_ST_CONNECTED) response.active = 1; err = at_tok_nextstr(&line, &type); if (err < 0) goto error; response.type = alloca(strlen(type) + 1); strcpy(response.type, type); err = at_tok_nextstr(&line, &apn); if (err < 0) goto error; at_response_free(atresponse); atresponse = NULL; /* TODO: Check if we should check ip for a specific CID instead */ if (parse_ip_information(&addresses, &gateways, &dnses, &addr, &gateway) < 0) { LOGE("%s() Failed to parse network interface data", __func__); goto error; } response.addresses = addresses; response.gateways = gateways; response.dnses = dnses; response.suggestedRetryTime = -1; if (token != NULL) RIL_onRequestComplete(*token, RIL_E_SUCCESS, &response, sizeof(RIL_Data_Call_Response_v6)); else RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, &response, sizeof(RIL_Data_Call_Response_v6)); free(addresses); free(gateways); free(dnses); return; error: if (token != NULL) RIL_onRequestComplete(*token, RIL_E_GENERIC_FAILURE, NULL, 0); else RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, NULL, 0); at_response_free(atresponse); }
void onStkProactiveCommand(char* urc, RILChannelCtx* p_channel) { int err = 0, temp_int = 0, type_pos = 0; ATResponse *p_response = NULL; char *temp_str; char *cmd; RIL_SOCKET_ID rid = getRILIdByChannelCtx(p_channel); int urc_len = 0; bool isStkServiceRunning = false; char *pProCmd = NULL; if(urc != NULL) urc_len = strlen(urc); isStkServiceRunning = getStkServiceRunningFlag(rid); LOGD("onStkProactiveCommand check %d.urc_len %d.",isStkServiceRunning, urc_len); if(false == isStkServiceRunning) { setStkProactiveCmdQueuedFlag(rid, true); pProCmd = (char*)calloc(1, urc_len + 1); memset(pProCmd, 0x0, urc_len + 1); memcpy(pProCmd, urc, urc_len); setStkQueuedProCmdWithRid(rid, pProCmd); LOGD("STK service is not running yet.[%p]",pProCmd); return; } err = at_tok_start(&urc); err = at_tok_nextint(&urc, &temp_int); err = at_tok_nextstr(&urc, &temp_str); if(temp_str[2] <= '7' ) { /*add comment*/ type_pos = 10; } else { type_pos = 12; } switch(checkStkCommandType(&(temp_str[type_pos]))) { case CMD_REFRESH: onSimRefresh(&(temp_str[type_pos - 6]), p_channel); // return; break; case CMD_DTMF: g_stk_at.cmd_type = CMD_DTMF; g_stk_at.cmd_res = 0; g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_0, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); RIL_onUnsolicitedResponseSocket ( RIL_UNSOL_STK_EVENT_NOTIFY, temp_str, strlen(temp_str), rid); return; break; default: break; } RIL_onUnsolicitedResponseSocket ( RIL_UNSOL_STK_PROACTIVE_COMMAND, temp_str, strlen(temp_str), rid); return; }
void onStkEventNotify(char* urc, RILChannelCtx* p_channel) { int err = 0; int temp_int = 0; int cmd_type = 0; int type_pos = 0; int cmd_not_understood = 0; /* mtk02374 20100502*/ unsigned int duration = 0; char *temp_str; char *cmd; RIL_SOCKET_ID rid = getRILIdByChannelCtx(p_channel); int urc_len = 0; bool isStkServiceRunning = false; char *pEventNotify = NULL; ATResponse *p_response = NULL; if(urc != NULL) urc_len = strlen(urc); isStkServiceRunning = getStkServiceRunningFlag(rid); LOGD("onStkEventNotify check %d.urc_len %d.", isStkServiceRunning, urc_len); if(false == isStkServiceRunning) { setStkEventNotifyQueuedFlag(rid, true); pEventNotify = (char*)calloc(1, urc_len + 1); memset(pEventNotify, 0x0, urc_len + 1); memcpy(pEventNotify, urc, urc_len); setStkQueuedEventNotifyWithRid(rid, pEventNotify); LOGD("STK service is not running yet.[%p]", pEventNotify); return; } err = at_tok_start(&urc); err = at_tok_nextint(&urc, &temp_int); err = at_tok_nextstr(&urc, &temp_str); if(temp_str[2] <= '7' ) { /*add comment*/ type_pos = 10; } else if(temp_str[2] > '7' ) { type_pos = 12; } cmd_not_understood = checkStkCmdDisplay(&(temp_str[type_pos - 6])); /*temp_str[type_pos -6] points to cmd_detail tag*/ switch(checkStkCommandType(&(temp_str[type_pos]))) { case CMD_REFRESH: onSimRefresh(&(temp_str[type_pos - 6]), p_channel); break; case CMD_SETUP_CALL: cmd_type = CMD_SETUP_CALL; if(cmd_not_understood == 0) { duration = findStkCallDuration(&temp_str[type_pos - 6]); /*temp_str[type_pos -6] points to cmd_detail tag*/ } else { g_stk_at.cmd_type = CMD_SETUP_CALL; g_stk_at.cmd_res = 50; g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_0, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); } break; case CMD_SEND_SMS: g_stk_at.cmd_type = CMD_SEND_SMS; g_stk_at.cmd_res = 0; g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_SMS, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); break; case CMD_SEND_SS: g_stk_at.cmd_type = CMD_SEND_SS; if(cmd_not_understood == 0) { g_stk_at.cmd_res = 0; } else { g_stk_at.cmd_res = 50; } g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_0, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); break; case CMD_SEND_USSD: g_stk_at.cmd_type = CMD_SEND_USSD; if(cmd_not_understood == 0) { g_stk_at.cmd_res = 0; } else { g_stk_at.cmd_res = 50; } g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_0, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); break; case CMD_DTMF: g_stk_at.cmd_type = CMD_DTMF; g_stk_at.cmd_res = 0; g_stk_at.rid = rid; RIL_requestProxyTimedCallback(onStkAtSendFromUrc, NULL, &TIMEVAL_0, getChannelCtxbyProxy(rid)->id, "onStkAtSendFromUrc"); break; default: break; } RIL_onUnsolicitedResponseSocket ( RIL_UNSOL_STK_EVENT_NOTIFY, temp_str, strlen(temp_str), rid); if(CMD_SETUP_CALL == cmd_type) { RIL_onUnsolicitedResponseSocket ( RIL_UNSOL_STK_CALL_SETUP, &duration, sizeof(duration), rid); } return; }
void requestStkSendEnvelopeCommandWithStatus (void *data, size_t datalen, RIL_Token t) { char* cmd; ATResponse *p_response = NULL; int err; char *line = NULL; RIL_SIM_IO_Response sr; ATLine *p_cur = NULL; bool headIntermediate = true; RIL_STK_UNUSED_PARM(datalen); memset(&sr, 0, sizeof(sr)); asprintf(&cmd, "AT+CUSATE=\"%s\"", (char *)data); err = at_send_command_raw(cmd, &p_response, STK_CHANNEL_CTX); if (err < 0 || p_response->success == 0) { goto error; } for (p_cur = p_response->p_intermediates; p_cur != NULL; p_cur = p_cur->p_next) { line = p_cur->line; if (NULL == line) { LOGE("requestStkSendEnvelopeCommand ok but no intermediates."); goto done; } if (headIntermediate) { headIntermediate = false; LOGD("CUSATE,[%s]", line); //sub_line = strstr(line, "+CUSATE2:"); err = at_tok_start(&line); if (err < 0) { LOGE("get +CUSATE: error."); goto error; } err = at_tok_nextstr(&line, &(sr.simResponse)); if (err < 0) { LOGE("response data is null."); goto error; } } else { /*skip <busy> field, just deal with sw1 sw2.*/ LOGD("CUSATE2,[%s]", line); err = at_tok_start(&line); if (err < 0) { LOGE("get +CUSATE2: error."); goto error; } err = at_tok_nextint(&line, &(sr.sw1)); if (err < 0) goto error; err = at_tok_nextint(&line, &(sr.sw2)); if (err < 0) goto error; LOGD("requestStkSendEnvelopeCommand sw: %02x, %02x", sr.sw1, sr.sw2); } } goto done; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); free(cmd); at_response_free(p_response); done: RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr)); free(cmd); at_response_free(p_response); }