if (dbus_set_error_from_message(&error, reply) == TRUE) {
connman_error("%s", error.message);
dbus_error_free(&error);
- goto done;
+
+ goto err;
}
if (dbus_message_get_args(reply, &error,
dbus_error_free(&error);
} else
connman_error("Wrong arguments for connect");
- goto done;
+ goto err;
}
if (interface == NULL)
- goto done;
+ goto err;
DBG("interface %s", interface);
connman_network_set_connected(network, TRUE);
-done:
+ dbus_message_unref(reply);
+
+ dbus_pending_call_unref(call);
+
+ return;
+err:
+
+ connman_network_set_connected(network, FALSE);
+
dbus_message_unref(reply);
dbus_pending_call_unref(call);
connman_network_set_group(network, ident);
- g_hash_table_insert(bluetooth_networks, g_strdup(path), network);
+ g_hash_table_replace(bluetooth_networks, g_strdup(path), network);
done:
dbus_message_unref(reply);
static gboolean device_removed(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- const char *network_path, *identifier;
+ const char *network_path;
struct connman_network *network;
struct connman_device *device;
DBusMessageIter iter;
if (device == NULL)
return TRUE;
- identifier = connman_network_get_identifier(network);
-
g_hash_table_remove(bluetooth_networks, network_path);
- connman_device_remove_network(device, identifier);
-
return TRUE;
}
return TRUE;
}
+static void remove_device_networks(struct connman_device *device)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+ GSList *key_list = NULL;
+ GSList *list;
+
+ if (bluetooth_networks == NULL)
+ return;
+
+ g_hash_table_iter_init(&iter, bluetooth_networks);
+
+ while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+ struct connman_network *network = value;
+
+ if (connman_network_get_device(network) != device)
+ continue;
+
+ key_list = g_slist_append(key_list, key);
+ }
+
+ for (list = key_list; list != NULL; list = list->next) {
+ const char *network_path = list->data;
+
+ g_hash_table_remove(bluetooth_networks, network_path);
+ }
+
+ g_slist_free(key_list);
+}
+
static void adapter_properties_reply(DBusPendingCall *call, void *user_data)
{
char *path = user_data;
if (powered == TRUE)
check_networks(device, &networks);
+ else
+ remove_device_networks(device);
done:
dbus_message_unref(reply);
DBG("");
+ remove_device_networks(device);
+
connman_device_unregister(device);
connman_device_unref(device);
}
+static void remove_network(gpointer data)
+{
+ struct connman_network *network = data;
+ struct connman_device *device;
+
+ DBG("network %p", network);
+
+ device = connman_network_get_device(network);
+ if (device != NULL)
+ connman_device_remove_network(device, network);
+
+ connman_network_unref(network);
+}
+
static void bluetooth_connect(DBusConnection *connection, void *user_data)
{
DBusMessage *message;
g_free, unregister_device);
bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
+ g_free, remove_network);
message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS);
return;
g_hash_table_destroy(bluetooth_networks);
+ bluetooth_networks = NULL;
g_hash_table_destroy(bluetooth_devices);
bluetooth_devices = NULL;
}
static void server_register_reply(DBusPendingCall *call, void *user_data)
{
+ struct connman_technology *technology = user_data;
DBusError error;
DBusMessage *reply;
dbus_message_unref(reply);
dbus_pending_call_unref(call);
+ connman_technology_tethering_notify(technology, TRUE);
}
+static void server_unregister_reply(DBusPendingCall *call, void *user_data)
+{
+ struct connman_technology *technology = user_data;
+ DBusError error;
+ DBusMessage *reply;
+
+ DBG("");
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply) == TRUE) {
+ connman_error("%s", error.message);
+ dbus_error_free(&error);
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+ }
+
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+
+ connman_technology_tethering_notify(technology, FALSE);
+}
+
+
static void server_register(const char *path, const char *uuid,
+ struct connman_technology *technology,
const char *bridge, connman_bool_t enabled)
{
DBusMessage *message;
return;
}
- dbus_pending_call_set_notify(call, server_register_reply,
- g_strdup(path), g_free);
+ if (enabled == TRUE)
+ dbus_pending_call_set_notify(call, server_register_reply,
+ technology, NULL);
+ else
+ dbus_pending_call_set_notify(call, server_unregister_reply,
+ technology, NULL);
dbus_message_unref(message);
}
-static void enable_nap(gpointer key, gpointer value,
- gpointer user_data)
+struct tethering_info {
+ struct connman_technology *technology;
+ const char *bridge;
+};
+
+static void enable_nap(gpointer key, gpointer value, gpointer user_data)
{
+ struct tethering_info *info = user_data;
struct connman_device *device = value;
- const char *bridge = user_data;
const char *path;
+ DBG("");
+
path = connman_device_get_string(device, "Path");
- server_register(path, "nap", bridge, TRUE);
+ server_register(path, "nap", info->technology, info->bridge, TRUE);
}
-static void disable_nap(gpointer key, gpointer value,
- gpointer user_data)
+static void disable_nap(gpointer key, gpointer value, gpointer user_data)
{
+ struct tethering_info *info = user_data;
struct connman_device *device = value;
- const char *bridge = user_data;
const char *path;
+ DBG("");
+
path = connman_device_get_string(device, "Path");
- server_register(path, "nap", bridge, FALSE);
+ server_register(path, "nap", info->technology, info->bridge, FALSE);
}
static int tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
const char *bridge, connman_bool_t enabled)
{
- char *bridge_name = g_strdup(bridge);
+ struct tethering_info info = {
+ .technology = technology,
+ .bridge = bridge,
+ };
DBG("bridge %s", bridge);
- if (bridge_name == NULL)
- return -ENOMEM;
-
if (enabled)
- g_hash_table_foreach(bluetooth_devices,
- enable_nap, bridge_name);
+ g_hash_table_foreach(bluetooth_devices, enable_nap, &info);
else
- g_hash_table_foreach(bluetooth_devices,
- disable_nap, bridge_name);
-
- g_free(bridge_name);
+ g_hash_table_foreach(bluetooth_devices, disable_nap, &info);
return 0;
}
if (err < 0) {
connman_device_driver_unregister(&bluetooth_driver);
connman_network_driver_unregister(&pan_driver);
- return err;
+ goto remove;
}
return 0;