X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fdevice.c;h=ef899332551b37f0f7d22810658fdea2ecef660d;hb=b972ec96236afc662b21ace09d6adaa29d222411;hp=0f74c20a81e0b29571e26d0eed66ed48dacf897c;hpb=219aefaa626b3b0c695d079acef6c08b30bfdd66;p=connman diff --git a/src/device.c b/src/device.c index 0f74c20..ef89933 100644 --- a/src/device.c +++ b/src/device.c @@ -56,6 +56,8 @@ static const char *type2description(enum connman_device_type type) return "WiMAX"; case CONNMAN_DEVICE_TYPE_BLUETOOTH: return "Bluetooth"; + case CONNMAN_DEVICE_TYPE_HSO: + return "Cellular"; default: return NULL; } @@ -74,6 +76,8 @@ static const char *type2string(enum connman_device_type type) return "modem"; case CONNMAN_DEVICE_TYPE_BLUETOOTH: return "bluetooth"; + case CONNMAN_DEVICE_TYPE_HSO: + return "cellular"; default: return NULL; } @@ -84,15 +88,31 @@ static const char *policy2string(enum connman_device_policy policy) switch (policy) { case CONNMAN_DEVICE_POLICY_IGNORE: return "ignore"; - case CONNMAN_DEVICE_POLICY_AUTO: - return "auto"; case CONNMAN_DEVICE_POLICY_OFF: return "off"; + case CONNMAN_DEVICE_POLICY_AUTO: + return "auto"; + case CONNMAN_DEVICE_POLICY_MANUAL: + return "manual"; default: return NULL; } } +static enum connman_device_policy string2policy(const char *policy) +{ + if (g_str_equal(policy, "ignore") == TRUE) + return CONNMAN_DEVICE_POLICY_IGNORE; + else if (g_str_equal(policy, "off") == TRUE) + return CONNMAN_DEVICE_POLICY_OFF; + else if (g_str_equal(policy, "auto") == TRUE) + return CONNMAN_DEVICE_POLICY_AUTO; + else if (g_str_equal(policy, "manual") == TRUE) + return CONNMAN_DEVICE_POLICY_MANUAL; + else + return CONNMAN_DEVICE_POLICY_UNKNOWN; +} + static int set_powered(struct connman_device *device, gboolean powered) { struct connman_device_driver *driver = device->driver; @@ -118,6 +138,60 @@ static int set_powered(struct connman_device *device, gboolean powered) return err; } +static int set_policy(DBusConnection *connection, + struct connman_device *device, + enum connman_device_policy policy) +{ + DBusMessage *signal; + DBusMessageIter entry, value; + const char *str, *key = "Policy"; + int err = 0; + + DBG("device %p policy %d", device, policy); + + if (device->policy == policy) + return 0; + + switch (policy) { + case CONNMAN_DEVICE_POLICY_OFF: + if (device->powered == TRUE) + err = set_powered(device, FALSE); + break; + case CONNMAN_DEVICE_POLICY_AUTO: + case CONNMAN_DEVICE_POLICY_MANUAL: + if (device->powered == FALSE) + err = set_powered(device, TRUE); + break; + default: + break; + } + + if (err < 0) + return err; + + device->policy = policy; + + signal = dbus_message_new_signal(device->element.path, + CONNMAN_DEVICE_INTERFACE, "PropertyChanged"); + if (signal == NULL) + return 0; + + dbus_message_iter_init_append(signal, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + str = policy2string(policy); + + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, &value); + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &str); + dbus_message_iter_close_container(&entry, &value); + + g_dbus_send_message(connection, signal); + + return 0; +} + static void append_networks(struct connman_device *device, DBusMessageIter *entry) { @@ -132,7 +206,8 @@ static void append_networks(struct connman_device *device, dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter); - /* FIXME append networks */ + __connman_element_list((struct connman_element *) device, + CONNMAN_ELEMENT_TYPE_NETWORK, &iter); dbus_message_iter_close_container(&value, &iter); dbus_message_iter_close_container(entry, &value); @@ -232,6 +307,19 @@ static DBusMessage *set_property(DBusConnection *conn, err = set_powered(device, powered); if (err < 0 && err != -EINPROGRESS) return __connman_error_failed(msg); + } else if (g_str_equal(name, "Policy") == TRUE) { + enum connman_device_policy policy; + const char *str; + int err; + + dbus_message_iter_get_basic(&value, &str); + policy = string2policy(str); + if (policy == CONNMAN_DEVICE_POLICY_UNKNOWN) + return __connman_error_invalid_arguments(msg); + + err = set_policy(conn, device, policy); + if (err < 0) + return __connman_error_failed(msg); } __connman_element_store(&device->element); @@ -298,13 +386,46 @@ static GDBusSignalTable device_signals[] = { static DBusConnection *connection; +static void append_devices(DBusMessageIter *entry) +{ + DBusMessageIter value, iter; + const char *key = "Devices"; + + dbus_message_iter_append_basic(entry, DBUS_TYPE_STRING, &key); + + dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING, + &value); + + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter); + __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, &iter); + dbus_message_iter_close_container(&value, &iter); + + dbus_message_iter_close_container(entry, &value); +} + +static void emit_devices_signal(void) +{ + DBusMessage *signal; + DBusMessageIter entry; + + signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH, + CONNMAN_MANAGER_INTERFACE, "PropertyChanged"); + if (signal == NULL) + return; + + dbus_message_iter_init_append(signal, &entry); + + append_devices(&entry); + + g_dbus_send_message(connection, signal); +} + static int register_interface(struct connman_element *element) { struct connman_device *device = element->device; - g_dbus_unregister_interface(connection, element->path, - CONNMAN_DEVICE_INTERFACE); - if (g_dbus_register_interface(connection, element->path, CONNMAN_DEVICE_INTERFACE, device_methods, device_signals, @@ -313,11 +434,15 @@ static int register_interface(struct connman_element *element) return -EIO; } + emit_devices_signal(); + return 0; } static void unregister_interface(struct connman_element *element) { + emit_devices_signal(); + g_dbus_unregister_interface(connection, element->path, CONNMAN_DEVICE_INTERFACE); } @@ -532,6 +657,19 @@ const char *connman_device_get_interface(struct connman_device *device) } /** + * connman_device_set_policy: + * @device: device structure + * @policy: power and connection policy + * + * Change power and connection policy of device + */ +void connman_device_set_policy(struct connman_device *device, + enum connman_device_policy policy) +{ + device->policy = policy; +} + +/** * connman_device_set_mode: * @device: device structure * @mode: network mode @@ -776,7 +914,8 @@ static void device_enable(struct connman_device *device) { DBG("device %p", device); - if (device->policy != CONNMAN_DEVICE_POLICY_AUTO) + if (device->policy == CONNMAN_DEVICE_POLICY_IGNORE || + device->policy == CONNMAN_DEVICE_POLICY_OFF) return; if (device->powered == TRUE) @@ -790,7 +929,7 @@ static void device_disable(struct connman_device *device) { DBG("device %p", device); - if (device->policy != CONNMAN_DEVICE_POLICY_AUTO) + if (device->policy == CONNMAN_DEVICE_POLICY_IGNORE) return; if (device->powered == FALSE) @@ -821,10 +960,6 @@ static int device_probe(struct connman_element *element) if (device == NULL) return -ENODEV; - err = register_interface(element); - if (err < 0) - return err; - for (list = driver_list; list; list = list->next) { struct connman_device_driver *driver = list->data; @@ -835,11 +970,22 @@ static int device_probe(struct connman_element *element) if (driver->probe(device) == 0) { device->driver = driver; - device_enable(device); break; } } + if (!device->driver) + return -ENODEV; + + err = register_interface(element); + if (err < 0) { + if (device->driver->remove) + device->driver->remove(device); + return err; + } + + device_enable(device); + return 0; } @@ -852,14 +998,15 @@ static void device_remove(struct connman_element *element) if (device == NULL) return; - unregister_interface(element); + if (!device->driver) + return; - if (device->driver) { - device_disable(device); + device_disable(device); - if (device->driver->remove) - device->driver->remove(device); - } + unregister_interface(element); + + if (device->driver->remove) + device->driver->remove(device); } static struct connman_driver device_driver = {