/* * Indicate oFono that a SMS driver is ready for operation * * This is called after ofono_sms_create() was done and the modem * driver determined that a modem supports SMS correctly. Once this * call succeeds, the D-BUS interface for SMS goes live. */ void ofono_sms_register(struct ofono_sms *sms) { DBusConnection *conn = ofono_dbus_get_connection(); struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom); const char *path = __ofono_atom_get_path(sms->atom); struct ofono_sim *sim; if (!g_dbus_register_interface(conn, path, OFONO_MESSAGE_MANAGER_INTERFACE, sms_manager_methods, sms_manager_signals, NULL, sms, NULL)) { ofono_error("Could not create %s interface", OFONO_MESSAGE_MANAGER_INTERFACE); return; } ofono_modem_add_interface(modem, OFONO_MESSAGE_MANAGER_INTERFACE); sms->mw_watch = __ofono_modem_add_atom_watch(modem, OFONO_ATOM_TYPE_MESSAGE_WAITING, mw_watch, sms, NULL); sms->netreg_watch = __ofono_modem_add_atom_watch(modem, OFONO_ATOM_TYPE_NETREG, netreg_watch, sms, NULL); sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem); /* * If we have a sim atom, we can uniquely identify the SIM, * otherwise create an sms assembly which doesn't backup the fragment * store. */ if (sim) { const char *imsi; imsi = ofono_sim_get_imsi(sim); sms->assembly = sms_assembly_new(imsi); sms->sr_assembly = status_report_assembly_new(imsi); sms_load_settings(sms, imsi); } else { sms->assembly = sms_assembly_new(NULL); sms->sr_assembly = status_report_assembly_new(NULL); sms->bearer = 3; /* Default to CS then PS */ } if (sms->driver->bearer_set) sms->driver->bearer_set(sms, sms->bearer, bearer_init_callback, sms); sms_restore_tx_queue(sms); sms->text_handlers = __ofono_watchlist_new(g_free); sms->datagram_handlers = __ofono_watchlist_new(g_free); __ofono_atom_register(sms->atom, sms_unregister); }
static void set_ia_apn(struct ofono_radio_settings *rs) { char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1]; struct radio_data *rd = ofono_radio_settings_get_data(rs); struct parcel rilp; struct ofono_gprs *gprs; const struct ofono_gprs_primary_context *ia_ctx; if ((rd->available_rats & OFONO_RADIO_ACCESS_MODE_LTE) == 0) return; gprs = __ofono_atom_find(OFONO_ATOM_TYPE_GPRS, rd->modem); if (gprs == NULL) return; /* Ask for APN data */ ia_ctx = ofono_gprs_get_ia_apn(gprs, mccmnc); if (ia_ctx == NULL) return; g_ril_request_set_initial_attach_apn(rd->ril, ia_ctx->apn, ia_ctx->proto, ia_ctx->username, ia_ctx->password, mccmnc, &rilp); if (g_ril_send(rd->ril, RIL_REQUEST_SET_INITIAL_ATTACH_APN, &rilp, set_ia_apn_cb, rs, NULL) == 0) ofono_error("%s: failure sending request", __func__); }
static DBusMessage *ussd_initiate(DBusConnection *conn, DBusMessage *msg, void *data) { struct ofono_ussd *ussd = data; struct ofono_modem *modem = __ofono_atom_get_modem(ussd->atom); struct ofono_voicecall *vc; gboolean call_in_progress; const char *str; int dcs = 0x0f; unsigned char buf[160]; long num_packed; if (__ofono_ussd_is_busy(ussd)) return __ofono_error_busy(msg); if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == FALSE) return __ofono_error_invalid_args(msg); if (strlen(str) == 0) return __ofono_error_invalid_format(msg); DBG("checking if this is a recognized control string"); if (recognized_control_string(ussd, str, msg)) return NULL; vc = __ofono_atom_find(OFONO_ATOM_TYPE_VOICECALL, modem); if (vc) call_in_progress = __ofono_voicecall_is_busy(vc, OFONO_VOICECALL_INTERACTION_NONE); else call_in_progress = FALSE; DBG("No.., checking if this is a USSD string"); if (!valid_ussd_string(str, call_in_progress)) return __ofono_error_not_recognized(msg); if (!ussd_encode(str, &num_packed, buf)) return __ofono_error_invalid_format(msg); if (ussd->driver->request == NULL) return __ofono_error_not_implemented(msg); DBG("OK, running USSD request"); ussd->pending = dbus_message_ref(msg); ussd->driver->request(ussd, dcs, buf, num_packed, ussd_callback, ussd); return NULL; }
void ofono_sms_deliver_notify(struct ofono_sms *sms, const unsigned char *pdu, int len, int tpdu_len) { struct ofono_modem *modem = __ofono_atom_get_modem(sms->atom); struct ofono_sim *sim; struct ofono_stk *stk; struct sms s; enum sms_class cls; DBG("len %d tpdu len %d", len, tpdu_len); if (!sms_decode(pdu, len, FALSE, tpdu_len, &s)) { ofono_error("Unable to decode PDU"); return; } if (s.type != SMS_TYPE_DELIVER) { ofono_error("Expecting a DELIVER pdu"); return; } if (s.deliver.pid == SMS_PID_TYPE_SM_TYPE_0) { DBG("Explicitly ignoring type 0 SMS"); return; } /* * This is an older style MWI notification, process MWI * headers and handle it like any other message */ if (s.deliver.pid == SMS_PID_TYPE_RETURN_CALL) { if (handle_mwi(sms, &s)) return; goto out; } /* * The DCS indicates this is an MWI notification, process it * and then handle the User-Data as any other message */ if (sms_mwi_dcs_decode(s.deliver.dcs, NULL, NULL, NULL, NULL)) { if (handle_mwi(sms, &s)) return; goto out; } if (!sms_dcs_decode(s.deliver.dcs, &cls, NULL, NULL, NULL)) { ofono_error("Unknown / Reserved DCS. Ignoring"); return; } switch (s.deliver.pid) { case SMS_PID_TYPE_ME_DOWNLOAD: if (cls == SMS_CLASS_1) { ofono_error("ME Download message ignored"); return; } break; case SMS_PID_TYPE_ME_DEPERSONALIZATION: if (s.deliver.dcs == 0x11) { ofono_error("ME Depersonalization message ignored"); return; } break; case SMS_PID_TYPE_USIM_DOWNLOAD: case SMS_PID_TYPE_ANSI136: /* If not Class 2, handle in a "normal" way */ if (cls != SMS_CLASS_2) break; sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem); if (sim == NULL) return; if (!__ofono_sim_service_available(sim, SIM_UST_SERVICE_DATA_DOWNLOAD_SMS_PP, SIM_SST_SERVICE_DATA_DOWNLOAD_SMS_PP)) return; stk = __ofono_atom_find(OFONO_ATOM_TYPE_STK, modem); if (stk == NULL) return; __ofono_sms_sim_download(stk, &s, NULL, sms); /* * Passing the USIM response back to network is not * currently supported * * TODO: store in EFsms if not handled */ return; default: break; } /* * Check to see if the SMS has any other MWI related headers, * as sometimes they are "tacked on" by the SMSC. * While we're doing this we also check for messages containing * WCMP headers or headers that can't possibly be in a normal * message. If we find messages like that, we ignore them. */ if (s.deliver.udhi) { struct sms_udh_iter iter; enum sms_iei iei; if (!sms_udh_iter_init(&s, &iter)) goto out; while ((iei = sms_udh_iter_get_ie_type(&iter)) != SMS_IEI_INVALID) { if (iei > 0x25) { ofono_error("Reserved / Unknown / USAT" "header in use, ignore"); return; } switch (iei) { case SMS_IEI_SPECIAL_MESSAGE_INDICATION: case SMS_IEI_ENHANCED_VOICE_MAIL_INFORMATION: /* * TODO: ignore if not in the very first * segment of a concatenated SM so as not * to repeat the indication. */ if (handle_mwi(sms, &s)) return; goto out; case SMS_IEI_WCMP: ofono_error("No support for WCMP, ignoring"); return; default: sms_udh_iter_next(&iter); } } } out: handle_deliver(sms, &s); }
void __ofono_modem_append_properties(struct ofono_modem *modem, DBusMessageIter *dict) { char **interfaces; char **features; int i; GSList *l; struct ofono_devinfo *info; dbus_bool_t emergency = ofono_modem_get_emergency_mode(modem); const char *strtype; ofono_dbus_dict_append(dict, "Online", DBUS_TYPE_BOOLEAN, &modem->online); ofono_dbus_dict_append(dict, "Powered", DBUS_TYPE_BOOLEAN, &modem->powered); ofono_dbus_dict_append(dict, "Lockdown", DBUS_TYPE_BOOLEAN, &modem->lockdown); ofono_dbus_dict_append(dict, "Emergency", DBUS_TYPE_BOOLEAN, &emergency); info = __ofono_atom_find(OFONO_ATOM_TYPE_DEVINFO, modem); if (info) { if (info->manufacturer) ofono_dbus_dict_append(dict, "Manufacturer", DBUS_TYPE_STRING, &info->manufacturer); if (info->model) ofono_dbus_dict_append(dict, "Model", DBUS_TYPE_STRING, &info->model); if (info->revision) ofono_dbus_dict_append(dict, "Revision", DBUS_TYPE_STRING, &info->revision); if (info->serial) ofono_dbus_dict_append(dict, "Serial", DBUS_TYPE_STRING, &info->serial); } interfaces = g_new0(char *, g_slist_length(modem->interface_list) + 1); for (i = 0, l = modem->interface_list; l; l = l->next, i++) interfaces[i] = l->data; ofono_dbus_dict_append_array(dict, "Interfaces", DBUS_TYPE_STRING, &interfaces); g_free(interfaces); features = g_new0(char *, g_slist_length(modem->feature_list) + 1); for (i = 0, l = modem->feature_list; l; l = l->next, i++) features[i] = l->data; ofono_dbus_dict_append_array(dict, "Features", DBUS_TYPE_STRING, &features); g_free(features); if (modem->name) ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING, &modem->name); strtype = modem_type_to_string(modem->driver->modem_type); ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &strtype); }