/**
 * Poll +COPS? and return a success, or if the loop counter reaches
 * REPOLL_OPERATOR_SELECTED, return generic failure.
 */
static void pollOperatorSelected(void *params)
{
    int err = 0;
    int response = 0;
    char *line = NULL;
    ATResponse *atresponse = NULL;
    struct operatorPollParams *poll_params;
    RIL_Token t;

    assert(params != NULL);

    poll_params = (struct operatorPollParams *) params;
    t = poll_params->t;

    if (poll_params->loopcount >= REPOLL_OPERATOR_SELECTED)
        goto error;

    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;

    /* If we don't get more than the COPS: {0-4} we are not registered.
       Loop and try again. */
    if (!at_tok_hasmore(&line)) {
        switch (s_registrationDeniedReason) {
        case IMSI_UNKNOWN_IN_HLR: /* fall through */
        case ILLEGAL_ME:
            RIL_onRequestComplete(t, RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
            free(poll_params);
            break;
        default:
            poll_params->loopcount++;
            enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, pollOperatorSelected,
                            poll_params, &TIMEVAL_OPERATOR_SELECT_POLL);
        }
    } else {
        /* We got operator, throw a success! */
        RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
        free(poll_params);
    }

    at_response_free(atresponse);
    return;

error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    free(poll_params);
    at_response_free(atresponse);
    return;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/**
 * 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;
}
Esempio n. 4
0
/**
 * RIL_UNSOL_ON_USSD
 *
 * Called when a new USSD message is received.
 */
int onUSSDReceived(const char *s, char* sms_pdu)
{
	char *line, *linestart;
	int typeCode, count, err, len;
	char *message;
	char *outputmessage;
	char *responseStr[2];

	linestart=line=strdup(s);
	err = at_tok_start(&line);
	if(err < 0) goto out;

	err = at_tok_nextint(&line, &typeCode);
	if(err < 0) goto out;

	if(at_tok_hasmore(&line)) {

		int format;
		char message[256];
		int n = sscanf(s+6,"%*d,\"%[^\"]\",%d",message,&format);

		LOGD("%s,%d",message,format);

		if(format == 15){
			responseStr[1] = malloc(strlen(message)+1);
			strcpy(responseStr[1],message);    
		}else{
			int len = strlen(message);
			outputmessage = malloc(len/2);
			gsm_hex_to_bytes((cbytes_t)message,len,(bytes_t)outputmessage);

			responseStr[1] = malloc(len);
			len = ucs2_to_utf8((cbytes_t)outputmessage,len/2,(bytes_t)responseStr[1]);
			free(outputmessage);    
		}
		count = 2;
	} else {
		responseStr[1]=NULL;
		count = 1;
	}
	free(linestart);
	asprintf(&responseStr[0], "%d", typeCode);
	RIL_onUnsolicitedResponse (RIL_UNSOL_ON_USSD, responseStr, count*sizeof(char*));
out:
	return UNSOLICITED_SUCCESSED;
}
Esempio n. 5
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;
}
/**
 * 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_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;
}
Esempio n. 9
0
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);
}