huawei: detect possible secondary device

This commit is contained in:
Kalle Valo 2010-05-20 13:53:15 +03:00 committed by Denis Kenzior
parent 6b0f2328c5
commit 6f4b3c31fd
2 changed files with 106 additions and 22 deletions

View File

@ -46,6 +46,7 @@
struct huawei_data { struct huawei_data {
GAtChat *chat; GAtChat *chat;
GAtChat *event;
}; };
static int huawei_probe(struct ofono_modem *modem) 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); ofono_modem_set_data(modem, NULL);
g_at_chat_unref(data->chat); g_at_chat_unref(data->chat);
g_at_chat_unref(data->event);
g_free(data); g_free(data);
} }
static void huawei_debug(const char *str, void *user_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) 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); 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; GAtSyntax *syntax;
GIOChannel *channel; GIOChannel *channel;
const char *device; GAtChat *chat;
DBG("%p", modem);
device = ofono_modem_get_string(modem, "Device");
if (!device)
return -EINVAL;
channel = g_at_tty_open(device, NULL); channel = g_at_tty_open(device, NULL);
if (!channel) if (!channel)
return -EIO; return NULL;
syntax = g_at_syntax_new_gsm_permissive(); 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_at_syntax_unref(syntax);
g_io_channel_unref(channel); 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; return -EIO;
g_at_chat_add_terminator(data->chat, "COMMAND NOT SUPPORT", -1, FALSE); g_at_chat_add_terminator(data->chat, "COMMAND NOT SUPPORT", -1, FALSE);
if (getenv("OFONO_AT_DEBUG")) 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); 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); 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) if (!data->chat)
return 0; return 0;

View File

@ -89,6 +89,24 @@ static const char *get_serial(struct udev_device *udev_device)
return serial; 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 MODEM_DEVICE "ModemDevice"
#define DATA_DEVICE "DataDevice" #define DATA_DEVICE "DataDevice"
#define GPS_DEVICE "GPSDevice" #define GPS_DEVICE "GPSDevice"
@ -201,18 +219,45 @@ static void add_hso(struct ofono_modem *modem,
static void add_huawei(struct ofono_modem *modem, static void add_huawei(struct ofono_modem *modem,
struct udev_device *udev_device) struct udev_device *udev_device)
{ {
const char *devnode; const char *devnode, *num;
int registered; int primary, secondary;
registered = ofono_modem_get_integer(modem, "Registered"); primary = ofono_modem_get_integer(modem, "PrimaryRegistered");
if (registered != 0) secondary = ofono_modem_get_integer(modem, "SecondaryRegistered");
if (primary && secondary)
return; return;
devnode = udev_device_get_devnode(udev_device); num = get_usb_num(udev_device);
ofono_modem_set_string(modem, "Device", devnode);
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, static void add_em770(struct ofono_modem *modem,