diff --git a/packages/network/connman/install b/packages/network/connman/install index ec8142f31c..c974009b79 100755 --- a/packages/network/connman/install +++ b/packages/network/connman/install @@ -32,7 +32,9 @@ mkdir -p $INSTALL/etc/connman cp $PKG_BUILD/src/main.conf $INSTALL/etc/connman sed -i $INSTALL/etc/connman/main.conf \ -e "s|^# BackgroundScanning.*|BackgroundScanning = true|g" \ - -e "s|^# PreferredTechnologies.*|PreferredTechnologies = ethernet,wifi,cellular|g" + -e "s|^# FallbackNameservers.*|FallbackNameservers = 8.8.8.8,8.8.4.4|g" \ + -e "s|^# PreferredTechnologies.*|PreferredTechnologies = ethernet,wifi,cellular|g" \ + -e "s|^# PersistentTetheringMode.*|PersistentTetheringMode = true|g" mkdir -p $INSTALL/etc/dbus-1/system.d cp $PKG_BUILD/src/connman.conf $INSTALL/etc/dbus-1/system.d diff --git a/packages/network/connman/patches/connman-101-Add_description_of_AllowEthernetTethering.patch b/packages/network/connman/patches/connman-101-Add_description_of_AllowEthernetTethering.patch new file mode 100644 index 0000000000..2fbc346d9a --- /dev/null +++ b/packages/network/connman/patches/connman-101-Add_description_of_AllowEthernetTethering.patch @@ -0,0 +1,27 @@ +From: Jukka Rissanen +Subject: [PATCH 2/6] conf: Add description of AllowEthernetTethering +Date: Tue, 23 Apr 2013 15:17:37 +0300 + +--- + src/main.conf | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/main.conf b/src/main.conf +index 2985613..a0608d4 100644 +--- a/src/main.conf ++++ b/src/main.conf +@@ -76,3 +76,12 @@ + # setting enabled applications will notice more network breaks than + # normal. Default value is false. + # SingleConnectedTechnology = false ++ ++# Allow ethernet technology devices to be used when tethering. ++# If this is set to true and if ethernet tethering is activated, ++# a DHCP server is started to ethernet interface. The ethernet tethered ++# device should never be connected to corporate and home networks as ++# the device might confuse other network devices and services. ++# This is a dangerous setting so the default value is false. ++# Do not activate this unless you really know what you are doing. ++# AllowEthernetTethering = false +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-102-Add_support_for_AllowEthernetTethering_configuration_variable.patch b/packages/network/connman/patches/connman-102-Add_support_for_AllowEthernetTethering_configuration_variable.patch new file mode 100644 index 0000000000..5be2ef7003 --- /dev/null +++ b/packages/network/connman/patches/connman-102-Add_support_for_AllowEthernetTethering_configuration_variable.patch @@ -0,0 +1,72 @@ +From: Jukka Rissanen +Subject: [PATCH 3/6] main: Add support for AllowEthernetTethering configuration variable +Date: Tue, 23 Apr 2013 15:17:38 +0300 + +--- + +rc/main.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/main.c b/src/main.c +index a76ec3b..016e52d 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -70,6 +70,7 @@ static struct { + char **blacklisted_interfaces; + connman_bool_t allow_hostname_updates; + connman_bool_t single_tech; ++ connman_bool_t allow_ethernet_tethering; + } connman_settings = { + .bg_scan = TRUE, + .pref_timeservers = NULL, +@@ -81,6 +82,7 @@ static struct { + .blacklisted_interfaces = NULL, + .allow_hostname_updates = TRUE, + .single_tech = FALSE, ++ .allow_ethernet_tethering = FALSE, + }; + + #define CONF_BG_SCAN "BackgroundScanning" +@@ -93,6 +95,7 @@ static struct { + #define CONF_BLACKLISTED_INTERFACES "NetworkInterfaceBlacklist" + #define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates" + #define CONF_SINGLE_TECH "SingleConnectedTechnology" ++#define CONF_ALLOW_ETHERNET_TETHERING "AllowEthernetTethering" + + static const char *supported_options[] = { + CONF_BG_SCAN, +@@ -105,6 +108,7 @@ static const char *supported_options[] = { + CONF_BLACKLISTED_INTERFACES, + CONF_ALLOW_HOSTNAME_UPDATES, + CONF_SINGLE_TECH, ++ CONF_ALLOW_ETHERNET_TETHERING, + NULL + }; + +@@ -327,6 +331,14 @@ static void parse_config(GKeyFile *config) + connman_settings.single_tech = boolean; + + g_clear_error(&error); ++ ++ boolean = g_key_file_get_boolean(config, "General", ++ CONF_ALLOW_ETHERNET_TETHERING, ++ &error); ++ if (error == NULL) ++ connman_settings.allow_ethernet_tethering = boolean; ++ ++ g_clear_error(&error); + } + + static int config_init(const char *file) +@@ -498,6 +510,9 @@ connman_bool_t connman_setting_get_bool(const char *key) + if (g_str_equal(key, CONF_SINGLE_TECH) == TRUE) + return connman_settings.single_tech; + ++ if (g_str_equal(key, CONF_ALLOW_ETHERNET_TETHERING) == TRUE) ++ return connman_settings.allow_ethernet_tethering; ++ + return FALSE; + } + +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-103-Add_support_functions_needed_by_ethernet_tethering.patch b/packages/network/connman/patches/connman-103-Add_support_functions_needed_by_ethernet_tethering.patch new file mode 100644 index 0000000000..1259b81126 --- /dev/null +++ b/packages/network/connman/patches/connman-103-Add_support_functions_needed_by_ethernet_tethering.patch @@ -0,0 +1,86 @@ +From: Jukka Rissanen +Subject: [PATCH 4/6] device: Add support functions needed by ethernet tethering +Date: Tue, 23 Apr 2013 15:17:39 +0300 + +--- + include/device.h | 3 +++ + src/device.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+) + +diff --git a/include/device.h b/include/device.h +index b372821..3382575 100644 +--- a/include/device.h ++++ b/include/device.h +@@ -113,6 +113,9 @@ int connman_device_set_regdom(struct connman_device *device, + void connman_device_regdom_notify(struct connman_device *device, + int result, const char *alpha2); + struct connman_device *connman_device_create_from_index(int index); ++struct connman_device *connman_device_find_by_index(int index); ++int connman_device_disconnect_service(struct connman_device *device); ++int connman_device_reconnect_service(struct connman_device *device); + + struct connman_device_driver { + const char *name; +diff --git a/src/device.c b/src/device.c +index 2e0dbdc..5feeee1 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -647,6 +647,36 @@ int __connman_device_disconnect(struct connman_device *device) + return 0; + } + ++int connman_device_disconnect_service(struct connman_device *device) ++{ ++ DBG("device %p", device); ++ ++ device->reconnect = FALSE; ++ ++ if (device->network) { ++ struct connman_service *service = ++ connman_service_lookup_from_network(device->network); ++ ++ if (service != NULL) ++ __connman_service_disconnect(service); ++ else ++ connman_network_set_connected(device->network, FALSE); ++ } ++ ++ return 0; ++} ++ ++int connman_device_reconnect_service(struct connman_device *device) ++{ ++ DBG("device %p", device); ++ ++ device->reconnect = TRUE; ++ ++ __connman_service_auto_connect(); ++ ++ return 0; ++} ++ + static void mark_network_available(gpointer key, gpointer value, + gpointer user_data) + { +@@ -1035,6 +1065,19 @@ struct connman_device *__connman_device_find_device( + return NULL; + } + ++struct connman_device *connman_device_find_by_index(int index) ++{ ++ GSList *list; ++ ++ for (list = device_list; list != NULL; list = list->next) { ++ struct connman_device *device = list->data; ++ if (device->index == index) ++ return device; ++ } ++ ++ return NULL; ++} ++ + /** + * connman_device_set_regdom + * @device: device structure +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-104-Interface_was_added_to_technology_too_early.patch b/packages/network/connman/patches/connman-104-Interface_was_added_to_technology_too_early.patch new file mode 100644 index 0000000000..efc02dac64 --- /dev/null +++ b/packages/network/connman/patches/connman-104-Interface_was_added_to_technology_too_early.patch @@ -0,0 +1,49 @@ +The __connman_technology_add_interface() needs to be called +after we have created the technology which is done by rtnl->newlink() +callback. If this is done the old way, the ethernet devices +will not get their interfaces set properly. +--- + src/rtnl.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/rtnl.c b/src/rtnl.c +index ef7f343..e5fab88 100644 +--- a/src/rtnl.c ++++ b/src/rtnl.c +@@ -406,6 +406,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags, + unsigned int mtu = 0; + char ident[13], str[18]; + GSList *list; ++ connman_bool_t add_interface = FALSE; + + memset(&stats, 0, sizeof(stats)); + if (extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, +@@ -461,8 +462,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags, + if (type == ARPHRD_ETHER) + read_uevent(interface); + +- __connman_technology_add_interface(interface->service_type, +- interface->index, interface->name, interface->ident); ++ add_interface = TRUE; + } + + for (list = rtnl_list; list; list = list->next) { +@@ -472,6 +472,16 @@ static void process_newlink(unsigned short type, int index, unsigned flags, + rtnl->newlink(type, index, flags, change); + } + ++ /* ++ * The interface needs to be added after the newlink call. ++ * The newlink will create the technology when needed and ++ * __connman_technology_add_interface() expects the ++ * technology to be there already. ++ */ ++ if (add_interface == TRUE) ++ __connman_technology_add_interface(interface->service_type, ++ interface->index, interface->name, interface->ident); ++ + for (list = watch_list; list; list = list->next) { + struct watch_data *watch = list->data; + +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-105-Add_tethering_support.patch b/packages/network/connman/patches/connman-105-Add_tethering_support.patch new file mode 100644 index 0000000000..7ac7ee7918 --- /dev/null +++ b/packages/network/connman/patches/connman-105-Add_tethering_support.patch @@ -0,0 +1,140 @@ +From: Jukka Rissanen +Subject: [PATCH 5/6] ethernet: Add tethering support +Date: Tue, 23 Apr 2013 15:17:40 +0300 + +ns/ethernet.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 100 insertions(+), 1 deletion(-) + +diff --git a/plugins/ethernet.c b/plugins/ethernet.c +index 6a20eb2..ac5033f 100644 +--- a/plugins/ethernet.c ++++ b/plugins/ethernet.c +@@ -39,6 +39,9 @@ + #include + #include + #include ++#include ++ ++static connman_bool_t eth_tethering = FALSE; + + struct ethernet_data { + int index; +@@ -107,7 +110,13 @@ static void add_network(struct connman_device *device, + return; + } + +- connman_network_set_group(network, "cable"); ++ if (eth_tethering == FALSE) ++ /* ++ * Prevent service from starting the reconnect ++ * procedure as we do not want the DHCP client ++ * to run when tethering. ++ */ ++ connman_network_set_group(network, "cable"); + + ethernet->network = network; + } +@@ -319,11 +328,101 @@ static void eth_remove(struct connman_technology *technology) + DBG(""); + } + ++static GList *eth_interface_list = NULL; ++ ++static void eth_add_interface(struct connman_technology *technology, ++ int index, const char *name, const char *ident) ++{ ++ DBG("index %d name %s ident %s", index, name, ident); ++ ++ if (g_list_find(eth_interface_list, ++ GINT_TO_POINTER((int) index)) != NULL) ++ return; ++ ++ eth_interface_list = g_list_prepend(eth_interface_list, ++ (GINT_TO_POINTER((int) index))); ++} ++ ++static void eth_remove_interface(struct connman_technology *technology, ++ int index) ++{ ++ DBG("index %d", index); ++ ++ eth_interface_list = g_list_remove(eth_interface_list, ++ GINT_TO_POINTER((int) index)); ++} ++ ++static void eth_enable_tethering(struct connman_technology *technology, ++ const char *bridge) ++{ ++ GList *list; ++ ++ for (list = eth_interface_list; list; list = list->next) { ++ int index = GPOINTER_TO_INT(list->data); ++ struct connman_device *device = ++ connman_device_find_by_index(index); ++ ++ if (device != NULL) ++ connman_device_disconnect_service(device); ++ ++ connman_technology_tethering_notify(technology, TRUE); ++ ++ connman_inet_ifup(index); ++ ++ connman_inet_add_to_bridge(index, bridge); ++ ++ eth_tethering = TRUE; ++ } ++} ++ ++static void eth_disable_tethering(struct connman_technology *technology, ++ const char *bridge) ++{ ++ GList *list; ++ ++ for (list = eth_interface_list; list; list = list->next) { ++ int index = GPOINTER_TO_INT(list->data); ++ struct connman_device *device = ++ connman_device_find_by_index(index); ++ ++ connman_inet_remove_from_bridge(index, bridge); ++ ++ connman_inet_ifdown(index); ++ ++ connman_technology_tethering_notify(technology, FALSE); ++ ++ if (device != NULL) ++ connman_device_reconnect_service(device); ++ ++ eth_tethering = FALSE; ++ } ++} ++ ++static int eth_set_tethering(struct connman_technology *technology, ++ const char *identifier, const char *passphrase, ++ const char *bridge, connman_bool_t enabled) ++{ ++ if (connman_setting_get_bool("AllowEthernetTethering") == FALSE) ++ return 0; ++ ++ DBG("bridge %s enabled %d", bridge, enabled); ++ ++ if (enabled) ++ eth_enable_tethering(technology, bridge); ++ else ++ eth_disable_tethering(technology, bridge); ++ ++ return 0; ++} ++ + static struct connman_technology_driver eth_driver = { + .name = "ethernet", + .type = CONNMAN_SERVICE_TYPE_ETHERNET, + .probe = eth_probe, + .remove = eth_remove, ++ .add_interface = eth_add_interface, ++ .remove_interface = eth_remove_interface, ++ .set_tethering = eth_set_tethering, + }; + + static int ethernet_init(void) +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-106-Check_if_ethernet_tethering_is_allowed.patch b/packages/network/connman/patches/connman-106-Check_if_ethernet_tethering_is_allowed.patch new file mode 100644 index 0000000000..39ec32fbac --- /dev/null +++ b/packages/network/connman/patches/connman-106-Check_if_ethernet_tethering_is_allowed.patch @@ -0,0 +1,30 @@ +From: Jukka Rissanen +Subject: [PATCH 6/6] technology: Check if ethernet tethering is allowed +Date: Tue, 23 Apr 2013 15:17:41 +0300 + +Return EOPNOTSUPP if user tries to activate ethernet tethering +and AllowEthernetTethering variable is not set in main.conf +--- + src/technology.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/technology.c b/src/technology.c +index f15fbd9..62950e7 100644 +--- a/src/technology.c ++++ b/src/technology.c +@@ -787,6 +787,13 @@ static DBusMessage *set_property(DBusConnection *conn, + if (type != DBUS_TYPE_BOOLEAN) + return __connman_error_invalid_arguments(msg); + ++ if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET && ++ connman_setting_get_bool("AllowEthernetTethering") ++ == FALSE) { ++ DBG("Ethernet tethering not allowed by config file"); ++ return __connman_error_not_supported(msg); ++ } ++ + dbus_message_iter_get_basic(&value, &tethering); + + if (technology->tethering == tethering) { +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-201-Add_description_of_StartTetheringAutomatically.patch b/packages/network/connman/patches/connman-201-Add_description_of_StartTetheringAutomatically.patch new file mode 100644 index 0000000000..371d0ad8fa --- /dev/null +++ b/packages/network/connman/patches/connman-201-Add_description_of_StartTetheringAutomatically.patch @@ -0,0 +1,23 @@ +From: Jukka Rissanen +Subject: [PATCH v2 1/3] conf: Add description of StartTetheringAutomatically +Date: Tue, 23 Apr 2013 15:17:43 +0300 + +--- + src/main.conf | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/main.conf b/src/main.conf +index a0608d4..7e509f7 100644 +--- a/src/main.conf ++++ b/src/main.conf +@@ -85,3 +85,8 @@ + # This is a dangerous setting so the default value is false. + # Do not activate this unless you really know what you are doing. + # AllowEthernetTethering = false ++ ++# Restore earlier tethering status when returning from offline mode, ++# re-enabling a technology, and after restarts and reboots. ++# Default value is false. ++# PersistentTetheringMode = false +-- +1.7.11.7 diff --git a/packages/network/connman/patches/connman-202-Add_support_for_StartTetheringAutomatically_configuration_variable.patch b/packages/network/connman/patches/connman-202-Add_support_for_StartTetheringAutomatically_configuration_variable.patch new file mode 100644 index 0000000000..e723d4d27f --- /dev/null +++ b/packages/network/connman/patches/connman-202-Add_support_for_StartTetheringAutomatically_configuration_variable.patch @@ -0,0 +1,71 @@ +From: Jukka Rissanen +Subject: [PATCH v2 2/3] main: Add support for StartTetheringAutomatically configuration variable +Date: Tue, 23 Apr 2013 15:17:44 +0300 + +--- + src/main.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 016e52d..5e738cf 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -71,6 +71,7 @@ static struct { + connman_bool_t allow_hostname_updates; + connman_bool_t single_tech; + connman_bool_t allow_ethernet_tethering; ++ connman_bool_t persistent_tethering_mode; + } connman_settings = { + .bg_scan = TRUE, + .pref_timeservers = NULL, +@@ -83,6 +84,7 @@ static struct { + .allow_hostname_updates = TRUE, + .single_tech = FALSE, + .allow_ethernet_tethering = FALSE, ++ .persistent_tethering_mode = FALSE, + }; + + #define CONF_BG_SCAN "BackgroundScanning" +@@ -96,6 +98,7 @@ static struct { + #define CONF_ALLOW_HOSTNAME_UPDATES "AllowHostnameUpdates" + #define CONF_SINGLE_TECH "SingleConnectedTechnology" + #define CONF_ALLOW_ETHERNET_TETHERING "AllowEthernetTethering" ++#define CONF_PERSISTENT_TETHERING_MODE "PersistentTetheringMode" + + static const char *supported_options[] = { + CONF_BG_SCAN, +@@ -109,6 +112,7 @@ static const char *supported_options[] = { + CONF_ALLOW_HOSTNAME_UPDATES, + CONF_SINGLE_TECH, + CONF_ALLOW_ETHERNET_TETHERING, ++ CONF_PERSISTENT_TETHERING_MODE, + NULL + }; + +@@ -339,6 +343,14 @@ static void parse_config(GKeyFile *config) + connman_settings.allow_ethernet_tethering = boolean; + + g_clear_error(&error); ++ ++ boolean = g_key_file_get_boolean(config, "General", ++ CONF_PERSISTENT_TETHERING_MODE, ++ &error); ++ if (error == NULL) ++ connman_settings.persistent_tethering_mode = boolean; ++ ++ g_clear_error(&error); + } + + static int config_init(const char *file) +@@ -513,6 +525,9 @@ connman_bool_t connman_setting_get_bool(const char *key) + if (g_str_equal(key, CONF_ALLOW_ETHERNET_TETHERING) == TRUE) + return connman_settings.allow_ethernet_tethering; + ++ if (g_str_equal(key, CONF_PERSISTENT_TETHERING_MODE) == TRUE) ++ return connman_settings.persistent_tethering_mode; ++ + return FALSE; + } + +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-203-Auto_start_tethering_if_enabled_and_configured.patch b/packages/network/connman/patches/connman-203-Auto_start_tethering_if_enabled_and_configured.patch new file mode 100644 index 0000000000..e21ada8e79 --- /dev/null +++ b/packages/network/connman/patches/connman-203-Auto_start_tethering_if_enabled_and_configured.patch @@ -0,0 +1,300 @@ +From: Jukka Rissanen +Subject: [PATCH v2 3/3] technology: Auto start tethering if enabled and configured +Date: Tue, 23 Apr 2013 15:17:45 +0300 + +If the user has enabled tethering autostart in main.conf, then +start tethering when technology is enabled. Tethering is only +auto activated if it was active when ConnMan was stopped. +If the user has enabled persistent tethering mode in main.conf, then +try to activate tethering when technology is re-enabled, or we are +returning from offline mode, or after the device has rebooted. +--- + src/technology.c | 185 +++++++++++++++++++++++++++++++++++-------------------- + 1 file changed, 119 insertions(+), 66 deletions(-) + +diff --git a/src/technology.c b/src/technology.c +index a6efac1..c80a553 100644 +--- a/src/technology.c ++++ b/src/technology.c +@@ -60,6 +60,10 @@ struct connman_technology { + connman_bool_t connected; + + connman_bool_t tethering; ++ connman_bool_t tethering_persistent; /* Tells the save status, needed ++ * as offline mode might set ++ * tethering OFF. ++ */ + char *tethering_ident; + char *tethering_passphrase; + +@@ -180,6 +184,69 @@ void connman_technology_driver_unregister(struct connman_technology_driver *driv + driver_list = g_slist_remove(driver_list, driver); + } + ++static const char *get_name(enum connman_service_type type) ++{ ++ switch (type) { ++ case CONNMAN_SERVICE_TYPE_UNKNOWN: ++ case CONNMAN_SERVICE_TYPE_SYSTEM: ++ case CONNMAN_SERVICE_TYPE_GPS: ++ case CONNMAN_SERVICE_TYPE_VPN: ++ case CONNMAN_SERVICE_TYPE_GADGET: ++ break; ++ case CONNMAN_SERVICE_TYPE_ETHERNET: ++ return "Wired"; ++ case CONNMAN_SERVICE_TYPE_WIFI: ++ return "WiFi"; ++ case CONNMAN_SERVICE_TYPE_BLUETOOTH: ++ return "Bluetooth"; ++ case CONNMAN_SERVICE_TYPE_CELLULAR: ++ return "Cellular"; ++ } ++ ++ return NULL; ++} ++ ++static void technology_save(struct connman_technology *technology) ++{ ++ GKeyFile *keyfile; ++ gchar *identifier; ++ ++ DBG("technology %p", technology); ++ ++ keyfile = __connman_storage_load_global(); ++ if (keyfile == NULL) ++ keyfile = g_key_file_new(); ++ ++ identifier = g_strdup_printf("%s", get_name(technology->type)); ++ if (identifier == NULL) ++ goto done; ++ ++ g_key_file_set_boolean(keyfile, identifier, "Enable", ++ technology->enable_persistent); ++ ++ g_key_file_set_boolean(keyfile, identifier, "Tethering", ++ technology->tethering_persistent); ++ ++ if (technology->tethering_ident != NULL) ++ g_key_file_set_string(keyfile, identifier, ++ "Tethering.Identifier", ++ technology->tethering_ident); ++ ++ if (technology->tethering_passphrase != NULL) ++ g_key_file_set_string(keyfile, identifier, ++ "Tethering.Passphrase", ++ technology->tethering_passphrase); ++ ++done: ++ g_free(identifier); ++ ++ __connman_storage_save_global(keyfile); ++ ++ g_key_file_free(keyfile); ++ ++ return; ++} ++ + static void tethering_changed(struct connman_technology *technology) + { + connman_bool_t tethering = technology->tethering; +@@ -187,6 +254,8 @@ static void tethering_changed(struct connman_technology *technology) + connman_dbus_property_changed_basic(technology->path, + CONNMAN_TECHNOLOGY_INTERFACE, "Tethering", + DBUS_TYPE_BOOLEAN, &tethering); ++ ++ technology_save(technology); + } + + void connman_technology_tethering_notify(struct connman_technology *technology, +@@ -199,7 +268,7 @@ void connman_technology_tethering_notify(struct connman_technology *technology, + if (technology->tethering == enabled) + return; + +- technology->tethering = enabled; ++ technology->tethering = enabled; + + tethering_changed(technology); + +@@ -361,72 +430,12 @@ static void free_rfkill(gpointer data) + g_free(rfkill); + } + +-static const char *get_name(enum connman_service_type type) +-{ +- switch (type) { +- case CONNMAN_SERVICE_TYPE_UNKNOWN: +- case CONNMAN_SERVICE_TYPE_SYSTEM: +- case CONNMAN_SERVICE_TYPE_GPS: +- case CONNMAN_SERVICE_TYPE_VPN: +- case CONNMAN_SERVICE_TYPE_GADGET: +- break; +- case CONNMAN_SERVICE_TYPE_ETHERNET: +- return "Wired"; +- case CONNMAN_SERVICE_TYPE_WIFI: +- return "WiFi"; +- case CONNMAN_SERVICE_TYPE_BLUETOOTH: +- return "Bluetooth"; +- case CONNMAN_SERVICE_TYPE_CELLULAR: +- return "Cellular"; +- } +- +- return NULL; +-} +- +-static void technology_save(struct connman_technology *technology) +-{ +- GKeyFile *keyfile; +- gchar *identifier; +- +- DBG("technology %p", technology); +- +- keyfile = __connman_storage_load_global(); +- if (keyfile == NULL) +- keyfile = g_key_file_new(); +- +- identifier = g_strdup_printf("%s", get_name(technology->type)); +- if (identifier == NULL) +- goto done; +- +- g_key_file_set_boolean(keyfile, identifier, "Enable", +- technology->enable_persistent); +- +- if (technology->tethering_ident != NULL) +- g_key_file_set_string(keyfile, identifier, +- "Tethering.Identifier", +- technology->tethering_ident); +- +- if (technology->tethering_passphrase != NULL) +- g_key_file_set_string(keyfile, identifier, +- "Tethering.Passphrase", +- technology->tethering_passphrase); +- +-done: +- g_free(identifier); +- +- __connman_storage_save_global(keyfile); +- +- g_key_file_free(keyfile); +- +- return; +-} +- + static void technology_load(struct connman_technology *technology) + { + GKeyFile *keyfile; + gchar *identifier; + GError *error = NULL; +- connman_bool_t enable; ++ connman_bool_t enable, need_saving = FALSE; + + DBG("technology %p", technology); + +@@ -454,10 +463,22 @@ static void technology_load(struct connman_technology *technology) + else + technology->enable_persistent = FALSE; + +- technology_save(technology); ++ need_saving = TRUE; + g_clear_error(&error); + } + ++ enable = g_key_file_get_boolean(keyfile, identifier, ++ "Tethering", &error); ++ if (error == NULL) ++ technology->tethering_persistent = enable; ++ else { ++ need_saving = TRUE; ++ g_clear_error(&error); ++ } ++ ++ if (need_saving == TRUE) ++ technology_save(technology); ++ + technology->tethering_ident = g_key_file_get_string(keyfile, + identifier, "Tethering.Identifier", NULL); + +@@ -678,6 +699,10 @@ static int technology_enable(struct connman_technology *technology) + if (technology->pending_reply != NULL) + return -EBUSY; + ++ if (connman_setting_get_bool("PersistentTetheringMode") == TRUE && ++ technology->tethering == TRUE) ++ set_tethering(technology, TRUE); ++ + if (technology->rfkill_driven == TRUE) + err = __connman_rfkill_block(technology->type, FALSE); + +@@ -807,6 +832,10 @@ static DBusMessage *set_property(DBusConnection *conn, + if (err < 0) + return __connman_error_failed(msg, -err); + ++ technology->tethering_persistent = tethering; ++ ++ technology_save(technology); ++ + } else if (g_str_equal(name, "TetheringIdentifier") == TRUE) { + const char *str; + +@@ -1233,10 +1262,10 @@ int __connman_technology_add_device(struct connman_device *device) + struct connman_technology *technology; + enum connman_service_type type; + +- DBG("device %p", device); +- + type = __connman_device_get_service_type(device); + ++ DBG("device %p type %s", device, get_name(type)); ++ + technology = technology_get(type); + if (technology == NULL) { + /* +@@ -1341,6 +1370,20 @@ static void powered_changed(struct connman_technology *technology) + DBUS_TYPE_BOOLEAN, &technology->enabled); + } + ++static void enable_tethering(struct connman_technology *technology) ++{ ++ int ret; ++ ++ if (connman_setting_get_bool("PersistentTetheringMode") != TRUE) ++ return; ++ ++ ret = set_tethering(technology, TRUE); ++ if (ret < 0 && ret != -EALREADY) ++ DBG("Cannot enable tethering yet for %s (%d/%s)", ++ get_name(technology->type), ++ -ret, strerror(-ret)); ++} ++ + static int technology_enabled(struct connman_technology *technology) + { + __sync_synchronize(); +@@ -1349,6 +1392,9 @@ static int technology_enabled(struct connman_technology *technology) + + technology->enabled = TRUE; + ++ if (technology->tethering_persistent == TRUE) ++ enable_tethering(technology); ++ + powered_changed(technology); + + return 0; +@@ -1362,8 +1408,15 @@ int __connman_technology_enabled(enum connman_service_type type) + if (technology == NULL) + return -ENXIO; + +- if (technology->rfkill_driven == TRUE) ++ DBG("technology %p type %s rfkill %d enabled %d", technology, ++ get_name(type), technology->rfkill_driven, ++ technology->enabled); ++ ++ if (technology->rfkill_driven == TRUE) { ++ if (technology->tethering_persistent == TRUE) ++ enable_tethering(technology); + return 0; ++ } + + return technology_enabled(technology); + } +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-301-Return_proper_return_code_if_listener_table_is_missing.patch b/packages/network/connman/patches/connman-301-Return_proper_return_code_if_listener_table_is_missing.patch new file mode 100644 index 0000000000..93bf29befd --- /dev/null +++ b/packages/network/connman/patches/connman-301-Return_proper_return_code_if_listener_table_is_missing.patch @@ -0,0 +1,23 @@ +The listener_table can be NULL if we have started connman with -r +option. Because we return <0 value to caller in this case, +the caller (like tethering code) has possibility to change how +its functionality (fall back to some other DNS servers). +--- + src/dnsproxy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/dnsproxy.c b/src/dnsproxy.c +index 52d67d4..8ed34a7 100644 +--- a/src/dnsproxy.c ++++ b/src/dnsproxy.c +@@ -3426,7 +3426,7 @@ int __connman_dnsproxy_add_listener(int index) + return -EINVAL; + + if (listener_table == NULL) +- return 0; ++ return -ENOENT; + + if (g_hash_table_lookup(listener_table, GINT_TO_POINTER(index)) != NULL) + return 0; +-- 1.7.11.7 + diff --git a/packages/network/connman/patches/connman-302-Use_fallback_nameservers_if_dnsproxy_is_not_in_use.patch b/packages/network/connman/patches/connman-302-Use_fallback_nameservers_if_dnsproxy_is_not_in_use.patch new file mode 100644 index 0000000000..51842f3da9 --- /dev/null +++ b/packages/network/connman/patches/connman-302-Use_fallback_nameservers_if_dnsproxy_is_not_in_use.patch @@ -0,0 +1,123 @@ +If user has disabled dnsproxy with -r option, then fallback to +user specified nameservers instead of using the Google DNS. +--- + src/tethering.c | 47 +++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 37 insertions(+), 10 deletions(-) + +diff --git a/src/tethering.c b/src/tethering.c +index bd79804..7042040 100644 +--- a/src/tethering.c ++++ b/src/tethering.c +@@ -49,12 +49,11 @@ + #endif + + #define BRIDGE_NAME "tether" +-#define BRIDGE_DNS "8.8.8.8" + + #define DEFAULT_MTU 1500 + +-#define PRIVATE_NETWORK_PRIMARY_DNS BRIDGE_DNS +-#define PRIVATE_NETWORK_SECONDARY_DNS "8.8.4.4" ++static char *private_network_primary_dns = NULL; ++static char *private_network_secondary_dns = NULL; + + static volatile int tethering_enabled; + static GDHCPServer *tethering_dhcp_server = NULL; +@@ -73,8 +72,8 @@ struct connman_private_network { + int index; + guint iface_watch; + struct connman_ippool *pool; +- const char *primary_dns; +- const char *secondary_dns; ++ char *primary_dns; ++ char *secondary_dns; + }; + + const char *__connman_tethering_get_bridge(void) +@@ -192,6 +191,7 @@ void __connman_tethering_set_enabled(void) + const char *end_ip; + const char *dns; + unsigned char prefixlen; ++ char **ns; + + DBG("enabled %d", tethering_enabled + 1); + +@@ -228,11 +228,28 @@ void __connman_tethering_set_enabled(void) + return; + } + ++ ns = connman_setting_get_string_list("FallbackNameservers"); ++ if (ns != NULL) { ++ if (ns[0] != NULL) { ++ g_free(private_network_primary_dns); ++ private_network_primary_dns = g_strdup(ns[0]); ++ } ++ if (ns[1] != NULL) { ++ g_free(private_network_secondary_dns); ++ private_network_secondary_dns = g_strdup(ns[1]); ++ } ++ ++ DBG("Fallback ns primary %s secondary %s", ++ private_network_primary_dns, ++ private_network_secondary_dns); ++ } ++ + dns = gateway; + if (__connman_dnsproxy_add_listener(index) < 0) { + connman_error("Can't add listener %s to DNS proxy", + BRIDGE_NAME); +- dns = BRIDGE_DNS; ++ dns = private_network_primary_dns; ++ DBG("Serving %s nameserver to clients", dns); + } + + tethering_dhcp_server = dhcp_server_start(BRIDGE_NAME, +@@ -278,6 +295,11 @@ void __connman_tethering_set_disabled(void) + + __connman_bridge_remove(BRIDGE_NAME); + ++ g_free(private_network_primary_dns); ++ private_network_primary_dns = NULL; ++ g_free(private_network_secondary_dns); ++ private_network_secondary_dns = NULL; ++ + DBG("tethering stopped"); + } + +@@ -329,9 +351,12 @@ static void setup_tun_interface(unsigned int flags, unsigned change, + DBUS_TYPE_STRING, &server_ip); + connman_dbus_dict_append_basic(&dict, "PeerIPv4", + DBUS_TYPE_STRING, &peer_ip); +- connman_dbus_dict_append_basic(&dict, "PrimaryDNS", ++ if (pn->primary_dns != NULL) ++ connman_dbus_dict_append_basic(&dict, "PrimaryDNS", + DBUS_TYPE_STRING, &pn->primary_dns); +- connman_dbus_dict_append_basic(&dict, "SecondaryDNS", ++ ++ if (pn->secondary_dns != NULL) ++ connman_dbus_dict_append_basic(&dict, "SecondaryDNS", + DBUS_TYPE_STRING, &pn->secondary_dns); + + connman_dbus_dict_close(&array, &dict); +@@ -367,6 +392,8 @@ static void remove_private_network(gpointer user_data) + g_free(pn->interface); + g_free(pn->owner); + g_free(pn->path); ++ g_free(pn->primary_dns); ++ g_free(pn->secondary_dns); + g_free(pn); + } + +@@ -447,8 +474,8 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner) + goto error; + } + +- pn->primary_dns = PRIVATE_NETWORK_PRIMARY_DNS; +- pn->secondary_dns = PRIVATE_NETWORK_SECONDARY_DNS; ++ pn->primary_dns = g_strdup(private_network_primary_dns); ++ pn->secondary_dns = g_strdup(private_network_secondary_dns); + + pn->iface_watch = connman_rtnl_add_newlink_watch(index, + setup_tun_interface, pn); +-- 1.7.11.7 +