From cd9553812a30cdbb7d30731d84cc90a8d4463156 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 3 Jul 2010 10:21:52 +0200 Subject: [PATCH] Add initial bits and pieces for Tethering support --- Makefile.am | 5 ++- doc/manager-api.txt | 7 ++++ src/connman.h | 7 ++++ src/main.c | 2 + src/manager.c | 20 ++++++++- src/notifier.c | 5 +++ src/tethering.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ test/test-manager | 2 +- 8 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 src/tethering.c diff --git a/Makefile.am b/Makefile.am index 41fffae..ea94852 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,7 +54,7 @@ src_connmand_SOURCES = $(gdbus_sources) $(builtin_sources) \ src/utsname.c src/timeserver.c src/rfkill.c \ src/wifi.c src/storage.c src/dbus.c src/config.c \ src/technology.c src/counter.c src/location.c \ - src/session.c + src/session.c src/tethering.c if UDEV src_connmand_SOURCES += src/udev.c @@ -146,7 +146,8 @@ test_scripts = test/get-state test/list-profiles test/list-services \ test/connect-vpn test/disconnect-vpn test/list-providers \ test/monitor-manager test/test-counter test/set-ip-method \ test/set-nameservers test/set-domains test/find-service \ - test/get-services + test/get-services \ + test/enable-tethering test/disable-tethering if TEST testdir = $(pkglibdir)/test diff --git a/doc/manager-api.txt b/doc/manager-api.txt index dff2e14..40dac01 100644 --- a/doc/manager-api.txt +++ b/doc/manager-api.txt @@ -221,6 +221,13 @@ Properties string State [readonly] the limited usage of WiFi or Bluetooth devices might be allowed in some situations. + boolean Tethering [readwrite] + + This option allows to enable or disable the support + for tethering. When tethering is enabled then the + default service is bridged to all client where + connection sharing is supported. + object ActiveProfile [readwrite] Object path of the current active profile. diff --git a/src/connman.h b/src/connman.h index 1fdada3..19ced9d 100644 --- a/src/connman.h +++ b/src/connman.h @@ -390,6 +390,13 @@ int __connman_profile_add_network(struct connman_network *network); int __connman_profile_update_network(struct connman_network *network); 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); +void __connman_tethering_update_interface(const char *interface); + #include int __connman_service_init(void); diff --git a/src/main.c b/src/main.c index ac1be83..a01f2fe 100644 --- a/src/main.c +++ b/src/main.c @@ -219,6 +219,7 @@ int main(int argc, char *argv[]) __connman_element_init(option_device, option_nodevice); __connman_agent_init(); + __connman_tethering_init(); __connman_counter_init(); __connman_manager_init(option_compat); __connman_profile_init(); @@ -265,6 +266,7 @@ int main(int argc, char *argv[]) __connman_manager_cleanup(); __connman_counter_cleanup(); __connman_agent_cleanup(); + __connman_tethering_cleanup(); __connman_element_cleanup(); __connman_storage_cleanup(); diff --git a/src/manager.c b/src/manager.c index 22e263a..514cd1e 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; + connman_bool_t offlinemode, tethering; const char *str; DBG("conn %p", conn); @@ -71,6 +71,10 @@ 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", @@ -126,6 +130,20 @@ static DBusMessage *set_property(DBusConnection *conn, __connman_profile_set_offlinemode(offlinemode); __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/notifier.c b/src/notifier.c index 95794ac..7871ffb 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -362,10 +362,15 @@ static void technology_default(enum connman_service_type type) void __connman_notifier_default_changed(struct connman_service *service) { enum connman_service_type type = connman_service_get_type(service); + char *interface; GSList *list; technology_default(type); + interface = connman_service_get_interface(service); + __connman_tethering_update_interface(interface); + g_free(interface); + for (list = notifier_list; list; list = list->next) { struct connman_notifier *notifier = list->data; diff --git a/src/tethering.c b/src/tethering.c new file mode 100644 index 0000000..415d4bc --- /dev/null +++ b/src/tethering.c @@ -0,0 +1,115 @@ +/* + * + * Connection Manager + * + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "connman.h" + +#define BRIDGE_NAME "tether" + +static connman_bool_t tethering_status = FALSE; + +connman_bool_t __connman_tethering_get_status(void) +{ + return tethering_status; +} + +static int create_bridge(const char *name) +{ + int sk, err; + + DBG("name %s", name); + + sk = socket(AF_INET, SOCK_STREAM, 0); + if (sk < 0) + return -EOPNOTSUPP; + + err = ioctl(sk, SIOCBRADDBR, name); + + close(sk); + + if (err < 0) + return -EOPNOTSUPP; + + return 0; +} + +static int remove_bridge(const char *name) +{ + int sk, err; + + DBG("name %s", name); + + sk = socket(AF_INET, SOCK_STREAM, 0); + if (sk < 0) + return -EOPNOTSUPP; + + err = ioctl(sk, SIOCBRDELBR, name); + + close(sk); + + if (err < 0) + return -EOPNOTSUPP; + + return 0; +} + +int __connman_tethering_set_status(connman_bool_t status) +{ + if (status == tethering_status) + return -EALREADY; + + if (status == TRUE) + create_bridge(BRIDGE_NAME); + else + remove_bridge(BRIDGE_NAME); + + tethering_status = status; + + return 0; +} + +void __connman_tethering_update_interface(const char *interface) +{ + DBG("interface %s", interface); +} + +int __connman_tethering_init(void) +{ + DBG(""); + + return 0; +} + +void __connman_tethering_cleanup(void) +{ + DBG(""); + + if (tethering_status == TRUE) + remove_bridge(BRIDGE_NAME); +} diff --git a/test/test-manager b/test/test-manager index 6f9c200..e2d72d1 100755 --- a/test/test-manager +++ b/test/test-manager @@ -87,7 +87,7 @@ for key in properties.keys(): for val in properties[key]: list = list + val + " " print " [ %s]" % (list) - elif key in ["OfflineMode"]: + elif key in ["OfflineMode", "Tethering"]: print "%s" % (key) if properties[key] == dbus.Boolean(1): print " true" -- 2.7.4