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; } }
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; } }
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); }
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; }
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; } } }
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; }; }
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); }
void __ofono_modem_sim_reset(struct ofono_modem *modem) { DBG("%p", modem); modem_change_state(modem, MODEM_STATE_PRE_SIM); }
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(); } }
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); }