DBusPendingCall *call_get_contexts;
};
+static const char *api2string(enum ofono_api api)
+{
+ switch (api) {
+ case OFONO_API_SIM:
+ return "sim";
+ case OFONO_API_NETREG:
+ return "netreg";
+ case OFONO_API_CM:
+ return "cm";
+ case OFONO_API_CDMA_NETREG:
+ return "cdma-netreg";
+ case OFONO_API_CDMA_CM:
+ return "cmda-cm";
+ }
+
+ return "unknown";
+}
+
static char *get_ident(const char *path)
{
char *pos;
DBG("%s path %s %s.%s", modem->path, path, interface, property);
if (modem->call_set_property != NULL) {
- connman_error("Pending SetProperty");
- return -EBUSY;
+ DBG("Cancel pending SetProperty");
+
+ dbus_pending_call_cancel(modem->call_set_property);
+ modem->call_set_property = NULL;
}
message = dbus_message_new_method_call(OFONO_SERVICE, path,
modem->device = device;
+ connman_device_set_powered(modem->device, modem->online);
out:
g_free(ident);
}
modem->network = NULL;
return;
}
+
+ /*
+ * Create the ipconfig layer before trying to connect. Withouth
+ * the ipconfig layer the core is not ready to process errors.
+ */
+ connman_network_set_index(modem->network, -1);
+}
+
+static void remove_network(struct modem_data *modem)
+{
+ DBG("%s", modem->path);
+
+ if (modem->network == NULL)
+ return;
+
+ DBG("network %p", modem->network);
+
+ connman_device_remove_network(modem->device, modem->network);
+ connman_network_unref(modem->network);
+ modem->network = NULL;
}
static int add_cm_context(struct modem_data *modem, const char *context_path,
if (modem->context == NULL)
modem->context = network_context_alloc(modem->path);
+ if (modem->name == NULL)
+ modem->name = g_strdup("CDMA Network");
+
add_network(modem);
if (modem->cdma_cm_powered == TRUE)
{
DBG("%s Settings", modem->path);
- if (modem->context != NULL)
- return;
-
extract_ipv4_settings(value, modem->context);
}
cdma_cm_properties_reply, modem);
}
-static connman_bool_t connection_manager_init(struct modem_data *modem)
-{
- if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
- if (ready_to_create_device(modem) == TRUE)
- create_device(modem);
-
- if (modem->device != NULL) {
- cm_get_properties(modem);
- cm_get_contexts(modem);
- }
-
- return TRUE;
- }
-
- if (has_interface(modem->interfaces, OFONO_API_CDMA_CM) == TRUE) {
- if (ready_to_create_device(modem) == TRUE)
- create_device(modem);
-
- if (modem->device != NULL)
- cdma_cm_get_properties(modem);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
static void sim_update_imsi(struct modem_data *modem,
DBusMessageIter* value)
{
if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
sim_update_imsi(modem, &value);
- if (modem->online == FALSE) {
- modem_set_online(modem, TRUE);
- } else if (has_interface(modem->interfaces,
- OFONO_API_CM) == TRUE) {
- if (ready_to_create_device(modem) == TRUE)
- create_device(modem);
- } else if (has_interface(modem->interfaces,
- OFONO_API_CDMA_CM) == TRUE) {
- if (ready_to_create_device(modem) == TRUE)
- create_device(modem);
- }
+ if (ready_to_create_device(modem) == FALSE)
+ return TRUE;
+
+ /*
+ * This is a GSM modem. Create the device and
+ * register it at the core. Enabling (setting
+ * it online is done through the
+ * modem_enable() callback.
+ */
+ create_device(modem);
}
return TRUE;
if (g_str_equal(key, "SubscriberIdentity") == TRUE) {
sim_update_imsi(modem, &value);
- connection_manager_init(modem);
+ if (ready_to_create_device(modem) == FALSE)
+ return;
+
+ /*
+ * This is a GSM modem. Create the device and
+ * register it at the core. Enabling (setting
+ * it online is done through the
+ * modem_enable() callback.
+ */
+ create_device(modem);
+
+ if (modem->online == FALSE)
+ return;
+
+ /*
+ * The modem is already online and we have the CM interface.
+ * There will be no interface update and therefore our
+ * state machine will not go to next step. We have to
+ * trigger it from here.
+ */
+ if (has_interface(modem->interfaces, OFONO_API_CM) == TRUE) {
+ cm_get_properties(modem);
+ cm_get_contexts(modem);
+ }
return;
}
sim_properties_reply, modem);
}
+static connman_bool_t api_added(uint8_t old_iface, uint8_t new_iface,
+ enum ofono_api api)
+{
+ if (has_interface(old_iface, api) == FALSE &&
+ has_interface(new_iface, api) == TRUE) {
+ DBG("%s added", api2string(api));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static connman_bool_t api_removed(uint8_t old_iface, uint8_t new_iface,
+ enum ofono_api api)
+{
+ if (has_interface(old_iface, api) == TRUE &&
+ has_interface(new_iface, api) == FALSE) {
+ DBG("%s removed", api2string(api));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void modem_update_interfaces(struct modem_data *modem,
+ uint8_t old_ifaces,
+ uint8_t new_ifaces)
+{
+ DBG("%s", modem->path);
+
+ if (api_added(old_ifaces, new_ifaces, OFONO_API_SIM) == TRUE) {
+ if (modem->imsi == NULL &&
+ modem->set_powered == FALSE) {
+ /*
+ * Only use do GetProperties() when
+ * device has not been powered up.
+ */
+ sim_get_properties(modem);
+ }
+ }
+
+ if (api_added(old_ifaces, new_ifaces, OFONO_API_CM) == TRUE) {
+ if (modem->device != NULL) {
+ cm_get_properties(modem);
+ cm_get_contexts(modem);
+ }
+ }
+
+ if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_CM) == TRUE) {
+ if (ready_to_create_device(modem) == TRUE)
+ create_device(modem);
+
+ if (modem->device != NULL)
+ cdma_cm_get_properties(modem);
+ }
+
+ if (api_added(old_ifaces, new_ifaces, OFONO_API_NETREG) == TRUE) {
+ if (modem->attached == TRUE)
+ netreg_get_properties(modem);
+ }
+
+ if (api_added(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG) == TRUE) {
+ cdma_netreg_get_properties(modem);
+ }
+
+ if (api_removed(old_ifaces, new_ifaces, OFONO_API_CM) == TRUE) {
+ remove_cm_context(modem, modem->context->path);
+ }
+
+ if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_CM) == TRUE) {
+ remove_cm_context(modem, modem->context->path);
+ }
+
+ if (api_removed(old_ifaces, new_ifaces, OFONO_API_NETREG) == TRUE) {
+ remove_network(modem);
+ }
+
+ if (api_removed(old_ifaces, new_ifaces, OFONO_API_CDMA_NETREG == TRUE)) {
+ remove_network(modem);
+ }
+}
+
static gboolean modem_changed(DBusConnection *connection, DBusMessage *message,
void *user_data)
{
DBG("%s Online %d", modem->path, modem->online);
- if (modem->online == FALSE)
+ if (modem->device == NULL)
return TRUE;
- connection_manager_init(modem);
+ connman_device_set_powered(modem->device, modem->online);
} else if (g_str_equal(key, "Interfaces") == TRUE) {
uint8_t interfaces;
if (interfaces == modem->interfaces)
return TRUE;
- modem->interfaces = interfaces;
-
- DBG("%s Interfaces 0x%02x", modem->path,
- modem->interfaces);
-
- if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE) {
- if (modem->imsi == NULL &&
- modem->set_powered == FALSE) {
- /*
- * Only use do GetProperties() when
- * device has not been powered up.
- */
- sim_get_properties(modem);
- return TRUE;
- }
- }
-
- if (connection_manager_init(modem) == FALSE) {
- if (modem->context != NULL) {
- remove_cm_context(modem,
- modem->context->path);
- }
+ DBG("%s Interfaces 0x%02x", modem->path, interfaces);
- if (modem->device != NULL)
- destroy_device(modem);
+ modem_update_interfaces(modem, modem->interfaces, interfaces);
- return TRUE;
- }
-
- if (has_interface(modem->interfaces, OFONO_API_NETREG) == TRUE) {
- if (modem->attached == TRUE)
- netreg_get_properties(modem);
- } else if (has_interface(modem->interfaces,
- OFONO_API_CDMA_NETREG) == TRUE)
- cdma_netreg_get_properties(modem);
+ modem->interfaces = interfaces;
} else if (g_str_equal(key, "Serial") == TRUE) {
char *serial;
DBG("%s Serial %s", modem->path, modem->serial);
- connection_manager_init(modem);
+ if (has_interface(modem->interfaces,
+ OFONO_API_CDMA_CM) == TRUE) {
+ if (ready_to_create_device(modem) == TRUE)
+ create_device(modem);
+ }
}
return TRUE;
if (modem->ignore == TRUE)
return;
- if (modem->powered == FALSE)
+ if (modem->powered == FALSE) {
modem_set_powered(modem, TRUE);
- else if (has_interface(modem->interfaces, OFONO_API_SIM) == TRUE)
- sim_get_properties(modem);
- else
- connection_manager_init(modem);
+ return;
+ }
+
+ modem_update_interfaces(modem, 0, modem->interfaces);
}
static void modem_power_down(gpointer key, gpointer value, gpointer user_data)
.disable = modem_disable,
};
+static int tech_probe(struct connman_technology *technology)
+{
+ return 0;
+}
+
+static void tech_remove(struct connman_technology *technology)
+{
+}
+
+static struct connman_technology_driver tech_driver = {
+ .name = "cellular",
+ .type = CONNMAN_SERVICE_TYPE_CELLULAR,
+ .probe = tech_probe,
+ .remove = tech_remove,
+};
+
static guint watch;
static guint modem_added_watch;
static guint modem_removed_watch;
goto remove;
}
+ err = connman_technology_driver_register(&tech_driver);
+ if (err < 0) {
+ connman_device_driver_unregister(&modem_driver);
+ connman_network_driver_unregister(&network_driver);
+ goto remove;
+ }
+
return 0;
remove:
context_hash = NULL;
}
+ connman_technology_driver_unregister(&tech_driver);
connman_device_driver_unregister(&modem_driver);
connman_network_driver_unregister(&network_driver);