+struct tethering_info {
+ struct connman_technology *technology;
+ char *bridge;
+ bool enable;
+};
+
+static void tethering_free(void *user_data)
+{
+ struct tethering_info *tethering = user_data;
+
+ g_free(tethering->bridge);
+ g_free(tethering);
+}
+
+static void tethering_create_cb(DBusMessage *message, void *user_data)
+{
+ struct tethering_info *tethering = user_data;
+
+ if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) {
+ const char *dbus_error = dbus_message_get_error_name(message);
+
+ DBG("%s tethering failed: %s",
+ tethering->enable ? "enable" : "disable",
+ dbus_error);
+ return;
+ }
+
+ DBG("bridge %s %s", tethering->bridge, tethering->enable ?
+ "enabled": "disabled");
+
+ if (tethering->technology)
+ connman_technology_tethering_notify(tethering->technology,
+ tethering->enable);
+}
+
+static void tethering_append(DBusMessageIter *iter, void *user_data)
+{
+ struct tethering_info *tethering = user_data;
+ const char *nap = "nap";
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &nap);
+ if (tethering->enable)
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
+ &tethering->bridge);
+}
+
+static bool tethering_create(const char *path,
+ struct connman_technology *technology, const char *bridge,
+ bool enabled)
+{
+ struct tethering_info *tethering = g_new0(struct tethering_info, 1);
+ GDBusProxy *proxy;
+ const char *method;
+ bool result;
+
+ DBG("path %s bridge %s", path, bridge);
+
+ if (!bridge) {
+ g_free(tethering);
+ return false;
+ }
+
+ proxy = g_dbus_proxy_new(client, path, "org.bluez.NetworkServer1");
+ if (!proxy) {
+ g_free(tethering);
+ return false;
+ }
+
+ tethering->technology = technology;
+ tethering->bridge = g_strdup(bridge);
+ tethering->enable = enabled;
+
+ if (tethering->enable)
+ method = "Register";
+ else
+ method = "Unregister";
+
+ result = g_dbus_proxy_method_call(proxy, method, tethering_append,
+ tethering_create_cb, tethering, tethering_free);
+
+ g_dbus_proxy_unref(proxy);
+
+ return result;
+}
+