static void ril_set_rat_mode(struct ofono_radio_settings *rs, enum ofono_radio_access_mode mode, ofono_radio_settings_rat_mode_set_cb_t cb, void *data) { struct radio_data *rd = ofono_radio_settings_get_data(rs); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int pref = rd->ratmode; int ret = 0; ofono_info("setting rat mode:%d", mode); parcel_init(&rilp); parcel_w_int32(&rilp, 1); /* Number of params */ switch (mode) { case OFONO_RADIO_ACCESS_MODE_GSM: pref = PREF_NET_TYPE_GSM_ONLY; break; case OFONO_RADIO_ACCESS_MODE_UMTS: pref = PREF_NET_TYPE_GSM_WCDMA_AUTO; /* according to UI design */ break; case OFONO_RADIO_ACCESS_MODE_LTE: pref = PREF_NET_TYPE_LTE_ONLY; default: break; } parcel_w_int32(&rilp, pref); ret = g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, rilp.data, rilp.size, ril_set_rat_cb, cbd, g_free); parcel_free(&rilp); if (ret <= 0) { ofono_error("unable to set rat mode"); g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static void ril_change_passwd(struct ofono_sim *sim, enum ofono_sim_password_type passwd_type, const char *old_passwd, const char *new_passwd, ofono_sim_lock_unlock_cb_t cb, void *data) { struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int request = RIL_REQUEST_CHANGE_SIM_PIN; int ret = 0; sd->passwd_type = passwd_type; cbd->user = sd; parcel_init(&rilp); parcel_w_int32(&rilp, CHANGE_SIM_PIN_PARAMS); parcel_w_string(&rilp, (char *) old_passwd); parcel_w_string(&rilp, (char *) new_passwd); parcel_w_string(&rilp, sd->aid_str); if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2) request = RIL_REQUEST_CHANGE_SIM_PIN2; else if (current_passwd) g_stpcpy(current_passwd, new_passwd); ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_pin_change_state_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "(old=%s,new=%s,aid=%s)", old_passwd, new_passwd, sd->aid_str); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static int ril_perso_change_state(struct ofono_sim *sim, enum ofono_sim_password_type passwd_type, int enable, const char *passwd, ofono_sim_lock_unlock_cb_t cb, void *data) { struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int request = 0; int ret = 0; sd->passwd_type = passwd_type; cbd->user = sd; parcel_init(&rilp); switch (passwd_type) { case OFONO_SIM_PASSWORD_PHNET_PIN: if (enable) { DBG("Not supported, enable=%d", enable); goto end; } request = RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION; parcel_w_int32(&rilp, RIL_PERSOSUBSTATE_SIM_NETWORK); parcel_w_string(&rilp, (char *) passwd); break; default: DBG("Not supported, type=%d", passwd_type); goto end; } ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_pin_change_state_cb, cbd, g_free); g_ril_print_request(sd->ril, ret, request); end: parcel_free(&rilp); return ret; }
static void ril_pin_send_puk(struct ofono_sim *sim, const char *puk, const char *passwd, ofono_sim_lock_unlock_cb_t cb, void *data) { struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int request = RIL_REQUEST_ENTER_SIM_PUK; int ret = 0; sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PUK; cbd->user = sd; if (current_passwd) g_stpcpy(current_passwd, passwd); parcel_init(&rilp); parcel_w_int32(&rilp, ENTER_SIM_PUK_PARAMS); parcel_w_string(&rilp, (char *) puk); parcel_w_string(&rilp, (char *) passwd); parcel_w_string(&rilp, sd->aid_str); ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_pin_change_state_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "(puk=%s,pin=%s,aid=%s)", puk, passwd, sd->aid_str); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static int ril_screen_state(struct ofono_modem *modem, ofono_bool_t state) { struct ril_data *ril = ofono_modem_get_data(modem); struct parcel rilp; int request = RIL_REQUEST_SCREEN_STATE; guint ret; parcel_init(&rilp); parcel_w_int32(&rilp, 1); /* size of array */ parcel_w_int32(&rilp, state); /* screen on/off */ /* fire and forget i.e. not waiting for the callback*/ ret = g_ril_send(ril->modem, request, rilp.data, rilp.size, NULL, NULL, NULL); g_ril_append_print_buf(ril->modem, "(0)"); g_ril_print_request(ril->modem, ret, request); parcel_free(&rilp); return 0; }
static void ril_sms_notify(struct ril_msg *message, gpointer user_data) { struct ofono_sms *sms = user_data; struct sms_data *sd = ofono_sms_get_data(sms); struct parcel rilp; char *ril_pdu; int ril_pdu_len; unsigned int smsc_len; long ril_buf_len; guchar *ril_data; int request = RIL_REQUEST_SMS_ACKNOWLEDGE; int ret; DBG("req: %d; data_len: %d", message->req, (int) message->buf_len); if (message->req != RIL_UNSOL_RESPONSE_NEW_SMS) goto error; ril_util_init_parcel(message, &rilp); ril_pdu = parcel_r_string(&rilp); if (ril_pdu == NULL) goto error; ril_pdu_len = strlen(ril_pdu); DBG("ril_pdu_len is %d", ril_pdu_len); ril_data = decode_hex(ril_pdu, ril_pdu_len, &ril_buf_len, -1); if (ril_data == NULL) goto error; /* The first octect in the pdu contains the SMSC address length * which is the X following octects it reads. We add 1 octet to * the read length to take into account this read octet in order * to calculate the proper tpdu length. */ smsc_len = ril_data[0] + 1; DBG("smsc_len is %d", smsc_len); g_ril_append_print_buf(sd->ril, "(%s)", ril_pdu); g_ril_print_unsol(sd->ril, message); /* Last parameter is 'tpdu_len' ( substract SMSC length ) */ ofono_sms_deliver_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); /* Re-use rilp, so initilize */ parcel_init(&rilp); parcel_w_int32(&rilp, 2); /* Number of int32 values in array */ parcel_w_int32(&rilp, 1); /* Successful receipt */ parcel_w_int32(&rilp, 0); /* error code */ /* TODO: should ACK be sent for either of the error cases? */ /* ACK the incoming NEW_SMS; ignore response so no cb needed */ ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, NULL, NULL, NULL); g_ril_append_print_buf(sd->ril, "(1,0)"); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); return; error: ofono_error("Unable to parse NEW_SMS notification"); }
static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc, const struct ofono_gprs_primary_context *ctx, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = cb_data_new(cb, data); struct req_setup_data_call request; struct parcel rilp; struct ofono_error error; int reqid = RIL_REQUEST_SETUP_DATA_CALL; int ret = 0; ofono_info("Activating context: %d", ctx->cid); cbd->user = gc; /* TODO: implement radio technology selection. */ request.tech = RADIO_TECH_HSPA; /* TODO: add comments about tethering, other non-public * profiles... */ request.data_profile = RIL_DATA_PROFILE_DEFAULT; request.apn = g_strdup(ctx->apn); request.username = g_strdup(ctx->username); request.password = g_strdup(ctx->password); request.auth_type = RIL_AUTH_BOTH; request.protocol = ctx->proto; if (g_ril_request_setup_data_call(gcd->ril, &request, &rilp, &error) == FALSE) { ofono_error("Couldn't build SETUP_DATA_CALL request."); goto error; } gcd->active_ctx_cid = ctx->cid; gcd->state = STATE_ENABLING; ret = g_ril_send(gcd->ril, reqid, rilp.data, rilp.size, ril_setup_data_call_cb, cbd, g_free); /* NOTE - we could make the following function part of g_ril_send? */ g_ril_print_request(gcd->ril, ret, reqid); parcel_free(&rilp); error: g_free(request.apn); g_free(request.username); g_free(request.password); if (ret <= 0) { ofono_error("Send RIL_REQUEST_SETUP_DATA_CALL failed."); set_context_disconnected(gcd); g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc, unsigned int id, ofono_gprs_context_cb_t cb, void *data) { struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc); struct cb_data *cbd = NULL; struct parcel rilp; struct req_deactivate_data_call request; struct ofono_error error; int reqid = RIL_REQUEST_DEACTIVATE_DATA_CALL; int ret = 0; ofono_info("deactivate primary"); if (gcd->active_rild_cid == -1) { set_context_disconnected(gcd); if (cb) { CALLBACK_WITH_SUCCESS(cb, data); g_free(cbd); } return; } cbd = cb_data_new(cb, data); cbd->user = gc; gcd->state = STATE_DISABLING; request.cid = gcd->active_rild_cid; request.reason = RIL_DEACTIVATE_DATA_CALL_NO_REASON; if (g_ril_request_deactivate_data_call(gcd->ril, &request, &rilp, &error) == FALSE) { ofono_error("Couldn't build DEACTIVATE_DATA_CALL request."); goto error; } ret = g_ril_send(gcd->ril, reqid, rilp.data, rilp.size, ril_deactivate_data_call_cb, cbd, g_free); g_ril_append_print_buf(gcd->ril, "(%d,0)", request.cid); g_ril_print_request(gcd->ril, ret, reqid); parcel_free(&rilp); error: if (ret <= 0) { ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed."); g_free(cbd); if (cb) CALLBACK_WITH_FAILURE(cb, data); } }
static void ril_pin_change_state(struct ofono_sim *sim, enum ofono_sim_password_type passwd_type, int enable, const char *passwd, ofono_sim_lock_unlock_cb_t cb, void *data) { DBG("passwd_type=%d", passwd_type); struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int request = RIL_REQUEST_SET_FACILITY_LOCK; int ret = 0; sd->passwd_type = passwd_type; cbd->user = sd; parcel_init(&rilp); parcel_w_int32(&rilp, SET_FACILITY_LOCK_PARAMS); /* * TODO: clean up the use of string literals & * the multiple g_ril_append_print_buf() calls * by using a table lookup as does the core sim code */ switch (passwd_type) { case OFONO_SIM_PASSWORD_SIM_PIN: if (current_passwd) g_stpcpy(current_passwd, passwd); g_ril_append_print_buf(sd->ril, "(SC,"); parcel_w_string(&rilp, "SC"); break; case OFONO_SIM_PASSWORD_PHSIM_PIN: g_ril_append_print_buf(sd->ril, "(PS,"); parcel_w_string(&rilp, "PS"); break; case OFONO_SIM_PASSWORD_PHFSIM_PIN: g_ril_append_print_buf(sd->ril, "(PF,"); parcel_w_string(&rilp, "PF"); break; case OFONO_SIM_PASSWORD_SIM_PIN2: g_ril_append_print_buf(sd->ril, "(P2,"); parcel_w_string(&rilp, "P2"); break; case OFONO_SIM_PASSWORD_PHNET_PIN: ret = ril_perso_change_state(sim, passwd_type, enable, passwd, cb, data); goto end; case OFONO_SIM_PASSWORD_PHNETSUB_PIN: g_ril_append_print_buf(sd->ril, "(PU,"); parcel_w_string(&rilp, "PU"); break; case OFONO_SIM_PASSWORD_PHSP_PIN: g_ril_append_print_buf(sd->ril, "(PP,"); parcel_w_string(&rilp, "PP"); break; case OFONO_SIM_PASSWORD_PHCORP_PIN: g_ril_append_print_buf(sd->ril, "(PC,"); parcel_w_string(&rilp, "PC"); break; default: goto end; } if (enable) parcel_w_string(&rilp, RIL_FACILITY_LOCK); else parcel_w_string(&rilp, RIL_FACILITY_UNLOCK); parcel_w_string(&rilp, (char *) passwd); /* TODO: make this a constant... */ parcel_w_string(&rilp, "0"); /* class */ parcel_w_string(&rilp, sd->aid_str); ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_pin_change_state_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "%s,%d,%s,0,aid=%s)", print_buf, enable, passwd, sd->aid_str); g_ril_print_request(sd->ril, ret, request); end: parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static void sim_status_cb(struct ril_msg *message, gpointer user_data) { struct ofono_sim *sim = user_data; struct sim_data *sd = ofono_sim_get_data(sim); struct sim_app *apps[MAX_UICC_APPS]; struct sim_status status; guint i = 0; guint search_index = -1; struct parcel rilp; DBG(""); if (ril_util_parse_sim_status(sd->ril, message, &status, apps) && status.num_apps) { DBG("num_apps: %d gsm_umts_index: %d", status.num_apps, status.gsm_umts_index); /* TODO(CDMA): need some kind of logic to * set the correct app_index, */ search_index = status.gsm_umts_index; for (i = 0; i < status.num_apps; i++) { if (i == search_index && apps[i]->app_type != RIL_APPTYPE_UNKNOWN) { current_active_app = apps[i]->app_type; configure_active_app(sd, apps[i], i); set_pin_lock_state(sim, apps[i]); break; } } if (sd->sim_registered == FALSE) { ofono_sim_register(sim); sd->sim_registered = TRUE; } else { /* TODO: There doesn't seem to be any other * way to force the core SIM code to * recheck the PIN. * Wouldn't __ofono_sim_refresh be * more appropriate call here?? * __ofono_sim_refresh(sim, NULL, TRUE, TRUE); */ DBG("sd->card_state:%u", sd->card_state); if (sd->card_state != RIL_CARDSTATE_PRESENT) { ofono_sim_inserted_notify(sim, TRUE); sd->card_state = RIL_CARDSTATE_PRESENT; sd->removed = FALSE; } } if (current_passwd) { if (!strcmp(current_passwd, defaultpasswd)) { __ofono_sim_recheck_pin(sim); } else if (sd->passwd_state != OFONO_SIM_PASSWORD_SIM_PIN) { __ofono_sim_recheck_pin(sim); } else if (sd->passwd_state == OFONO_SIM_PASSWORD_SIM_PIN) { parcel_init(&rilp); parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS); parcel_w_string(&rilp, current_passwd); parcel_w_string(&rilp, sd->aid_str); g_ril_send(sd->ril, RIL_REQUEST_ENTER_SIM_PIN, rilp.data, rilp.size, NULL, NULL, g_free); parcel_free(&rilp); } } else { __ofono_sim_recheck_pin(sim); } if (current_online_state == RIL_ONLINE_PREF) { parcel_init(&rilp); parcel_w_int32(&rilp, 1); parcel_w_int32(&rilp, 1); ofono_info("RIL_REQUEST_RADIO_POWER ON"); g_ril_send(sd->ril, RIL_REQUEST_RADIO_POWER, rilp.data, rilp.size, NULL, NULL, g_free); parcel_free(&rilp); current_online_state = RIL_ONLINE; } ril_util_free_sim_apps(apps, status.num_apps); } else { if (current_online_state == RIL_ONLINE) current_online_state = RIL_ONLINE_PREF; if (status.card_state == RIL_CARDSTATE_ABSENT) { DBG("sd->card_state:%u,status.card_state:%u,", sd->card_state, status.card_state); ofono_info("RIL_CARDSTATE_ABSENT"); ofono_sim_inserted_notify(sim, FALSE); if (sd->card_state == RIL_CARDSTATE_PRESENT) sd->removed = TRUE; sd->card_state = RIL_CARDSTATE_ABSENT; if (current_passwd) g_stpcpy(current_passwd, defaultpasswd); sd->initialized = FALSE; } } /* TODO: if no SIM present, handle emergency calling. */ }
static void ril_sim_read_info(struct ofono_sim *sim, int fileid, const unsigned char *path, unsigned int path_len, ofono_sim_file_info_cb_t cb, void *data) { struct sim_data *sd = ofono_sim_get_data(sim); struct cb_data *cbd = cb_data_new(cb, data); struct parcel rilp; int request = RIL_REQUEST_SIM_IO; guint ret; cbd->user = sd; parcel_init(&rilp); parcel_w_int32(&rilp, CMD_GET_RESPONSE); parcel_w_int32(&rilp, fileid); g_ril_append_print_buf(sd->ril, "(cmd=0x%.2X,efid=0x%.4X,", CMD_GET_RESPONSE, fileid); set_path(sd, &rilp, fileid, path, path_len); parcel_w_int32(&rilp, 0); /* P1 */ parcel_w_int32(&rilp, 0); /* P2 */ /* * TODO: review parameters values used by Android. * The values of P1-P3 in this code were based on * values used by the atmodem driver impl. * * NOTE: * GET_RESPONSE_EF_SIZE_BYTES == 15; !255 */ parcel_w_int32(&rilp, 15); /* P3 - max length */ parcel_w_string(&rilp, NULL); /* data; only req'd for writes */ parcel_w_string(&rilp, NULL); /* pin2; only req'd for writes */ parcel_w_string(&rilp, sd->aid_str); /* AID (Application ID) */ ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_file_info_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "%s0,0,15,(null),pin2=(null),aid=%s)", print_buf, sd->aid_str); g_ril_print_request(sd->ril, ret, RIL_REQUEST_SIM_IO); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, data); } }