Ejemplo n.º 1
0
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
{
	struct ofono_modem *modem = user;

	switch (new_state) {
	case OFONO_SIM_STATE_NOT_PRESENT:
		modem_change_state(modem, MODEM_STATE_PRE_SIM);
	case OFONO_SIM_STATE_INSERTED:
	case OFONO_SIM_STATE_RESETTING:
		break;
	case OFONO_SIM_STATE_LOCKED_OUT:
		modem_change_state(modem, MODEM_STATE_PRE_SIM);
		break;
	case OFONO_SIM_STATE_READY:
		modem_change_state(modem, MODEM_STATE_OFFLINE);

		/*
		 * If we don't have the set_online method, also proceed
		 * straight to the online state
		 */
		if (modem->driver->set_online == NULL)
			set_online(modem, TRUE);

		if (modem->online == TRUE)
			modem_change_state(modem, MODEM_STATE_ONLINE);
		else if (modem->get_online)
			modem->driver->set_online(modem, 1, common_online_cb,
							modem);

		modem->get_online = FALSE;

		break;
	}
}
Ejemplo n.º 2
0
static void sim_state_watch(enum ofono_sim_state new_state, void *user)
{
	struct ofono_modem *modem = user;

	switch (new_state) {
	case OFONO_SIM_STATE_NOT_PRESENT:
		modem_change_state(modem, MODEM_STATE_PRE_SIM);
	case OFONO_SIM_STATE_INSERTED:
	case OFONO_SIM_STATE_RESETTING:
		break;
	case OFONO_SIM_STATE_LOCKED_OUT:
		if (modem->driver_watches_sim == FALSE)
			modem_change_state(modem, MODEM_STATE_PRE_SIM);
		break;
	case OFONO_SIM_STATE_READY:
		/* Avoid state regressions */
		if (modem->modem_state != MODEM_STATE_ONLINE) {
			modem_change_state(modem, MODEM_STATE_OFFLINE);

			/* Modem is always online, proceed to online state. */
			if (modem_is_always_online(modem) == TRUE)
				set_online(modem, TRUE);

			if (modem->online == TRUE)
				modem_change_state(modem, MODEM_STATE_ONLINE);
			else if (modem->get_online)
				modem->driver->set_online(modem, 1,
						common_online_cb, modem);

			modem->get_online = FALSE;
		}

		break;
	}
}
Ejemplo n.º 3
0
void ofono_modem_set_online(struct ofono_modem *modem, ofono_bool_t online)
{
	DBusConnection *conn = ofono_dbus_get_connection();
	dbus_bool_t dbus_online = online;

	if (modem->online == online)
		return;

	set_online(modem, online);

	if (online)
		modem_change_state(modem, MODEM_STATE_ONLINE);
	else
		modem_change_state(modem, MODEM_STATE_OFFLINE);
}
Ejemplo n.º 4
0
static int set_powered(struct ofono_modem *modem, ofono_bool_t powered)
{
	const struct ofono_modem_driver *driver = modem->driver;
	int err = -EINVAL;

	if (modem->powered_pending == powered)
		return -EALREADY;

	/* Remove the atoms even if the driver is no longer available */
	if (powered == FALSE)
		modem_change_state(modem, MODEM_STATE_POWER_OFF);

	modem->powered_pending = powered;

	if (driver == NULL)
		return -EINVAL;

	if (powered == TRUE) {
		if (driver->enable)
			err = driver->enable(modem);
	} else {
		if (driver->disable)
			err = driver->disable(modem);
	}

	if (err == 0) {
		modem->powered = powered;
		notify_powered_watches(modem);
	} else if (err != -EINPROGRESS)
		modem->powered_pending = modem->powered;

	return err;
}
Ejemplo n.º 5
0
static void offline_cb(const struct ofono_error *error, void *data)
{
	struct ofono_modem *modem = data;
	DBusMessage *reply;

	if (error->type == OFONO_ERROR_TYPE_NO_ERROR)
		reply = dbus_message_new_method_return(modem->pending);
	else
		reply = __ofono_error_failed(modem->pending);

	__ofono_dbus_pending_reply(&modem->pending, reply);

	if (error->type == OFONO_ERROR_TYPE_NO_ERROR) {
		switch (modem->modem_state) {
		case MODEM_STATE_PRE_SIM:
			set_online(modem, FALSE);
			break;
		case MODEM_STATE_ONLINE:
			set_online(modem, FALSE);
			modem_change_state(modem, MODEM_STATE_OFFLINE);
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 6
0
static void common_online_cb(const struct ofono_error *error, void *data)
{
	struct ofono_modem *modem = data;

	if (error->type != OFONO_ERROR_TYPE_NO_ERROR)
		return;

	/*
	 * If we need to get online after a silent reset this callback
	 * is called.  The callback should not consider the pending dbus
	 * message.
	 *
	 * Additionally, this process can be interrupted by the following
	 * events:
	 *	- Sim being removed or reset
	 *	- SetProperty(Powered, False) being called
	 *	- SetProperty(Lockdown, True) being called
	 *
	 * We should not set the modem to the online state in these cases.
	 */
	switch (modem->modem_state) {
	case MODEM_STATE_OFFLINE:
		set_online(modem, TRUE);

		/* Will this increase emergency call setup time??? */
		modem_change_state(modem, MODEM_STATE_ONLINE);
		break;
	case MODEM_STATE_POWER_OFF:
		/* The powered operation is pending */
		break;
	case MODEM_STATE_PRE_SIM:
		/*
		 * Its valid to be in online even without a SIM/SIM being
		 * PIN locked. e.g.: Emergency mode
		 */
		DBG("Online in PRE SIM state");

		set_online(modem, TRUE);
		break;
	case MODEM_STATE_ONLINE:
		ofono_error("Online called when the modem is already online!");
		break;
	};
}
Ejemplo n.º 7
0
void ofono_modem_reset(struct ofono_modem *modem)
{
	int err;

	DBG("%p", modem);

	if (modem->pending) {
		DBusMessage *reply = __ofono_error_failed(modem->pending);
		__ofono_dbus_pending_reply(&modem->pending, reply);
	}

	if (modem->modem_state == MODEM_STATE_ONLINE)
		modem->get_online = TRUE;

	ofono_modem_set_powered(modem, FALSE);

	err = set_powered(modem, TRUE);
	if (err == -EINPROGRESS)
		return;

	modem_change_state(modem, MODEM_STATE_PRE_SIM);
}
Ejemplo n.º 8
0
void __ofono_modem_sim_reset(struct ofono_modem *modem)
{
	DBG("%p", modem);

	modem_change_state(modem, MODEM_STATE_PRE_SIM);
}
Ejemplo n.º 9
0
void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
{
	DBusConnection *conn = ofono_dbus_get_connection();
	dbus_bool_t dbus_powered = powered;

	if (modem->timeout > 0) {
		g_source_remove(modem->timeout);
		modem->timeout = 0;
	}

	if (modem->powered_pending != modem->powered &&
						modem->pending != NULL) {
		DBusMessage *reply;

		if (powered == modem->powered_pending)
			reply = dbus_message_new_method_return(modem->pending);
		else
			reply = __ofono_error_failed(modem->pending);

		__ofono_dbus_pending_reply(&modem->pending, reply);
	}

	modem->powered_pending = powered;

	if (modem->powered == powered)
		goto out;

	modem->powered = powered;
	notify_powered_watches(modem);

	if (modem->lockdown)
		ofono_dbus_signal_property_changed(conn, modem->path,
					OFONO_MODEM_INTERFACE,
					"Lockdown", DBUS_TYPE_BOOLEAN,
					&modem->lockdown);

	if (modem->driver == NULL) {
		ofono_error("Calling ofono_modem_set_powered on a"
				"modem with no driver is not valid, "
				"please fix the modem driver.");
		return;
	}

	ofono_dbus_signal_property_changed(conn, modem->path,
					OFONO_MODEM_INTERFACE,
					"Powered", DBUS_TYPE_BOOLEAN,
					&dbus_powered);

	if (powered) {
		modem_change_state(modem, MODEM_STATE_PRE_SIM);

		/* Force SIM Ready for devices with no sim atom */
		if (modem_has_sim(modem) == FALSE)
			sim_state_watch(OFONO_SIM_STATE_READY, modem);
	} else {
		set_online(modem, FALSE);

		modem_change_state(modem, MODEM_STATE_POWER_OFF);
	}

out:
	if (powering_down && powered == FALSE) {
		modems_remaining -= 1;

		if (modems_remaining == 0)
			__ofono_exit();
	}
}
Ejemplo n.º 10
0
static DBusMessage *modem_set_property(DBusConnection *conn,
					DBusMessage *msg, void *data)
{
	struct ofono_modem *modem = data;
	DBusMessageIter iter, var;
	const char *name;

	if (dbus_message_iter_init(msg, &iter) == FALSE)
		return __ofono_error_invalid_args(msg);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
		return __ofono_error_invalid_args(msg);

	dbus_message_iter_get_basic(&iter, &name);
	dbus_message_iter_next(&iter);

	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
		return __ofono_error_invalid_args(msg);

	if (powering_down == TRUE)
		return __ofono_error_failed(msg);

	dbus_message_iter_recurse(&iter, &var);

	if (g_str_equal(name, "Online"))
		return set_property_online(modem, msg, &var);

	if (g_str_equal(name, "Powered") == TRUE) {
		ofono_bool_t powered;
		int err;

		if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
			return __ofono_error_invalid_args(msg);

		dbus_message_iter_get_basic(&var, &powered);

		if (modem->pending != NULL)
			return __ofono_error_busy(msg);

		if (modem->powered == powered)
			return dbus_message_new_method_return(msg);

		if (ofono_modem_get_emergency_mode(modem) == TRUE)
			return __ofono_error_emergency_active(msg);

		if (modem->lockdown)
			return __ofono_error_access_denied(msg);

		err = set_powered(modem, powered);
		if (err < 0) {
			if (err != -EINPROGRESS)
				return __ofono_error_failed(msg);

			modem->pending = dbus_message_ref(msg);
			modem->timeout = g_timeout_add_seconds(20,
						set_powered_timeout, modem);
			return NULL;
		}

		g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);

		ofono_dbus_signal_property_changed(conn, modem->path,
						OFONO_MODEM_INTERFACE,
						"Powered", DBUS_TYPE_BOOLEAN,
						&powered);

		if (powered) {
			modem_change_state(modem, MODEM_STATE_PRE_SIM);

			/* Force SIM Ready for devies with no sim atom */
			if (modem_has_sim(modem) == FALSE)
				sim_state_watch(OFONO_SIM_STATE_READY, modem);
		} else {
			set_online(modem, FALSE);
			modem_change_state(modem, MODEM_STATE_POWER_OFF);
		}

		return NULL;
	}

	if (g_str_equal(name, "Lockdown"))
		return set_property_lockdown(modem, msg, &var);

	return __ofono_error_invalid_args(msg);
}