summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@canonical.com>2010-05-20 13:53:15 +0300
committerDenis Kenzior <denkenz@gmail.com>2010-05-19 23:08:33 -0500
commit6f4b3c31fdcf6a9991062d232f435310e5f3155e (patch)
tree3a6e2db908b0814e062d75dff28d5b0486f453d9
parent6b0f2328c5e190053f6a28ed119d01581e2119b3 (diff)
downloadofono-6f4b3c31fdcf6a9991062d232f435310e5f3155e.tar.bz2
huawei: detect possible secondary device
-rw-r--r--plugins/huawei.c67
-rw-r--r--plugins/udev.c61
2 files changed, 106 insertions, 22 deletions
diff --git a/plugins/huawei.c b/plugins/huawei.c
index df4d177f..489f3e2d 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -46,6 +46,7 @@
struct huawei_data {
GAtChat *chat;
+ GAtChat *event;
};
static int huawei_probe(struct ofono_modem *modem)
@@ -72,12 +73,14 @@ 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);
}
static void huawei_debug(const char *str, void *user_data)
{
- ofono_info("%s", str);
+ const char *prefix = user_data;
+ ofono_info("%s%s", prefix, str);
}
static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data)
@@ -90,35 +93,64 @@ 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);
if (getenv("OFONO_AT_DEBUG"))
- g_at_chat_set_debug(data->chat, huawei_debug, NULL);
+ g_at_chat_set_debug(data->chat, huawei_debug, "");
+
+ data->event = create_port(event_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_debug,
+ "EventChannel: ");
g_at_chat_send(data->chat, "ATE0", NULL, NULL, NULL, NULL);
@@ -148,6 +180,13 @@ 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);
+ g_at_chat_unref(data->event);
+ data->event = NULL;
+ }
+
if (!data->chat)
return 0;
diff --git a/plugins/udev.c b/plugins/udev.c
index 3a6ea285..bdac4fde 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,