static void ril_call_barring_query_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; struct parcel rilp; struct ofono_error error; ofono_call_barring_query_cb_t cb = cbd->cb; int bearer_class = 0; if (message->error != RIL_E_SUCCESS) { ofono_error("Call Barring query failed, err: %i", message->error); decode_ril_error(&error, "FAIL"); goto out; } ril_util_init_parcel(message, &rilp); /* * Services for which the specified barring facility is active. * "0" means "disabled for all, -1 if unknown" */ parcel_r_int32(&rilp); /* count - we know there is only 1 */ bearer_class = parcel_r_int32(&rilp); DBG("Active services: %i", bearer_class); decode_ril_error(&error, "OK"); out: cb(&error, bearer_class, cbd->data); }
static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_sim_lock_unlock_cb_t cb = cbd->cb; struct sim_data *sd = cbd->user; struct parcel rilp; int retry_count; int retries[OFONO_SIM_PASSWORD_INVALID]; int passwd_type; /* There is no reason to ask SIM status until * unsolicited sim status change indication * Looks like state does not change before that. */ passwd_type = sd->passwd_type; ril_util_init_parcel(message, &rilp); parcel_r_int32(&rilp); retry_count = parcel_r_int32(&rilp); retries[passwd_type] = retry_count; sd->retries[passwd_type] = retries[passwd_type]; DBG("result=%d passwd_type=%d retry_count=%d", message->error, passwd_type, retry_count); if (message->error == RIL_E_SUCCESS) { CALLBACK_WITH_SUCCESS(cb, cbd->data); g_ril_print_response_no_args(sd->ril, message); } else { if (current_passwd) g_stpcpy(current_passwd, defaultpasswd); CALLBACK_WITH_FAILURE(cb, cbd->data); } }
static void ril_imsi_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_sim_imsi_cb_t cb = cbd->cb; struct sim_data *sd = cbd->user; struct ofono_error error; struct parcel rilp; gchar *imsi; if (message->error == RIL_E_SUCCESS) { DBG("GET IMSI reply - OK"); decode_ril_error(&error, "OK"); } else { ofono_error("Reply failure: %s", ril_error_to_string(message->error)); decode_ril_error(&error, "FAIL"); cb(&error, NULL, cbd->data); return; } ril_util_init_parcel(message, &rilp); /* 15 is the max length of IMSI * add 4 bytes for string length */ /* FIXME: g_assert(message->buf_len <= 19); */ imsi = parcel_r_string(&rilp); g_ril_append_print_buf(sd->ril, "{%s}", imsi); g_ril_print_response(sd->ril, message); cb(&error, imsi, cbd->data); g_free(imsi); }
static void ril_cops_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_netreg_operator_cb_t cb = cbd->cb; struct netreg_data *nd = cbd->user; struct ofono_error error; struct parcel rilp; struct ofono_network_operator op; gchar *lalpha, *salpha, *numeric; if (message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { ofono_error("Failed to retrive the current operator"); goto error; } ril_util_init_parcel(message, &rilp); /* Size of char ** */ if (parcel_r_int32(&rilp) == 0) goto error; lalpha = parcel_r_string(&rilp); salpha = parcel_r_string(&rilp); numeric = parcel_r_string(&rilp); /* Try to use long by default */ if (lalpha) strncpy(op.name, lalpha, OFONO_MAX_OPERATOR_NAME_LENGTH); else if (salpha) strncpy(op.name, salpha, OFONO_MAX_OPERATOR_NAME_LENGTH); else goto error; extract_mcc_mnc(numeric, op.mcc, op.mnc); /* Set to current */ op.status = OPERATOR_STATUS_CURRENT; op.tech = nd->tech; g_ril_append_print_buf(nd->ril, "(lalpha=%s, salpha=%s, numeric=%s, %s, mcc=%s, mnc=%s, %s)", lalpha, salpha, numeric, op.name, op.mcc, op.mnc, registration_tech_to_string(op.tech)); g_ril_print_response(nd->ril, message); g_free(lalpha); g_free(salpha); g_free(numeric); cb(&error, &op, cbd->data); return; error: CALLBACK_WITH_FAILURE(cb, NULL, cbd->data); }
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data) { DBG(""); struct cb_data *cbd = user_data; ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb; struct parcel rilp, rilp_out; int mode = OFONO_RADIO_ACCESS_MODE_ANY; int pref; struct radio_data *rd = NULL; if (message->error == RIL_E_SUCCESS) { ril_util_init_parcel(message, &rilp); /*first item in int[] is len so let's skip that*/ parcel_r_int32(&rilp); pref = parcel_r_int32(&rilp); switch (pref) { case PREF_NET_TYPE_LTE_ONLY: mode = OFONO_RADIO_ACCESS_MODE_LTE; case PREF_NET_TYPE_GSM_ONLY: mode = OFONO_RADIO_ACCESS_MODE_GSM; break; case PREF_NET_TYPE_WCDMA: case PREF_NET_TYPE_GSM_WCDMA: /* according to UI design */ case PREF_NET_TYPE_GSM_WCDMA_AUTO:/* according to UI design */ mode = OFONO_RADIO_ACCESS_MODE_UMTS; break; case PREF_NET_TYPE_LTE_CDMA_EVDO: case PREF_NET_TYPE_LTE_GSM_WCDMA: case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA: if (!cb) { rd = cbd->user; parcel_init(&rilp_out); parcel_w_int32(&rilp_out, 1); parcel_w_int32(&rilp_out, rd->ratmode); g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, rilp_out.data, rilp_out.size, NULL, NULL, g_free); parcel_free(&rilp_out); } break; case PREF_NET_TYPE_CDMA_EVDO_AUTO: case PREF_NET_TYPE_CDMA_ONLY: case PREF_NET_TYPE_EVDO_ONLY: case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO: default: break; } if (cb) CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); } else { if (cb) CALLBACK_WITH_FAILURE(cb, -1, cbd->data); } }
static void ril_query_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_call_forwarding_query_cb_t cb = cbd->cb; struct ofono_call_forwarding_condition *list = NULL; struct parcel rilp; int nmbr_of_resps = 0; int i; if (message->error == RIL_E_SUCCESS) { ril_util_init_parcel(message, &rilp); nmbr_of_resps = parcel_r_int32(&rilp); list = g_new0( struct ofono_call_forwarding_condition, nmbr_of_resps); for (i = 0; i < nmbr_of_resps; i++) { const char *str; list[i].status = parcel_r_int32(&rilp); parcel_r_int32(&rilp); list[i].cls = parcel_r_int32(&rilp); list[i].phone_number.type = parcel_r_int32(&rilp); str = parcel_r_string(&rilp); if (str) { strncpy(list[i].phone_number.number, str, OFONO_MAX_PHONE_NUMBER_LENGTH); list[i].phone_number.number[ OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0'; list[i].time = parcel_r_int32(&rilp); } } CALLBACK_WITH_SUCCESS(cb, 1, list, cbd->data); g_free(list); } else
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data) { DBG(""); struct cb_data *cbd = user_data; ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb; struct parcel rilp; int mode = OFONO_RADIO_ACCESS_MODE_ANY; int pref; if (message->error == RIL_E_SUCCESS) { ril_util_init_parcel(message, &rilp); /* first item in int[] is len so let's skip that */ parcel_r_int32(&rilp); pref = parcel_r_int32(&rilp); switch (pref) { case PREF_NET_TYPE_LTE_ONLY: mode = OFONO_RADIO_ACCESS_MODE_LTE; case PREF_NET_TYPE_GSM_ONLY: mode = OFONO_RADIO_ACCESS_MODE_GSM; break; case PREF_NET_TYPE_GSM_WCDMA_AUTO:/* according to UI design */ if (!cb) ril_force_rat_mode(cbd->user, pref); case PREF_NET_TYPE_WCDMA: case PREF_NET_TYPE_GSM_WCDMA: /* according to UI design */ mode = OFONO_RADIO_ACCESS_MODE_UMTS; break; case PREF_NET_TYPE_LTE_CDMA_EVDO: case PREF_NET_TYPE_LTE_GSM_WCDMA: case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA: if (!cb) ril_force_rat_mode(cbd->user, pref); break; case PREF_NET_TYPE_CDMA_EVDO_AUTO: case PREF_NET_TYPE_CDMA_ONLY: case PREF_NET_TYPE_EVDO_ONLY: case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO: default: break; } ofono_info("rat mode %d (ril %d)", mode, pref); if (cb) CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); } else { if (cb) CALLBACK_WITH_FAILURE(cb, -1, cbd->data); ofono_error("rat mode query failed"); } }
static void ril_nitz_notify(struct ril_msg *message, gpointer user_data) { struct ofono_netreg *netreg = user_data; struct netreg_data *nd = ofono_netreg_get_data(netreg); struct parcel rilp; int year, mon, mday, hour, min, sec, dst, tzi; char tzs, tz[4]; gchar *nitz; if (message->req != RIL_UNSOL_NITZ_TIME_RECEIVED) goto error; ril_util_init_parcel(message, &rilp); nitz = parcel_r_string(&rilp); g_ril_append_print_buf(nd->ril, "(%s)", nitz); g_ril_print_unsol(nd->ril, message); sscanf(nitz, "%u/%u/%u,%u:%u:%u%c%u,%u", &year, &mon, &mday, &hour, &min, &sec, &tzs, &tzi, &dst); sprintf(tz, "%c%d", tzs, tzi); nd->time.utcoff = atoi(tz) * 15 * 60; nd->time.dst = dst; nd->time.sec = sec; nd->time.min = min; nd->time.hour = hour; nd->time.mday = mday; nd->time.mon = mon; nd->time.year = 2000 + year; ofono_netreg_time_notify(netreg, &nd->time); g_free(nitz); return; error: ofono_error("Unable to notify ofono about nitz"); }
static void lastcause_cb(struct ril_msg *message, gpointer user_data) { struct lastcause_req *reqdata = user_data; struct ofono_voicecall *vc = reqdata->vc; int id = reqdata->id; enum ofono_disconnect_reason reason = OFONO_DISCONNECT_REASON_ERROR; int last_cause = CALL_FAIL_ERROR_UNSPECIFIED; struct parcel rilp; ril_util_init_parcel(message, &rilp); if (parcel_r_int32(&rilp) > 0) last_cause = parcel_r_int32(&rilp); DBG("Call %d ended with RIL cause %d", id, last_cause); if (last_cause == CALL_FAIL_NORMAL || last_cause == CALL_FAIL_BUSY) { reason = OFONO_DISCONNECT_REASON_REMOTE_HANGUP; } ofono_voicecall_disconnected(vc, id, reason, NULL); }
static void ril_csca_query_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_sms_sca_query_cb_t cb = cbd->cb; struct ofono_error error; struct ofono_phone_number sca; struct parcel rilp; gchar *number, *temp_buf; if (message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { decode_ril_error(&error, "FAIL"); cb(&error, NULL, cbd->data); return; } ril_util_init_parcel(message, &rilp); temp_buf = parcel_r_string(&rilp); if (temp_buf != NULL) { /* RIL gives address in quotes */ number = strtok(temp_buf, "\""); if (number[0] == '+') { number = number + 1; sca.type = 145; } else { sca.type = 129; } strncpy(sca.number, number, OFONO_MAX_PHONE_NUMBER_LENGTH); sca.number[OFONO_MAX_PHONE_NUMBER_LENGTH] = '\0'; DBG("csca_query_cb: %s, %d", sca.number, sca.type); cb(&error, &sca, cbd->data); } else { CALLBACK_WITH_FAILURE(cb, NULL, cbd->data); } }
static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb; struct parcel rilp; int mode = OFONO_RADIO_BAND_GSM_ANY; int pref; if (message->error == RIL_E_SUCCESS) { ril_util_init_parcel(message, &rilp); pref = parcel_r_int32(&rilp); switch (pref) { case PREF_NET_TYPE_LTE_ONLY: mode = OFONO_RADIO_ACCESS_MODE_LTE; case PREF_NET_TYPE_GSM_ONLY: mode = OFONO_RADIO_ACCESS_MODE_GSM; break; case PREF_NET_TYPE_WCDMA: mode = OFONO_RADIO_ACCESS_MODE_UMTS; break; case PREF_NET_TYPE_GSM_WCDMA: case PREF_NET_TYPE_GSM_WCDMA_AUTO: case PREF_NET_TYPE_CDMA_EVDO_AUTO: case PREF_NET_TYPE_CDMA_ONLY: case PREF_NET_TYPE_EVDO_ONLY: case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO: case PREF_NET_TYPE_LTE_CDMA_EVDO: case PREF_NET_TYPE_LTE_GSM_WCDMA: case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA: default: break; } CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); } else { CALLBACK_WITH_FAILURE(cb, -1, cbd->data); } }
static void ril_stk_pcmd_notify(struct ril_msg *message, gpointer user_data) { struct ofono_stk *stk = user_data; struct parcel rilp; char *pcmd = NULL; guchar *pdu = NULL; long len; DBG(""); ril_util_init_parcel(message, &rilp); pcmd = parcel_r_string(&rilp); DBG("pcmd: %s", pcmd); pdu = decode_hex((const char *) pcmd, strlen(pcmd), &len, -1); g_free(pcmd); ofono_stk_proactive_command_notify(stk, len, (const guchar *)pdu); g_free(pdu); }
static void ril_connected(struct ril_msg *message, gpointer user_data) { DBG(""); struct ofono_modem *modem = (struct ofono_modem *) user_data; struct ril_data *ril = ofono_modem_get_data(modem); int ril_version = 0; struct parcel rilp; ril_util_init_parcel(message, &rilp); ril_version = parcel_r_int32(&rilp); ofono_debug("%s: [UNSOL]< %s, RIL_VERSION %d", __func__, ril_unsol_request_to_string(message->req), ril_version); ril->connected = TRUE; send_get_sim_status(modem); connection = ofono_dbus_get_connection(); mce_daemon_watch = g_dbus_add_service_watch(connection, MCE_SERVICE, mce_connect, mce_disconnect, modem, NULL); }
static void ril_ussd_notify(struct ril_msg *message, gpointer user_data) { struct ofono_ussd *ussd = user_data; struct parcel rilp; gchar *ussd_from_network; gchar *type; gint ussdtype; ril_util_init_parcel(message, &rilp); parcel_r_int32(&rilp); type = parcel_r_string(&rilp); ussdtype = g_ascii_xdigit_value(*type); ussd_from_network = parcel_r_string(&rilp); if (ussd_from_network) ofono_ussd_notify(ussd, ussdtype, 0xFF, (const unsigned char *)ussd_from_network, strlen(ussd_from_network)); else ofono_ussd_notify(ussd, ussdtype, 0, NULL, 0); return; }
static void ril_cbs_notify(struct ril_msg *message, gpointer user_data) { struct ofono_cbs *cbs = user_data; /* * Ofono does not support UMTS CB - see * src/smsutil.c method cbs_decode. * But let's let the core to make * the rejection reserve memory here * for maximum UMTS CB length */ unsigned char pdu[1252]; char *resp; struct parcel rilp; ril_util_init_parcel(message, &rilp); resp = parcel_r_string(&rilp); memcpy(resp, pdu, strlen((char *)resp)); ofono_cbs_notify(cbs, pdu, strlen((char *)resp)); }
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; DBG("req: %d; data_len: %d", message->req, message->buf_len); switch (message->req) { case RIL_UNSOL_RESPONSE_NEW_SMS: case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: break; default: 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); if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS) { /* Last parameter is 'tpdu_len' ( substract SMSC length ) */ ofono_sms_deliver_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } else if (message->req == RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT) { ofono_sms_status_notify(sms, ril_data, ril_buf_len, ril_buf_len - smsc_len); } ril_ack_delivery(sms); return; error: ofono_error("Unable to parse NEW_SMS notification"); }
static void ril_cops_list_cb(struct ril_msg *message, gpointer user_data) { struct cb_data *cbd = user_data; ofono_netreg_operator_list_cb_t cb = cbd->cb; struct netreg_data *nd = cbd->user; struct ofono_network_operator *list; struct ofono_error error; struct parcel rilp; int noperators, i; gchar *lalpha, *salpha, *numeric, *status; if (message->error == RIL_E_SUCCESS) { decode_ril_error(&error, "OK"); } else { ofono_error("Failed to retrive the list of operators"); goto error; } ril_util_init_parcel(message, &rilp); g_ril_append_print_buf(nd->ril, "{"); /* Number of operators at the list (4 strings for every operator) */ noperators = parcel_r_int32(&rilp) / 4; DBG("noperators = %d", noperators); list = g_try_new0(struct ofono_network_operator, noperators); if (list == NULL) goto error; for (i = 0; i < noperators; i++) { lalpha = parcel_r_string(&rilp); salpha = parcel_r_string(&rilp); numeric = parcel_r_string(&rilp); status = parcel_r_string(&rilp); /* Try to use long by default */ if (lalpha) { strncpy(list[i].name, lalpha, OFONO_MAX_OPERATOR_NAME_LENGTH); } else { strncpy(list[i].name, salpha, OFONO_MAX_OPERATOR_NAME_LENGTH); } extract_mcc_mnc(numeric, list[i].mcc, list[i].mnc); /* FIXME: need to fix this for CDMA */ /* Use GSM as default, as RIL doesn't pass that info to us */ list[i].tech = ACCESS_TECHNOLOGY_GSM; /* Set the proper status */ if (!strcmp(status, "unknown")) list[i].status = OPERATOR_STATUS_UNKNOWN; else if (!strcmp(status, "available")) list[i].status = OPERATOR_STATUS_AVAILABLE; else if (!strcmp(status, "current")) list[i].status = OPERATOR_STATUS_CURRENT; else if (!strcmp(status, "forbidden")) list[i].status = OPERATOR_STATUS_FORBIDDEN; g_ril_append_print_buf(nd->ril, "%s [operator=%s, %s, %s, status: %s]", print_buf, list[i].name, list[i].mcc, list[i].mnc, status); g_free(lalpha); g_free(salpha); g_free(numeric); g_free(status); } g_ril_append_print_buf(nd->ril, "%s}", print_buf); g_ril_print_response(nd->ril, message); cb(&error, noperators, list, cbd->data); return; error: CALLBACK_WITH_FAILURE(cb, 0, NULL, cbd->data); }
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"); }