From: Martin Xu <martin...@intel.com> --- include/device.h | 1 + include/service.h | 1 + plugins/ethernet.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/iospm.c | 1 + plugins/portal.c | 1 + src/detect.c | 1 + src/device.c | 12 +++++ src/element.c | 4 ++ src/inet.c | 2 + src/notifier.c | 7 +++ src/rtnl.c | 4 ++ src/service.c | 10 ++++ src/session.c | 1 + src/technology.c | 3 + 14 files changed, 177 insertions(+), 0 deletions(-)
diff --git a/include/device.h b/include/device.h index 31aa92b..c5e005d 100644 --- a/include/device.h +++ b/include/device.h @@ -43,6 +43,7 @@ enum connman_device_type { CONNMAN_DEVICE_TYPE_BLUETOOTH = 4, CONNMAN_DEVICE_TYPE_CELLULAR = 5, CONNMAN_DEVICE_TYPE_GPS = 6, + CONNMAN_DEVICE_TYPE_GADGET = 7, CONNMAN_DEVICE_TYPE_VENDOR = 10000, }; diff --git a/include/service.h b/include/service.h index 16d10f2..e67dd42 100644 --- a/include/service.h +++ b/include/service.h @@ -44,6 +44,7 @@ enum connman_service_type { CONNMAN_SERVICE_TYPE_CELLULAR = 6, CONNMAN_SERVICE_TYPE_GPS = 7, CONNMAN_SERVICE_TYPE_VPN = 8, + CONNMAN_SERVICE_TYPE_GADGET = 9, }; enum connman_service_mode { diff --git a/plugins/ethernet.c b/plugins/ethernet.c index 797fc7c..eaf1167 100644 --- a/plugins/ethernet.c +++ b/plugins/ethernet.c @@ -33,6 +33,7 @@ #include <glib.h> #define CONNMAN_API_SUBJECT_TO_CHANGE +#include <connman/technology.h> #include <connman/plugin.h> #include <connman/device.h> #include <connman/inet.h> @@ -201,6 +202,127 @@ static struct connman_device_driver ethernet_driver = { .disable = ethernet_disable, }; +static GHashTable *interface_hash = NULL; + +struct cdc_interface { + int index; + char *name; + char *ident; +}; + +static void free_interface(gpointer data) +{ + struct cdc_interface *interface = data; + + g_free(interface->ident); + g_free(interface->name); + g_free(interface); +} + +static void tech_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_hash_table_lookup(interface_hash, + GINT_TO_POINTER(index)) == NULL) { + struct cdc_interface *interface; + + interface = g_try_new0(struct cdc_interface, 1); + if (interface == NULL) + return; + interface->index = index; + interface->name = g_strdup(name); + interface->ident = g_strdup(ident); + g_hash_table_insert(interface_hash, + GINT_TO_POINTER(index), interface); + } +} + +static void tech_remove_interface(struct connman_technology *technology, + int index) +{ + DBG("index %d", index); + + g_hash_table_remove(interface_hash, GINT_TO_POINTER(index)); +} + +struct tethering_info { + struct connman_technology *technology; + const char *bridge; +}; + +static void enable_tethering(gpointer key, gpointer value, gpointer user_data) +{ + struct tethering_info *info = user_data; + struct cdc_interface *interface = value; + + DBG(""); + + connman_inet_ifup(interface->index); + + connman_technology_tethering_notify(info->technology, TRUE); + + connman_inet_add_to_bridge(interface->index, info->bridge); +} + +static void disable_tethering(gpointer key, gpointer value, gpointer user_data) +{ + struct tethering_info *info = user_data; + struct cdc_interface *interface = value; + + DBG(""); + + connman_inet_remove_from_bridge(interface->index, info->bridge); + + connman_inet_ifdown(interface->index); + + connman_technology_tethering_notify(info->technology, FALSE); +} + +static int tech_set_tethering(struct connman_technology *technology, + const char *bridge, connman_bool_t enabled) +{ + struct tethering_info info = { + .technology = technology, + .bridge = bridge, + }; + + DBG("bridge %s", bridge); + + if (enabled) + g_hash_table_foreach(interface_hash, enable_tethering, &info); + else + g_hash_table_foreach(interface_hash, disable_tethering, &info); + + return 0; +} + +static int tech_probe(struct connman_technology *technology) +{ + if (interface_hash == NULL) + interface_hash = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, free_interface); + + return 0; +} + +static void tech_remove(struct connman_technology *technology) +{ + g_hash_table_destroy(interface_hash); +} + +static struct connman_technology_driver tech_driver = { + .name = "cdc_ethernet", + .type = CONNMAN_SERVICE_TYPE_GADGET, + .probe = tech_probe, + .remove = tech_remove, + .add_interface = tech_add_interface, + .remove_interface = tech_remove_interface, + .set_tethering = tech_set_tethering, +}; + static int ethernet_init(void) { int err; @@ -215,6 +337,13 @@ static int ethernet_init(void) return err; } + err = connman_technology_driver_register(&tech_driver); + if (err < 0) { + connman_device_driver_unregister(ðernet_driver); + connman_network_driver_unregister(&cable_driver); + return err; + } + return 0; } diff --git a/plugins/iospm.c b/plugins/iospm.c index 20c9b46..a36e4aa 100644 --- a/plugins/iospm.c +++ b/plugins/iospm.c @@ -73,6 +73,7 @@ static void iospm_service_enabled(enum connman_service_type type, case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; case CONNMAN_SERVICE_TYPE_BLUETOOTH: send_indication(IOSPM_BLUETOOTH, enabled); diff --git a/plugins/portal.c b/plugins/portal.c index f1d5ce3..d4456f5 100644 --- a/plugins/portal.c +++ b/plugins/portal.c @@ -123,6 +123,7 @@ static int location_detect(struct connman_location *location) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return -EOPNOTSUPP; } diff --git a/src/detect.c b/src/detect.c index c27d2cc..39ab06a 100644 --- a/src/detect.c +++ b/src/detect.c @@ -63,6 +63,7 @@ static void detect_newlink(unsigned short type, int index, return; case CONNMAN_DEVICE_TYPE_ETHERNET: case CONNMAN_DEVICE_TYPE_WIFI: + case CONNMAN_DEVICE_TYPE_GADGET: break; } diff --git a/src/device.c b/src/device.c index 7f2b54f..b8110c4 100644 --- a/src/device.c +++ b/src/device.c @@ -124,6 +124,9 @@ static const char *type2description(enum connman_device_type type) return "GPS"; case CONNMAN_DEVICE_TYPE_CELLULAR: return "Cellular"; + case CONNMAN_DEVICE_TYPE_GADGET: + return "Gadget"; + } return NULL; @@ -147,6 +150,9 @@ static const char *type2string(enum connman_device_type type) return "gps"; case CONNMAN_DEVICE_TYPE_CELLULAR: return "cellular"; + case CONNMAN_DEVICE_TYPE_GADGET: + return "gadget"; + } return NULL; @@ -171,6 +177,9 @@ enum connman_service_type __connman_device_get_service_type(struct connman_devic return CONNMAN_SERVICE_TYPE_BLUETOOTH; case CONNMAN_DEVICE_TYPE_CELLULAR: return CONNMAN_SERVICE_TYPE_CELLULAR; + case CONNMAN_DEVICE_TYPE_GADGET: + return CONNMAN_SERVICE_TYPE_GADGET; + } return CONNMAN_SERVICE_TYPE_UNKNOWN; @@ -482,6 +491,9 @@ struct connman_device *connman_device_create(const char *node, case CONNMAN_DEVICE_TYPE_CELLULAR: device->scan_interval = 0; break; + case CONNMAN_DEVICE_TYPE_GADGET: + device->scan_interval = 0; + break; } device->networks = g_hash_table_new_full(g_str_hash, g_str_equal, diff --git a/src/element.c b/src/element.c index 5d74bda..a4230b7 100644 --- a/src/element.c +++ b/src/element.c @@ -205,6 +205,7 @@ struct connman_service *__connman_element_get_service(struct connman_element *el case CONNMAN_DEVICE_TYPE_UNKNOWN: case CONNMAN_DEVICE_TYPE_VENDOR: case CONNMAN_DEVICE_TYPE_GPS: + case CONNMAN_DEVICE_TYPE_GADGET: break; case CONNMAN_DEVICE_TYPE_ETHERNET: case CONNMAN_DEVICE_TYPE_WIFI: @@ -290,6 +291,7 @@ static gboolean request_scan(GNode *node, gpointer user_data) case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return FALSE; case CONNMAN_SERVICE_TYPE_WIFI: case CONNMAN_SERVICE_TYPE_WIMAX: @@ -334,6 +336,7 @@ static gboolean enable_technology(GNode *node, gpointer user_data) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return FALSE; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -386,6 +389,7 @@ static gboolean disable_technology(GNode *node, gpointer user_data) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return FALSE; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: diff --git a/src/inet.c b/src/inet.c index 82e3a82..38f5d20 100644 --- a/src/inet.c +++ b/src/inet.c @@ -470,6 +470,7 @@ struct connman_device *connman_inet_create_device(int index) g_free(devname); return NULL; case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: case CONNMAN_DEVICE_TYPE_WIFI: case CONNMAN_DEVICE_TYPE_WIMAX: name = index2ident(index, ""); @@ -493,6 +494,7 @@ struct connman_device *connman_inet_create_device(int index) case CONNMAN_DEVICE_TYPE_GPS: break; case CONNMAN_DEVICE_TYPE_ETHERNET: + case CONNMAN_DEVICE_TYPE_GADGET: ident = index2ident(index, NULL); break; case CONNMAN_DEVICE_TYPE_WIFI: diff --git a/src/notifier.c b/src/notifier.c index 7871ffb..bf6aaa1 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -223,6 +223,7 @@ void __connman_notifier_register(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -245,6 +246,7 @@ void __connman_notifier_unregister(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -267,6 +269,7 @@ void __connman_notifier_enable(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -289,6 +292,7 @@ void __connman_notifier_disable(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -311,6 +315,7 @@ void __connman_notifier_connect(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -333,6 +338,7 @@ void __connman_notifier_disconnect(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: @@ -413,6 +419,7 @@ static connman_bool_t technology_supported(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return FALSE; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIFI: diff --git a/src/rtnl.c b/src/rtnl.c index ceb98fc..c061731 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -175,6 +175,10 @@ static void read_uevent(struct interface_data *interface) } else if (strcmp(line + 8, "wimax") == 0) { interface->service_type = CONNMAN_SERVICE_TYPE_WIMAX; interface->device_type = CONNMAN_DEVICE_TYPE_WIMAX; + } else if (strcmp(line + 8, "gadget") == 0) { + interface->service_type = CONNMAN_SERVICE_TYPE_GADGET; + interface->device_type = CONNMAN_DEVICE_TYPE_GADGET; + } else { interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN; interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN; diff --git a/src/service.c b/src/service.c index b1842d6..7aa302b 100644 --- a/src/service.c +++ b/src/service.c @@ -172,6 +172,8 @@ const char *__connman_service_type2string(enum connman_service_type type) return "gps"; case CONNMAN_SERVICE_TYPE_VPN: return "vpn"; + case CONNMAN_SERVICE_TYPE_GADGET: + return "gadget"; } return NULL; @@ -668,6 +670,7 @@ static void passphrase_changed(struct connman_service *service) case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_WIFI: required = FALSE; @@ -719,6 +722,7 @@ static void apn_changed(struct connman_service *service) case CONNMAN_SERVICE_TYPE_WIFI: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return; case CONNMAN_SERVICE_TYPE_CELLULAR: break; @@ -1363,6 +1367,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited, 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_CELLULAR: connman_dbus_dict_append_basic(dict, "Roaming", @@ -2776,6 +2781,7 @@ static gint service_compare(gconstpointer a, gconstpointer b, case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; case CONNMAN_SERVICE_TYPE_WIFI: return 1; @@ -3188,6 +3194,7 @@ int __connman_service_connect(struct connman_service *service) case CONNMAN_SERVICE_TYPE_UNKNOWN: case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: + case CONNMAN_SERVICE_TYPE_GADGET: return -EINVAL; case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_WIMAX: @@ -4006,6 +4013,7 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne case CONNMAN_SERVICE_TYPE_BLUETOOTH: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: service->autoconnect = FALSE; break; case CONNMAN_SERVICE_TYPE_WIFI: @@ -4218,6 +4226,7 @@ static int service_load(struct connman_service *service) case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; case CONNMAN_SERVICE_TYPE_WIFI: if (service->name == NULL) { @@ -4415,6 +4424,7 @@ update: case CONNMAN_SERVICE_TYPE_ETHERNET: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; case CONNMAN_SERVICE_TYPE_WIFI: if (service->network) { diff --git a/src/session.c b/src/session.c index 9264c0c..49aed25 100644 --- a/src/session.c +++ b/src/session.c @@ -86,6 +86,7 @@ static char *service2bearer(enum connman_service_type type) case CONNMAN_SERVICE_TYPE_SYSTEM: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: return NULL; } diff --git a/src/technology.c b/src/technology.c index 98fcf8d..68137c7 100644 --- a/src/technology.c +++ b/src/technology.c @@ -120,6 +120,7 @@ void __connman_technology_add_interface(enum connman_service_type type, case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; } @@ -157,6 +158,7 @@ void __connman_technology_remove_interface(enum connman_service_type type, case CONNMAN_SERVICE_TYPE_CELLULAR: case CONNMAN_SERVICE_TYPE_GPS: case CONNMAN_SERVICE_TYPE_VPN: + case CONNMAN_SERVICE_TYPE_GADGET: break; } @@ -285,6 +287,7 @@ static const char *get_name(enum connman_service_type type) 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"; -- 1.6.1.3 _______________________________________________ connman mailing list connman@connman.net http://lists.connman.net/listinfo/connman