summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am5
-rw-r--r--doc/manager-api.txt7
-rw-r--r--src/connman.h7
-rw-r--r--src/main.c2
-rw-r--r--src/manager.c20
-rw-r--r--src/notifier.c5
-rw-r--r--src/tethering.c115
-rwxr-xr-xtest/test-manager2
8 files changed, 159 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am
index 41fffae5..ea948521 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 dff2e149..40dac019 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 1fdada37..19ced9d1 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 <connman/service.h>
int __connman_service_init(void);
diff --git a/src/main.c b/src/main.c
index ac1be834..a01f2fec 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 22e263a4..514cd1eb 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 95794ac1..7871ffb8 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 00000000..415d4bc5
--- /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 <config.h>
+#endif
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+
+#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 6f9c2004..e2d72d11 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"