Esempio n. 1
0
File: sms.c Progetto: AndriusA/ofono
/*
 * 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);
}
Esempio n. 2
0
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__);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
File: sms.c Progetto: AndriusA/ofono
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);
}
Esempio n. 5
0
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);
}