コード例 #1
0
/**
 * SIM ready means any commands that access the SIM will work, including:
 *  AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
 *  (all SMS-related commands).
 */
void pollSIMState(void *param)
{
    if (((int) param) != 1 &&
        getRadioState() != RADIO_STATE_SIM_NOT_READY &&
        getRadioState() != RADIO_STATE_SIM_LOCKED_OR_ABSENT)
        /* No longer valid to poll. */
        return;

    switch (getSIMStatus()) {
    case SIM_NOT_READY:
        ALOGI("SIM_NOT_READY, poll for sim state.");
        enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, pollSIMState, NULL,
                        &TIMEVAL_SIMPOLL);
        return;

    case SIM_PIN2:
    case SIM_PUK2:
    case SIM_PUK2_PERM_BLOCKED:
    case SIM_READY:
        setRadioState(RADIO_STATE_SIM_READY);
        enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, setPollSIMState, (void *) 1, NULL);
        return;
    case SIM_ABSENT:
        setRadioState(RADIO_STATE_SIM_LOCKED_OR_ABSENT);
        enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, setPollSIMState, (void *) 0, NULL);
        return;
    case SIM_PIN:
    case SIM_PUK:
    case SIM_NETWORK_PERSO:
    case SIM_NETWORK_SUBSET_PERSO:
    case SIM_SERVICE_PROVIDER_PERSO:
    case SIM_CORPORATE_PERSO:
    case SIM_SIM_PERSO:
    case SIM_STERICSSON_LOCK:
    case SIM_BLOCKED:
    case SIM_PERM_BLOCKED:
    case SIM_NETWORK_PERSO_PUK:
    case SIM_NETWORK_SUBSET_PERSO_PUK:
    case SIM_SERVICE_PROVIDER_PERSO_PUK:
    case SIM_CORPORATE_PERSO_PUK:
    /* pass through, do not break */
    default:
        setRadioState(RADIO_STATE_SIM_LOCKED_OR_ABSENT);
        enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, setPollSIMState, (void *) 1, NULL);
        return;
    }
}
コード例 #2
0
/**
 * Fetch information about UICC card type (SIM/USIM)
 *
 * \return UICC_Type: type of UICC card.
 */
static UICC_Type getUICCType(void)
{
    ATResponse *atresponse = NULL;
    static UICC_Type UiccType = UICC_TYPE_UNKNOWN;
    int err;

    if (getRadioState() == RADIO_STATE_OFF ||
        getRadioState() == RADIO_STATE_UNAVAILABLE) {
        return UICC_TYPE_UNKNOWN;
    }

    if (UiccType == UICC_TYPE_UNKNOWN) {
        err = at_send_command_singleline("AT+CUAD", "+CUAD:", &atresponse);
        if (err == AT_NOERROR) {
            /* USIM */
            if(strstr(atresponse->p_intermediates->line, USIM_APPLICATION_ID)){
                UiccType = UICC_TYPE_USIM;
                ALOGI("Detected card type USIM - stored");
            } else {
                /* should maybe be unknown */
                UiccType = UICC_TYPE_SIM;
            }
        } else if (at_get_error_type(err) != AT_ERROR) {
            /* Command failed - unknown card */
            UiccType = UICC_TYPE_UNKNOWN;
            ALOGE("%s() Failed to detect card type - Retry at next request", __func__);
        } else {
            /* Legacy SIM */
            /* TODO: CUAD only responds OK if SIM is inserted.
             *       This is an inccorect AT response...
             */
            UiccType = UICC_TYPE_SIM;
            ALOGI("Detected card type Legacy SIM - stored");
        }
        at_response_free(atresponse);
    }

    return UiccType;
}
コード例 #3
0
static RIL_RadioState
currentState(RILId rid, int *sim_status)
{
    if (sim_status != NULL)
    {
        #ifdef MTK_GEMINI
        *sim_status = sim_inserted_status;
        #else
        *sim_status = 0;
        #endif
     }
    
    return getRadioState(rid);
}
コード例 #4
0
static int disconnect(void)
{
    int e2napState, i, err;

    err = at_send_command("AT*ENAP=0");
    if (err != AT_NOERROR && at_get_error_type(err) != CME_ERROR)
        return -1;

    for (i = 0; i < MBM_ENAP_DISCONNECT_TIME * 5; i++) {
        e2napState = getE2napState();
        if ((e2napState == E2NAP_STATE_DISCONNECTED) ||
                (e2napState == E2NAP_STATE_UNKNOWN) ||
                (RADIO_STATE_UNAVAILABLE == getRadioState()))
            break;
        usleep(200 * 1000);
    }
    return 0;
}
コード例 #5
0
/** Returns one of SIM_*. Returns SIM_NOT_READY on error. */
static SIM_Status getSIMStatus(void)
{
    ATResponse *atresponse = NULL;
    int err;
    SIM_Status ret = SIM_ABSENT;
    char *cpinLine;
    char *cpinResult;

    if (s_simRemoved)
        return SIM_ABSENT;

    if (getRadioState() == RADIO_STATE_OFF ||
        getRadioState() == RADIO_STATE_UNAVAILABLE) {
        return SIM_NOT_READY;
    }

    err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &atresponse);

    if (err != AT_NOERROR) {
        if (at_get_error_type(err) == AT_ERROR)
            return SIM_NOT_READY;

        switch (at_get_cme_error(err)) {
        case CME_SIM_NOT_INSERTED:
            ret = SIM_ABSENT;
            break;
        case CME_SIM_PIN_REQUIRED:
            ret = SIM_PIN;
            break;
        case CME_SIM_PUK_REQUIRED:
            ret = SIM_PUK;
            break;
        case CME_SIM_PIN2_REQUIRED:
            ret = SIM_PIN2;
            break;
        case CME_SIM_PUK2_REQUIRED:
            ret = SIM_PUK2;
            break;
        case CME_NETWORK_PERSONALIZATION_PIN_REQUIRED:
            ret = SIM_NETWORK_PERSO;
            break;
        case CME_NETWORK_PERSONALIZATION_PUK_REQUIRED:
            ret = SIM_NETWORK_PERSO_PUK;
            break;
        case CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED:
            ret = SIM_NETWORK_SUBSET_PERSO;
            break;
        case CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED:
            ret = SIM_NETWORK_SUBSET_PERSO_PUK;
            break;
        case CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED:
            ret = SIM_SERVICE_PROVIDER_PERSO;
            break;
        case CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED:
            ret = SIM_SERVICE_PROVIDER_PERSO_PUK;
            break;
        case CME_PH_SIMLOCK_PIN_REQUIRED: /* PUK not in use by modem */
            ret = SIM_SIM_PERSO;
            break;
        case CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED:
            ret = SIM_CORPORATE_PERSO;
            break;
        case CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED:
            ret = SIM_CORPORATE_PERSO_PUK;
            break;
        default:
            ret = SIM_NOT_READY;
            break;
        }
        return ret;
    }

    /* CPIN? has succeeded, now look at the result. */

    cpinLine = atresponse->p_intermediates->line;
    err = at_tok_start(&cpinLine);

    if (err < 0) {
        ret = SIM_NOT_READY;
        goto done;
    }

    err = at_tok_nextstr(&cpinLine, &cpinResult);

    if (err < 0) {
        ret = SIM_NOT_READY;
        goto done;
    }

    if (0 == strcmp(cpinResult, "READY")) {
        ret = SIM_READY;
    } else if (0 == strcmp(cpinResult, "SIM PIN")) {
        ret = SIM_PIN;
    } else if (0 == strcmp(cpinResult, "SIM PUK")) {
        ret = SIM_PUK;
    } else if (0 == strcmp(cpinResult, "SIM PIN2")) {
        ret = SIM_PIN2;
    } else if (0 == strcmp(cpinResult, "SIM PUK2")) {
        ret = SIM_PUK2;
    } else if (0 == strcmp(cpinResult, "PH-NET PIN")) {
        ret = SIM_NETWORK_PERSO;
    } else if (0 == strcmp(cpinResult, "PH-NETSUB PIN")) {
        ret = SIM_NETWORK_SUBSET_PERSO;
    } else if (0 == strcmp(cpinResult, "PH-SP PIN")) {
        ret = SIM_SERVICE_PROVIDER_PERSO;
    } else if (0 == strcmp(cpinResult, "PH-CORP PIN")) {
        ret = SIM_CORPORATE_PERSO;
    } else if (0 == strcmp(cpinResult, "PH-SIMLOCK PIN")) {
        ret = SIM_SIM_PERSO;
    } else if (0 == strcmp(cpinResult, "PH-ESL PIN")) {
        ret = SIM_STERICSSON_LOCK;
    } else if (0 == strcmp(cpinResult, "BLOCKED")) {
        int numRetries = getNumRetries(RIL_REQUEST_ENTER_SIM_PUK);
        if (numRetries == -1 || numRetries == 0)
            ret = SIM_PERM_BLOCKED;
        else
            ret = SIM_PUK2_PERM_BLOCKED;
    } else if (0 == strcmp(cpinResult, "PH-SIM PIN")) {
        /*
         * Should not happen since lock must first be set from the phone.
         * Setting this lock is not supported by Android.
         */
        ret = SIM_BLOCKED;
    } else {
        /* Unknown locks should not exist. Defaulting to "sim absent" */
        ret = SIM_ABSENT;
    }
done:
    at_response_free(atresponse);
    return ret;
}
コード例 #6
0
static RIL_RadioState
currentState()
{
    return getRadioState();
}
コード例 #7
0
void requestSetupDefaultPDP(void *data, size_t datalen, RIL_Token t)
{
    in_addr_t addr;
    in_addr_t gateway;

    const char *apn, *user, *pass, *auth;
    char *addresses = NULL;
    char *gateways = NULL;
    char *dnses = NULL;
    const char *type = NULL;

    RIL_Data_Call_Response_v6 response;

    int e2napState = getE2napState();
    int err = -1;
    int cme_err, i, prof;

    (void) data;
    (void) datalen;

    prof = atoi(((const char **) data)[1]);
    apn = ((const char **) data)[2];
    user = ((const char **) data)[3];
    pass = ((const char **) data)[4];
    auth = ((const char **) data)[5];
    type = getNWType(((const char **) data)[6]);

    s_lastPdpFailCause = PDP_FAIL_ERROR_UNSPECIFIED;

    memset(&response, 0, sizeof(response));
    response.ifname = ril_iface;
    response.cid = prof + 1;
    response.active = 0;
    response.type = (char *) type;
    response.suggestedRetryTime = -1;

    /* Handle case where Android framework tries to setup multiple PDPs
       when sending/receiving MMS. Tear down the default context if any
       attempt is made to setup a new context with different DataProfile.
       Requires changes to Android framework (RILConstants.java and
       GsmDataConnectionTracker.java). This need to be in place until the
       framework properly handles priorities on APNs */
    if (e2napState > E2NAP_STATE_DISCONNECTED) {
        if (prof > RIL_DATA_PROFILE_DEFAULT) {
            ALOGD("%s() tearing down default cid:%d to allow cid:%d",
                        __func__, s_ActiveCID, prof + 1);
            s_DeactCalled = 1;
            if (disconnect()) {
                goto down;
            } else {
                e2napState = getE2napState();

                if (e2napState != E2NAP_STATE_DISCONNECTED)
                    goto error;

                if (ifc_init())
                    goto error;

                if (ifc_down(ril_iface))
                    goto error;

                ifc_close();
                requestOrSendPDPContextList(NULL);
            }
        } else {
            ALOGE("%s() denying data connection to APN '%s' Multiple PDP not supported!",
                                __func__, apn);
            response.status = PDP_FAIL_INSUFFICIENT_RESOURCES;
            RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
            return;
        }
    }

down:
    e2napState = setE2napState(E2NAP_STATE_UNKNOWN);

    ALOGD("%s() requesting data connection to APN '%s'", __func__, apn);

    if (ifc_init()) {
        ALOGE("%s() Failed to set up ifc!", __func__);
        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
        return;
    }

    if (ifc_down(ril_iface)) {
        ALOGE("%s() Failed to bring down %s!", __func__, ril_iface);
        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
        return;
    }

    err = at_send_command("AT+CGDCONT=%d,\"IP\",\"%s\"", RIL_CID_IP, apn);
    if (err != AT_NOERROR) {
        cme_err = at_get_cme_error(err);
        ALOGE("%s() CGDCONT failed: %d, cme: %d", __func__, err, cme_err);
        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
        return;
    }

    if (networkAuth(auth, user, pass, RIL_CID_IP)) {
        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
        return;
    }

    /* Start data on PDP context for IP */
    err = at_send_command("AT*ENAP=1,%d", RIL_CID_IP);
    if (err != AT_NOERROR) {
        cme_err = at_get_cme_error(err);
        ALOGE("requestSetupDefaultPDP: ENAP failed: %d  cme: %d", err, cme_err);
        goto error;
    }

    for (i = 0; i < MBM_ENAP_CONNECT_TIME * 5; i++) {
        e2napState = getE2napState();
        if (e2napState == E2NAP_STATE_CONNECTED
                || e2napState == E2NAP_STATE_DISCONNECTED
                || RADIO_STATE_UNAVAILABLE == getRadioState()) {
            ALOGD("%s() %s", __func__, e2napStateToString(e2napState));
            break;
        }
        usleep(200 * 1000);
    }

    e2napState = getE2napState();

    if (e2napState != E2NAP_STATE_CONNECTED)
        goto error;

    if (parse_ip_information(&addresses, &gateways, &dnses, &addr, &gateway) < 0) {
        ALOGE("%s() Failed to parse network interface data", __func__);
        goto error;
    }

    response.addresses = addresses;
    response.gateways = gateways;
    response.dnses = dnses;
    ALOGI("%s() Setting up interface %s,%s,%s",
        __func__, response.addresses, response.gateways, response.dnses);

    e2napState = getE2napState();

    if (e2napState == E2NAP_STATE_DISCONNECTED)
        goto error; /* we got disconnected */

    /* Don't use android netutils. We use our own and get the routing correct.
     * Carl Nordbeck */
    if (ifc_configure(ril_iface, addr, gateway))
        ALOGE("%s() Failed to configure the interface %s", __func__, ril_iface);

    ALOGI("IP Address %s, %s", addresses, e2napStateToString(e2napState));

    e2napState = getE2napState();

    if (e2napState == E2NAP_STATE_DISCONNECTED)
        goto error; /* we got disconnected */

    response.active = 2;
    response.status = 0;
    s_ActiveCID = response.cid;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));

    free(addresses);
    free(gateways);
    free(dnses);

    startPollFastDormancy();

    return;

error:

    mbm_check_error_cause();
    response.status = s_lastPdpFailCause;

    /* Restore enap state and wait for enap to report disconnected*/
    disconnect();

    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));

    free(addresses);
    free(gateways);
    free(dnses);
}