X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fdevice.c;h=b52fb7ea275ec52f5f539e739b91d7685221040b;hb=c3f5d63a9788544edcf7846e6c0e6977db52c2bc;hp=93a076f550ef27183b0dd5d2abcb3369f789eeb3;hpb=925e46442d09bccaec4e5077011eb2c45189a3e2;p=connman diff --git a/src/device.c b/src/device.c index 93a076f..b52fb7e 100644 --- a/src/device.c +++ b/src/device.c @@ -43,6 +43,7 @@ struct connman_device { connman_uint16_t scan_interval; char *name; char *node; + char *address; char *interface; unsigned int connections; guint scan_timeout; @@ -88,6 +89,8 @@ static const char *type2description(enum connman_device_type type) return "WiMAX"; case CONNMAN_DEVICE_TYPE_BLUETOOTH: return "Bluetooth"; + case CONNMAN_DEVICE_TYPE_GPS: + return "GPS"; case CONNMAN_DEVICE_TYPE_HSO: case CONNMAN_DEVICE_TYPE_NOZOMI: case CONNMAN_DEVICE_TYPE_HUAWEI: @@ -112,6 +115,8 @@ static const char *type2string(enum connman_device_type type) return "wimax"; case CONNMAN_DEVICE_TYPE_BLUETOOTH: return "bluetooth"; + case CONNMAN_DEVICE_TYPE_GPS: + return "gps"; case CONNMAN_DEVICE_TYPE_HSO: case CONNMAN_DEVICE_TYPE_HUAWEI: case CONNMAN_DEVICE_TYPE_NOZOMI: @@ -154,6 +159,39 @@ static enum connman_device_policy string2policy(const char *policy) return CONNMAN_DEVICE_POLICY_UNKNOWN; } +static int set_carrier(struct connman_device *device, connman_bool_t carrier) +{ + if (carrier == TRUE) { + enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN; + struct connman_element *element; + + switch (device->element.ipv4.method) { + case CONNMAN_IPV4_METHOD_UNKNOWN: + case CONNMAN_IPV4_METHOD_OFF: + return 0; + case CONNMAN_IPV4_METHOD_STATIC: + type = CONNMAN_ELEMENT_TYPE_IPV4; + break; + case CONNMAN_IPV4_METHOD_DHCP: + type = CONNMAN_ELEMENT_TYPE_DHCP; + break; + } + + element = connman_element_create(NULL); + if (element != NULL) { + element->type = type; + element->index = device->element.index; + + if (connman_element_register(element, + &device->element) < 0) + connman_element_unref(element); + } + } else + connman_element_unregister_children(&device->element); + + return 0; +} + static int set_powered(struct connman_device *device, connman_bool_t powered) { struct connman_device_driver *driver = device->driver; @@ -165,16 +203,20 @@ static int set_powered(struct connman_device *device, connman_bool_t powered) return -EINVAL; if (powered == TRUE) { - if (driver->enable) + if (driver->enable) { err = driver->enable(device); - else + __connman_notifier_device_type_increase(device->type); + } else err = -EINVAL; } else { g_hash_table_remove_all(device->networks); - if (driver->disable) + set_carrier(device, FALSE); + + if (driver->disable) { err = driver->disable(device); - else + __connman_notifier_device_type_decrease(device->type); + } else err = -EINVAL; } @@ -208,6 +250,8 @@ static int set_policy(DBusConnection *connection, case CONNMAN_DEVICE_POLICY_MANUAL: if (device->powered == FALSE) err = set_powered(device, TRUE); + else + err = set_carrier(device, device->carrier); break; } @@ -291,20 +335,19 @@ static DBusMessage *get_properties(DBusConnection *conn, DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - str = type2description(device->type); - if (str != NULL && device->interface != NULL) { - char *name = g_strdup_printf("%s (%s)", str, device->interface); - if (name != NULL) - connman_dbus_dict_append_variant(&dict, "Name", - DBUS_TYPE_STRING, &name); - g_free(name); - } + if (device->name != NULL) + connman_dbus_dict_append_variant(&dict, "Name", + DBUS_TYPE_STRING, &device->name); str = type2string(device->type); if (str != NULL) connman_dbus_dict_append_variant(&dict, "Type", DBUS_TYPE_STRING, &str); + if (device->address != NULL) + connman_dbus_dict_append_variant(&dict, "Address", + DBUS_TYPE_STRING, &device->address); + if (device->interface != NULL) connman_dbus_dict_append_variant(&dict, "Interface", DBUS_TYPE_STRING, &device->interface); @@ -459,6 +502,78 @@ static DBusMessage *set_property(DBusConnection *conn, return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } +static DBusMessage *join_network(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct connman_device *device = data; + struct connman_network *network; + enum connman_network_type type; + DBusMessageIter iter, array; + int err, index; + + DBG("conn %p", conn); + + if (__connman_security_check_privilege(msg, + CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) + return __connman_error_permission_denied(msg); + + if (!device->driver || !device->driver->join) + return __connman_error_not_supported(msg); + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_recurse(&iter, &array); + + switch (device->type) { + case CONNMAN_DEVICE_TYPE_WIFI: + type = CONNMAN_NETWORK_TYPE_WIFI; + break; + default: + return __connman_error_not_supported(msg); + } + + network = connman_network_create("00_00_00_00_00_00", type); + if (network == NULL) + return __connman_error_failed(msg); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, value; + const char *key, *str; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); + + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &value); + + switch (dbus_message_iter_get_arg_type(&value)) { + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic(&value, &str); + if (g_str_equal(key, "WiFi.SSID") == TRUE) + connman_network_set_blob(network, key, + str, strlen(str)); + else + connman_network_set_string(network, key, str); + break; + } + + dbus_message_iter_next(&array); + } + + index = connman_device_get_index(device); + connman_network_set_index(network, index); + + connman_network_set_protocol(network, CONNMAN_NETWORK_PROTOCOL_IP); + + err = device->driver->join(device, network); + + connman_network_unref(network); + + if (err < 0) + return __connman_error_failed(msg); + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); +} + static DBusMessage *create_network(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -516,6 +631,7 @@ static DBusMessage *propose_scan(DBusConnection *conn, static GDBusMethodTable device_methods[] = { { "GetProperties", "", "a{sv}", get_properties }, { "SetProperty", "sv", "", set_property }, + { "JoinNetwork", "a{sv}", "", join_network }, { "CreateNetwork", "a{sv}", "o", create_network }, { "RemoveNetwork", "o", "", remove_network }, { "ProposeScan", "", "", propose_scan }, @@ -611,8 +727,10 @@ static void device_enable(struct connman_device *device) if (device->powered == TRUE) return; - if (device->driver->enable) + if (device->driver->enable) { device->driver->enable(device); + __connman_notifier_device_type_increase(device->type); + } } static void device_disable(struct connman_device *device) @@ -627,8 +745,10 @@ static void device_disable(struct connman_device *device) g_hash_table_remove_all(device->networks); - if (device->driver->disable) + if (device->driver->disable) { device->driver->disable(device); + __connman_notifier_device_type_decrease(device->type); + } } static int setup_device(struct connman_device *device) @@ -794,6 +914,7 @@ static void device_destruct(struct connman_element *element) g_free(device->node); g_free(device->name); + g_free(device->address); g_free(device->interface); g_free(device->last_network); @@ -835,12 +956,13 @@ struct connman_device *connman_device_create(const char *node, str = type2string(type); if (str != NULL) - connman_element_set_static_property(&device->element, - "Type", DBUS_TYPE_STRING, &str); + connman_element_set_string(&device->element, + CONNMAN_PROPERTY_ID_TYPE, str); device->element.ipv4.method = CONNMAN_IPV4_METHOD_DHCP; device->type = type; + device->name = g_strdup(type2description(device->type)); device->mode = CONNMAN_DEVICE_MODE_UNKNOWN; device->policy = CONNMAN_DEVICE_POLICY_AUTO; @@ -863,6 +985,10 @@ struct connman_device *connman_device_create(const char *node, device->priority = 50; device->scan_interval = 0; break; + case CONNMAN_DEVICE_TYPE_GPS: + device->priority = 0; + device->scan_interval = 0; + break; case CONNMAN_DEVICE_TYPE_HSO: case CONNMAN_DEVICE_TYPE_NOZOMI: case CONNMAN_DEVICE_TYPE_HUAWEI: @@ -903,6 +1029,22 @@ void connman_device_unref(struct connman_device *device) connman_element_unref(&device->element); } +const char *__connman_device_get_type(struct connman_device *device) +{ + return type2string(device->type); +} + +/** + * connman_device_get_type: + * @device: device structure + * + * Get type of device + */ +enum connman_device_type connman_device_get_type(struct connman_device *device) +{ + return device->type; +} + /** * connman_device_get_name: * @device: device structure @@ -963,6 +1105,13 @@ void connman_device_set_interface(struct connman_device *device, g_free(device->interface); device->interface = g_strdup(interface); + + if (device->name == NULL) { + const char *str = type2description(device->type); + if (str != NULL && device->interface != NULL) + device->name = g_strdup_printf("%s (%s)", str, + device->interface); + } } /** @@ -1102,35 +1251,17 @@ int connman_device_set_carrier(struct connman_device *device, device->carrier = carrier; - if (carrier == TRUE) { - enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN; - struct connman_element *element; - - switch (device->element.ipv4.method) { - case CONNMAN_IPV4_METHOD_UNKNOWN: - case CONNMAN_IPV4_METHOD_OFF: - return 0; - case CONNMAN_IPV4_METHOD_STATIC: - type = CONNMAN_ELEMENT_TYPE_IPV4; - break; - case CONNMAN_IPV4_METHOD_DHCP: - type = CONNMAN_ELEMENT_TYPE_DHCP; - break; - } - - element = connman_element_create(NULL); - if (element != NULL) { - element->type = type; - element->index = device->element.index; - - if (connman_element_register(element, - &device->element) < 0) - connman_element_unref(element); - } - } else - connman_element_unregister_children(&device->element); + switch (device->policy) { + case CONNMAN_DEVICE_POLICY_UNKNOWN: + case CONNMAN_DEVICE_POLICY_IGNORE: + case CONNMAN_DEVICE_POLICY_OFF: + return 0; + case CONNMAN_DEVICE_POLICY_AUTO: + case CONNMAN_DEVICE_POLICY_MANUAL: + break; + } - return 0; + return set_carrier(device, device->carrier); } void __connman_device_disconnect(struct connman_device *device) @@ -1173,7 +1304,8 @@ static void connect_known_network(struct connman_device *device) if (connman_network_get_available(value) == FALSE) continue; - name = connman_network_get_string(value, "Name"); + name = connman_network_get_string(value, + CONNMAN_PROPERTY_ID_NAME); if (name != NULL && device->last_network != NULL) { if (g_str_equal(name, device->last_network) == TRUE) { network = value; @@ -1189,8 +1321,10 @@ static void connect_known_network(struct connman_device *device) continue; } - old_priority = connman_network_get_uint8(network, "Priority"); - new_priority = connman_network_get_uint8(value, "Priority"); + old_priority = connman_network_get_uint8(network, + CONNMAN_PROPERTY_ID_PRIORITY); + new_priority = connman_network_get_uint8(value, + CONNMAN_PROPERTY_ID_PRIORITY); if (new_priority != old_priority) { if (new_priority > old_priority) @@ -1198,8 +1332,10 @@ static void connect_known_network(struct connman_device *device) continue; } - old_strength = connman_network_get_uint8(network, "Strength"); - new_strength = connman_network_get_uint8(value, "Strength"); + old_strength = connman_network_get_uint8(network, + CONNMAN_PROPERTY_ID_STRENGTH); + new_strength = connman_network_get_uint8(value, + CONNMAN_PROPERTY_ID_STRENGTH); if (new_strength > old_strength) network = value; @@ -1364,7 +1500,10 @@ int connman_device_set_string(struct connman_device *device, { DBG("device %p key %s value %s", device, key, value); - if (g_str_equal(key, "Name") == TRUE) { + if (g_str_equal(key, "Address") == TRUE) { + g_free(device->address); + device->address = g_strdup(value); + } else if (g_str_equal(key, "Name") == TRUE) { g_free(device->name); device->name = g_strdup(value); } else if (g_str_equal(key, "Node") == TRUE) { @@ -1372,7 +1511,7 @@ int connman_device_set_string(struct connman_device *device, device->node = g_strdup(value); } - return 0; + return connman_element_set_string(&device->element, key, value); } /** @@ -1387,12 +1526,14 @@ const char *connman_device_get_string(struct connman_device *device, { DBG("device %p key %s", device, key); - if (g_str_equal(key, "Name") == TRUE) + if (g_str_equal(key, "Address") == TRUE) + return device->address; + else if (g_str_equal(key, "Name") == TRUE) return device->name; else if (g_str_equal(key, "Node") == TRUE) return device->node; - return NULL; + return connman_element_get_string(&device->element, key); } static void set_offlinemode(struct connman_element *element, gpointer user_data) @@ -1421,6 +1562,8 @@ int __connman_device_set_offlinemode(connman_bool_t offlinemode) __connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, set_offlinemode, GUINT_TO_POINTER(offlinemode)); + __connman_notifier_offline_mode(offlinemode); + return 0; } @@ -1513,7 +1656,8 @@ void __connman_device_set_network(struct connman_device *device, const char *name; if (network != NULL) { - name = connman_network_get_string(network, "Name"); + name = connman_network_get_string(network, + CONNMAN_PROPERTY_ID_NAME); device->last_network = g_strdup(name); } @@ -1701,10 +1845,12 @@ static int device_load(struct connman_device *device) break; } +#if 0 str = g_key_file_get_string(keyfile, "Configuration", "LastNetwork", NULL); if (str != NULL) device->last_network = str; +#endif g_key_file_free(keyfile);