summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/technology.h1
-rw-r--r--plugins/bluetooth.c1
-rw-r--r--plugins/ethernet.c1
-rw-r--r--src/connman.h5
-rw-r--r--src/manager.c20
-rw-r--r--src/technology.c140
-rw-r--r--src/tethering.c32
7 files changed, 127 insertions, 73 deletions
diff --git a/include/technology.h b/include/technology.h
index ad6d43e9..39fcbbb1 100644
--- a/include/technology.h
+++ b/include/technology.h
@@ -54,6 +54,7 @@ struct connman_technology_driver {
void (*remove_interface) (struct connman_technology *technology,
int index);
int (*set_tethering) (struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
const char *bridge, connman_bool_t enabled);
int (*set_regdom) (struct connman_technology *technology,
const char *alpha2);
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 985f0e64..8c8840f8 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -1080,6 +1080,7 @@ static void disable_nap(gpointer key, gpointer value, gpointer user_data)
}
static int tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
const char *bridge, connman_bool_t enabled)
{
struct tethering_info info = {
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 71dff3f3..50442fcd 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -259,6 +259,7 @@ static void disable_tethering(struct connman_technology *technology,
}
static int tech_set_tethering(struct connman_technology *technology,
+ const char *identifier, const char *passphrase,
const char *bridge, connman_bool_t enabled)
{
DBG("bridge %s enabled %d", bridge, enabled);
diff --git a/src/connman.h b/src/connman.h
index bf31b62b..992d5339 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -313,8 +313,6 @@ void __connman_technology_add_interface(enum connman_service_type type,
int index, const char *name, const char *ident);
void __connman_technology_remove_interface(enum connman_service_type type,
int index, const char *name, const char *ident);
-int __connman_technology_enable_tethering(const char *bridge);
-int __connman_technology_disable_tethering(const char *bridge);
connman_bool_t __connman_technology_get_blocked(enum connman_service_type type);
@@ -417,8 +415,7 @@ int __connman_profile_remove_network(struct connman_network *network);
int __connman_tethering_init(void);
void __connman_tethering_cleanup(void);
-connman_bool_t __connman_tethering_get_status(void);
-int __connman_tethering_set_status(connman_bool_t status);
+const char *__connman_tethering_get_bridge(void);
void __connman_tethering_update_interface(const char *interface);
void __connman_tethering_set_enabled(void);
void __connman_tethering_set_disabled(void);
diff --git a/src/manager.c b/src/manager.c
index 9705b055..0a11f5da 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -32,7 +32,7 @@ static DBusMessage *get_properties(DBusConnection *conn,
{
DBusMessage *reply;
DBusMessageIter array, dict;
- connman_bool_t offlinemode, tethering;
+ connman_bool_t offlinemode;
const char *str;
DBG("conn %p", conn);
@@ -65,10 +65,6 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_basic(&dict, "OfflineMode",
DBUS_TYPE_BOOLEAN, &offlinemode);
- tethering = __connman_tethering_get_status();
- connman_dbus_dict_append_basic(&dict, "Tethering",
- DBUS_TYPE_BOOLEAN, &tethering);
-
connman_dbus_dict_append_array(&dict, "AvailableTechnologies",
DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL);
connman_dbus_dict_append_array(&dict, "EnabledTechnologies",
@@ -120,20 +116,6 @@ static DBusMessage *set_property(DBusConnection *conn,
__connman_profile_set_offlinemode(offlinemode, TRUE);
__connman_profile_save_default();
- } else if (g_str_equal(name, "Tethering") == TRUE) {
- connman_bool_t tethering;
-
- if (type != DBUS_TYPE_BOOLEAN)
- return __connman_error_invalid_arguments(msg);
-
- dbus_message_iter_get_basic(&value, &tethering);
-
- if (__connman_tethering_set_status(tethering) < 0)
- return __connman_error_invalid_arguments(msg);
-
- connman_dbus_property_changed_basic(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "Tethering",
- DBUS_TYPE_BOOLEAN, &tethering);
} else if (g_str_equal(name, "ActiveProfile") == TRUE) {
const char *str;
diff --git a/src/technology.c b/src/technology.c
index ff1cf782..7d89b2ef 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -23,6 +23,8 @@
#include <config.h>
#endif
+#include <string.h>
+
#include <gdbus.h>
#include "connman.h"
@@ -60,6 +62,10 @@ struct connman_technology {
gint blocked;
char *regdom;
+ connman_bool_t tethering;
+ char *tethering_ident;
+ char *tethering_passphrase;
+
struct connman_technology_driver *driver;
void *driver_data;
};
@@ -208,43 +214,51 @@ void __connman_technology_remove_interface(enum connman_service_type type,
}
}
+static void tethering_changed(struct connman_technology *technology)
+{
+ connman_bool_t tethering = technology->tethering;
+
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
+ DBUS_TYPE_BOOLEAN, &tethering);
+}
+
void connman_technology_tethering_notify(struct connman_technology *technology,
connman_bool_t enabled)
{
DBG("technology %p enabled %u", technology, enabled);
+ if (technology->tethering == enabled)
+ return;
+
+ technology->tethering = enabled;
+
+ tethering_changed(technology);
+
if (enabled == TRUE)
__connman_tethering_set_enabled();
else
__connman_tethering_set_disabled();
}
-static int set_tethering(const char *bridge, connman_bool_t enabled)
+static int set_tethering(struct connman_technology *technology,
+ const char *bridge, connman_bool_t enabled)
{
- GSList *list;
+ const char *ident, *passphrase;
- for (list = technology_list; list; list = list->next) {
- struct connman_technology *technology = list->data;
+ ident = technology->tethering_ident;
+ passphrase = technology->tethering_passphrase;
- if (technology->driver == NULL)
- continue;
+ if (technology->driver == NULL ||
+ technology->driver->set_tethering == NULL)
+ return -EOPNOTSUPP;
- if (technology->driver->set_tethering)
- technology->driver->set_tethering(technology,
- bridge, enabled);
- }
-
- return 0;
-}
+ if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ (ident == NULL || passphrase == NULL))
+ return -EINVAL;
-int __connman_technology_enable_tethering(const char *bridge)
-{
- return set_tethering(bridge, TRUE);
-}
-
-int __connman_technology_disable_tethering(const char *bridge)
-{
- return set_tethering(bridge, FALSE);
+ return technology->driver->set_tethering(technology, ident, passphrase,
+ bridge, enabled);
}
void connman_technology_regdom_notify(struct connman_technology *technology,
@@ -395,13 +409,95 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &str);
+ connman_dbus_dict_append_basic(&dict, "Tethering",
+ DBUS_TYPE_BOOLEAN,
+ &technology->tethering);
+
+ if (technology->tethering_ident != NULL)
+ connman_dbus_dict_append_basic(&dict, "TetheringIdentifier",
+ DBUS_TYPE_STRING,
+ &technology->tethering_ident);
+
+ if (technology->tethering_passphrase != NULL)
+ connman_dbus_dict_append_basic(&dict, "TetheringPassphrase",
+ DBUS_TYPE_STRING,
+ &technology->tethering_passphrase);
+
connman_dbus_dict_close(&array, &dict);
return reply;
}
+static DBusMessage *set_property(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct connman_technology *technology = data;
+ DBusMessageIter iter, value;
+ const char *name;
+ int type;
+
+ DBG("conn %p", conn);
+
+ if (dbus_message_iter_init(msg, &iter) == FALSE)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&iter, &name);
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &value);
+
+ type = dbus_message_iter_get_arg_type(&value);
+
+ DBG("property %s", name);
+
+ if (g_str_equal(name, "Tethering") == TRUE) {
+ int err;
+ connman_bool_t tethering;
+ const char *bridge;
+
+ if (type != DBUS_TYPE_BOOLEAN)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&value, &tethering);
+
+ if (technology->tethering == tethering)
+ return __connman_error_in_progress(msg);
+
+ bridge = __connman_tethering_get_bridge();
+
+ err = set_tethering(technology, bridge, tethering);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ } else if (g_str_equal(name, "TetheringIdentifier") == TRUE) {
+ const char *str;
+
+ dbus_message_iter_get_basic(&value, &str);
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ technology->tethering_ident = g_strdup(str);
+ } else if (g_str_equal(name, "TetheringPassphrase") == TRUE) {
+ const char *str;
+
+ dbus_message_iter_get_basic(&value, &str);
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ if (strlen(str) < 8)
+ return __connman_error_invalid_arguments(msg);
+
+ technology->tethering_passphrase = g_strdup(str);
+ } else
+ return __connman_error_invalid_property(msg);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
static GDBusMethodTable technology_methods[] = {
- { "GetProperties", "", "a{sv}", get_properties },
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property },
{ },
};
diff --git a/src/tethering.c b/src/tethering.c
index d069fa31..2609ab02 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -41,17 +41,15 @@
#define BRIDGE_IP_END "192.168.218.200"
#define BRIDGE_DNS "8.8.8.8"
-static connman_bool_t tethering_status = FALSE;
static char *default_interface = NULL;
static volatile gint tethering_enabled;
static GDHCPServer *tethering_dhcp_server = NULL;
-connman_bool_t __connman_tethering_get_status(void)
+const char *__connman_tethering_get_bridge(void)
{
- return tethering_status;
+ return BRIDGE_NAME;
}
-
static void dhcp_server_debug(const char *str, void *data)
{
connman_info("%s: %s\n", (const char *) data, str);
@@ -291,9 +289,6 @@ void __connman_tethering_set_enabled(void)
{
int err;
- if (tethering_status == FALSE)
- return;
-
DBG("enabled %d", tethering_enabled + 1);
if (g_atomic_int_exchange_and_add(&tethering_enabled, 1) == 0) {
@@ -326,9 +321,6 @@ void __connman_tethering_set_enabled(void)
void __connman_tethering_set_disabled(void)
{
- if (tethering_status == TRUE)
- return;
-
DBG("enabled %d", tethering_enabled - 1);
if (g_atomic_int_dec_and_test(&tethering_enabled) == TRUE) {
@@ -344,21 +336,6 @@ void __connman_tethering_set_disabled(void)
}
}
-int __connman_tethering_set_status(connman_bool_t status)
-{
- if (status == tethering_status)
- return -EALREADY;
-
- tethering_status = status;
-
- if (status == TRUE)
- __connman_technology_enable_tethering(BRIDGE_NAME);
- else
- __connman_technology_disable_tethering(BRIDGE_NAME);
-
- return 0;
-}
-
void __connman_tethering_update_interface(const char *interface)
{
DBG("interface %s", interface);
@@ -374,8 +351,7 @@ void __connman_tethering_update_interface(const char *interface)
default_interface = g_strdup(interface);
- if (tethering_status == FALSE ||
- !g_atomic_int_get(&tethering_enabled))
+ if (!g_atomic_int_get(&tethering_enabled))
return;
enable_nat(interface);
@@ -394,7 +370,7 @@ void __connman_tethering_cleanup(void)
{
DBG("");
- if (tethering_status == TRUE) {
+ if (g_atomic_int_get(&tethering_enabled)) {
if (tethering_dhcp_server)
dhcp_server_stop(tethering_dhcp_server);
disable_bridge(BRIDGE_NAME);