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(&ethernet_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

Reply via email to