---

 plugins/huawei.c |   68 ++++++++++++++++++++++++++++++++++++++++++++----------
 plugins/udev.c   |   61 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 108 insertions(+), 21 deletions(-)

diff --git a/plugins/huawei.c b/plugins/huawei.c
index df4d177..2a95cf6 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -45,7 +45,7 @@
 #include <drivers/atmodem/vendor.h>
 
 struct huawei_data {
-       GAtChat *chat;
+       GAtChat *chat, *event;
 };
 
 static int huawei_probe(struct ofono_modem *modem)
@@ -72,6 +72,7 @@ static void huawei_remove(struct ofono_modem *modem)
        ofono_modem_set_data(modem, NULL);
 
        g_at_chat_unref(data->chat);
+       g_at_chat_unref(data->event);
        g_free(data);
 }
 
@@ -80,6 +81,11 @@ static void huawei_debug(const char *str, void *user_data)
        ofono_info("%s", str);
 }
 
+static void huawei_event_debug(const char *str, void *user_data)
+{
+       ofono_info("* %s", str);
+}
+
 static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
 {
        struct ofono_modem *modem = user_data;
@@ -90,29 +96,43 @@ static void cfun_enable(gboolean ok, GAtResult *result, 
gpointer user_data)
                ofono_modem_set_powered(modem, TRUE);
 }
 
-static int huawei_enable(struct ofono_modem *modem)
+static GAtChat *create_port(const char *device)
 {
-       struct huawei_data *data = ofono_modem_get_data(modem);
        GAtSyntax *syntax;
        GIOChannel *channel;
-       const char *device;
-
-       DBG("%p", modem);
-
-       device = ofono_modem_get_string(modem, "Device");
-       if (!device)
-                       return -EINVAL;
+       GAtChat *chat;
 
        channel = g_at_tty_open(device, NULL);
        if (!channel)
-               return -EIO;
+               return NULL;
 
        syntax = g_at_syntax_new_gsm_permissive();
-       data->chat = g_at_chat_new(channel, syntax);
+       chat = g_at_chat_new(channel, syntax);
        g_at_syntax_unref(syntax);
        g_io_channel_unref(channel);
 
-       if (!data->chat)
+       if (!chat)
+               return NULL;
+
+       return chat;
+}
+
+static int huawei_enable(struct ofono_modem *modem)
+{
+       struct huawei_data *data = ofono_modem_get_data(modem);
+       const char *modem_device, *event_device;
+
+       DBG("%p", modem);
+
+       modem_device = ofono_modem_get_string(modem, "Device");
+       event_device = ofono_modem_get_string(modem, "SecondaryDevice");
+
+       if (modem_device == NULL || event_device == NULL)
+               return -EINVAL;
+
+       data->chat = create_port(modem_device);
+
+       if (data->chat == NULL)
                return -EIO;
 
        g_at_chat_add_terminator(data->chat, "COMMAND NOT SUPPORT", -1, FALSE);
@@ -120,6 +140,20 @@ static int huawei_enable(struct ofono_modem *modem)
        if (getenv("OFONO_AT_DEBUG"))
                g_at_chat_set_debug(data->chat, huawei_debug, NULL);
 
+       data->event = create_port(modem_device);
+
+       if (data->event == NULL) {
+               g_at_chat_unref(data->chat);
+               data->chat = NULL;
+               return -EIO;
+       }
+
+       g_at_chat_add_terminator(data->event, "COMMAND NOT SUPPORT", -1,
+                                       FALSE);
+
+       if (getenv("OFONO_AT_DEBUG"))
+               g_at_chat_set_debug(data->event, huawei_event_debug, NULL);
+
        g_at_chat_send(data->chat, "ATE0", NULL, NULL, NULL, NULL);
 
        g_at_chat_send(data->chat, "AT+CFUN=1", NULL,
@@ -138,6 +172,9 @@ static void cfun_disable(gboolean ok, GAtResult *result, 
gpointer user_data)
        g_at_chat_unref(data->chat);
        data->chat = NULL;
 
+       g_at_chat_unref(data->event);
+       data->event = NULL;
+
        if (ok)
                ofono_modem_set_powered(modem, FALSE);
 }
@@ -148,6 +185,11 @@ static int huawei_disable(struct ofono_modem *modem)
 
        DBG("%p", modem);
 
+       if (data->event) {
+               g_at_chat_cancel_all(data->event);
+               g_at_chat_unregister_all(data->event);
+       }
+
        if (!data->chat)
                return 0;
 
diff --git a/plugins/udev.c b/plugins/udev.c
index 3a6ea28..bdac4fd 100644
--- a/plugins/udev.c
+++ b/plugins/udev.c
@@ -89,6 +89,24 @@ static const char *get_serial(struct udev_device 
*udev_device)
        return serial;
 }
 
+static const char *get_usb_num(struct udev_device *udev_device)
+{
+       struct udev_list_entry *entry;
+       const char *num = NULL;
+
+       entry = udev_device_get_properties_list_entry(udev_device);
+       while (entry) {
+               const char *name = udev_list_entry_get_name(entry);
+
+               if (g_strcmp0(name, "ID_USB_INTERFACE_NUM") == 0)
+                       num = udev_list_entry_get_value(entry);
+
+               entry = udev_list_entry_get_next(entry);
+       }
+
+       return num;
+}
+
 #define MODEM_DEVICE           "ModemDevice"
 #define DATA_DEVICE            "DataDevice"
 #define GPS_DEVICE             "GPSDevice"
@@ -201,18 +219,45 @@ static void add_hso(struct ofono_modem *modem,
 static void add_huawei(struct ofono_modem *modem,
                                        struct udev_device *udev_device)
 {
-       const char *devnode;
-       int registered;
+       const char *devnode, *num;
+       int primary, secondary;
 
-       registered = ofono_modem_get_integer(modem, "Registered");
-       if (registered != 0)
+       primary = ofono_modem_get_integer(modem, "PrimaryRegistered");
+       secondary = ofono_modem_get_integer(modem, "SecondaryRegistered");
+
+       if (primary && secondary)
                return;
 
-       devnode = udev_device_get_devnode(udev_device);
-       ofono_modem_set_string(modem, "Device", devnode);
+       num = get_usb_num(udev_device);
 
-       ofono_modem_set_integer(modem, "Registered", 1);
-       ofono_modem_register(modem);
+       /*
+        * Here is is assumed that that usb port number 0 is the control
+        * port and port 2 is the event port. This assumption will surely
+        * be false with some devices and better heuristics is needed.
+        */
+       if (g_strcmp0(num, "00") == 0) {
+               if (primary != 0)
+                       return;
+
+               devnode = udev_device_get_devnode(udev_device);
+               ofono_modem_set_string(modem, "Device", devnode);
+
+               primary = 1;
+               ofono_modem_set_integer(modem, "PrimaryRegistered", primary);
+       } else if (g_strcmp0(num, "02") == 0) {
+               if (secondary != 0)
+                       return;
+
+               devnode = udev_device_get_devnode(udev_device);
+               ofono_modem_set_string(modem, "SecondaryDevice", devnode);
+
+               secondary = 1;
+               ofono_modem_set_integer(modem, "SecondaryRegistered",
+                                       secondary);
+       }
+
+       if (primary && secondary)
+               ofono_modem_register(modem);
 }
 
 static void add_em770(struct ofono_modem *modem,

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to