static void ril_ack_delivery(struct ofono_sms *sms) { struct sms_data *sd = ofono_sms_get_data(sms); struct parcel rilp; int ret; int request = RIL_REQUEST_SMS_ACKNOWLEDGE; 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 */ ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_ack_delivery_cb, NULL, NULL); g_ril_append_print_buf(sd->ril, "(1,0)"); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); }
static int ril_disable(struct ofono_modem *modem) { DBG("%p", modem); struct ril_data *ril = ofono_modem_get_data(modem); struct parcel rilp; int request = RIL_REQUEST_RADIO_POWER; guint ret; parcel_init(&rilp); parcel_w_int32(&rilp, 1); /* size of array */ parcel_w_int32(&rilp, 0); /* POWER=OFF */ ofono_info("%s: RIL_REQUEST_RADIO_POWER OFF", __func__); /* 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); /* this will trigger the cleanup of g_io_channel */ g_ril_unref(ril->modem); ril->modem = NULL; return 0; }
static void ril_register_manual(struct ofono_netreg *netreg, const char *mcc, const char *mnc, ofono_netreg_register_cb_t cb, void *data) { struct netreg_data *nd = ofono_netreg_get_data(netreg); struct cb_data *cbd = cb_data_new(cb, data); char buf[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1]; struct parcel rilp; int request = RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL; int ret; /* add *netreg_data to callback */ cbd->user = nd; parcel_init(&rilp); /* RIL expects a char * specifying MCCMNC of network to select */ snprintf(buf, sizeof(buf), "%s%s", mcc, mnc); parcel_w_string(&rilp, buf); ret = g_ril_send(nd->ril, request, rilp.data, rilp.size, ril_register_cb, cbd, g_free); parcel_free(&rilp); g_ril_append_print_buf(nd->ril, "(%s)", buf); g_ril_print_request(nd->ril, ret, request); /* In case of error free cbd and return the cb with failure */ if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, data); } }
static void ril_pin_send(struct ofono_sim *sim, 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_PIN; int ret; sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PIN; cbd->user = sd; if (current_passwd) g_stpcpy(current_passwd, passwd); parcel_init(&rilp); parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS); 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, "(%s,aid=%s)", 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 void ril_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_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_GET_IMSI; guint ret; cbd->user = sd; parcel_init(&rilp); parcel_w_int32(&rilp, GET_IMSI_NUM_PARAMS); parcel_w_string(&rilp, sd->aid_str); ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, ril_imsi_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "(%s)", sd->aid_str); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, NULL, data); } }
static void ril_cmgs(struct ofono_sms *sms, const unsigned char *pdu, int pdu_len, int tpdu_len, int mms, ofono_sms_submit_cb_t cb, void *user_data) { struct sms_data *sd = ofono_sms_get_data(sms); struct cb_data *cbd = cb_data_new(cb, user_data); struct parcel rilp; char *tpdu; int request = RIL_REQUEST_SEND_SMS; int ret, smsc_len; cbd->user = sd; DBG("pdu_len: %d, tpdu_len: %d mms: %d", pdu_len, tpdu_len, mms); /* TODO: if (mms) { ... } */ parcel_init(&rilp); parcel_w_int32(&rilp, 2); /* Number of strings */ /* SMSC address: * * smsc_len == 1, then zero-length SMSC was spec'd * RILD expects a NULL string in this case instead * of a zero-length string. */ smsc_len = pdu_len - tpdu_len; if (smsc_len > 1) { /* TODO: encode SMSC & write to parcel */ DBG("SMSC address specified (smsc_len %d); NOT-IMPLEMENTED", smsc_len); } parcel_w_string(&rilp, NULL); /* SMSC address; NULL == default */ /* TPDU: * * 'pdu' is a raw hexadecimal string * encode_hex() turns it into an ASCII/hex UTF8 buffer * parcel_w_string() encodes utf8 -> utf16 */ tpdu = encode_hex(pdu + smsc_len, tpdu_len, 0); parcel_w_string(&rilp, tpdu); ret = g_ril_send(sd->ril, request, rilp.data, rilp.size, submit_sms_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "(%s)", tpdu); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, -1, user_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_sim_read_record(struct ofono_sim *sim, int fileid, int record, int length, const unsigned char *path, unsigned int path_len, ofono_sim_read_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_READ_RECORD); 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, record); /* P1 */ parcel_w_int32(&rilp, 4); /* P2 */ parcel_w_int32(&rilp, length); /* P3 */ 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_io_cb, cbd, g_free); g_ril_append_print_buf(sd->ril, "%s%d,%d,%d,(null),pin2=(null),aid=%s)", print_buf, record, 4, length, sd->aid_str); g_ril_print_request(sd->ril, ret, request); parcel_free(&rilp); if (ret <= 0) { g_free(cbd); CALLBACK_WITH_FAILURE(cb, NULL, 0, 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 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_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 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); } }