diff options
author | Dan Williams <dcbw@redhat.com> | 2009-06-29 10:15:52 -0400 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2009-06-29 10:15:52 -0400 |
commit | ff58936f1f7ef1645be9062095c35de2b03c0cc1 (patch) | |
tree | 1031e04ee0117b953c1835ffe9341726a59c0926 | |
parent | b79ebbac352e581c5a9d6eea2a5000f4cdc62188 (diff) |
mbm: port to udev and new plugin API
-rw-r--r-- | plugins/77-mm-ericsson-mbm.rules | 22 | ||||
-rw-r--r-- | plugins/Makefile.am | 19 | ||||
-rw-r--r-- | plugins/mm-modem-mbm.c | 343 | ||||
-rw-r--r-- | plugins/mm-modem-mbm.h | 8 | ||||
-rw-r--r-- | plugins/mm-plugin-mbm.c | 278 | ||||
-rw-r--r-- | plugins/mm-plugin-mbm.h | 10 |
6 files changed, 309 insertions, 371 deletions
diff --git a/plugins/77-mm-ericsson-mbm.rules b/plugins/77-mm-ericsson-mbm.rules new file mode 100644 index 00000000..c3acaac2 --- /dev/null +++ b/plugins/77-mm-ericsson-mbm.rules @@ -0,0 +1,22 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add|change", GOTO="mm_mbm_end" +SUBSYSTEM!="usb", GOTO="mm_mbm_end" +ENV{DEVTYPE}!="usb_device", GOTO="mm_mbm_end" + +# Sony-Ericsson F3507g +ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1900", ENV{ID_MM_ERICSSON_MBM}="1" +ATTRS{idVendor}=="0bdb", ATTRS{idProduct}=="1902", ENV{ID_MM_ERICSSON_MBM}="1" + +# Sony-Ericsson MD300 +ATTRS{idVendor}=="0fce", ATTRS{idProduct}=="d0cf", ENV{ID_MM_ERICSSON_MBM}="1" + +# Dell 5530 HSDPA +ATTRS{idVendor}=="413c", ATTRS{idProduct}=="8147", ENV{ID_MM_ERICSSON_MBM}="1" + +# Toshiba +ATTRS{idVendor}=="0930", ATTRS{idProduct}=="130b", ENV{ID_MM_ERICSSON_MBM}="1" + + +LABEL="mm_mbm_end" + diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 3d8f6167..98450bcc 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -106,16 +106,20 @@ libmm_plugin_hso_la_LDFLAGS = \ # MBM libmm_plugin_mbm_la_SOURCES = \ - mm-modem-mbm.c \ - mm-modem-mbm.h \ mm-plugin-mbm.c \ - mm-plugin-mbm.h + mm-plugin-mbm.h \ + mm-modem-mbm.c \ + mm-modem-mbm.h libmm_plugin_mbm_la_CPPFLAGS = \ $(MM_CFLAGS) \ + $(GUDEV_CFLAGS) \ -I$(top_srcdir)/src -libmm_plugin_mbm_la_LDFLAGS = -module -avoid-version +libmm_plugin_mbm_la_LDFLAGS = \ + $(GUDEV_LDFLAGS) \ + -module \ + -avoid-version # Option @@ -208,7 +212,14 @@ libmm_plugin_zte_la_LDFLAGS = \ -avoid-version +udevrulesdir = $(UDEV_BASE_DIR)/rules.d +udevrules_DATA = 77-mm-ericsson-mbm.rules + BUILT_SOURCES = \ mm-modem-gsm-hso-glue.h CLEANFILES = $(BUILT_SOURCES) + +EXTRA_DIST = \ + $(udevrules_DATA) + diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 04ee5d92..62da91a6 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -27,6 +27,7 @@ #include <stdio.h> #include <string.h> #include <unistd.h> + #include "mm-modem-mbm.h" #include "mm-modem-simple.h" #include "mm-errors.h" @@ -39,7 +40,6 @@ #define MBM_E2NAP_CONNECTING 2 #define MBM_SIGNAL_INDICATOR 2 -#define MBM_SEND_DELAY 1000 #define MBM_NETWORK_MODE_ANY 1 #define MBM_NETWORK_MODE_2G 5 @@ -76,12 +76,6 @@ mbm_modem_authenticate (MMModemMbm *self, const char *password, gpointer user_data); -static void -mbm_set_network_mode_done (MMSerial *serial, - GString *response, - GError *error, - gpointer user_data); - static const char * mbm_simple_get_string_property (GHashTable *properties, const char *name, GError **error); @@ -89,21 +83,19 @@ static uint mbm_simple_get_uint_property (GHashTable *properties, const char *name, GError **error); MMModem * -mm_modem_mbm_new (const char *serial_device, - const char *network_device, - const char *driver) +mm_modem_mbm_new (const char *device, + const char *driver, + const char *plugin) { - g_return_val_if_fail (serial_device != NULL, NULL); - g_return_val_if_fail (network_device != NULL, NULL); + g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); + g_return_val_if_fail (plugin != NULL, NULL); return MM_MODEM (g_object_new (MM_TYPE_MODEM_MBM, - MM_SERIAL_DEVICE, serial_device, - MM_SERIAL_SEND_DELAY, (guint64) MBM_SEND_DELAY, + MM_MODEM_MASTER_DEVICE, device, MM_MODEM_DRIVER, driver, - MM_MODEM_DEVICE, network_device, + MM_MODEM_PLUGIN, plugin, MM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_DHCP, - MM_MODEM_TYPE, MM_MODEM_TYPE_GSM, NULL)); } @@ -125,14 +117,18 @@ register_done (gpointer user_data) MMModemMbm *self = MM_MODEM_MBM (reg_data->modem); MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (self); MMModemGsmNetwork *parent_modem_iface; + MMSerialPort *primary; priv->reg_id = 0; - mm_serial_queue_command (MM_SERIAL (reg_data->modem), "+CREG=1", 3, NULL, NULL); - mm_serial_queue_command (MM_SERIAL (reg_data->modem), "+CMER=3,0,0,1", 3, NULL, NULL); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + + mm_serial_port_queue_command (primary, "+CREG=1", 3, NULL, NULL); + mm_serial_port_queue_command (primary, "+CMER=3,0,0,1", 3, NULL, NULL); - parent_modem_iface = g_type_interface_peek_parent (MM_MODEM_GSM_NETWORK_GET_INTERFACE (reg_data->modem)); - parent_modem_iface->do_register (MM_MODEM_GSM_NETWORK (reg_data->modem), + parent_modem_iface = g_type_interface_peek_parent (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)); + parent_modem_iface->do_register (MM_MODEM_GSM_NETWORK (self), reg_data->network_id, reg_data->callback, reg_data->user_data); @@ -167,7 +163,10 @@ do_register (MMModemGsmNetwork *modem, } static void -mbm_cind_done (MMSerial *serial, GString *response, GError *error, gpointer user_data) +mbm_cind_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; char *cind; @@ -193,9 +192,12 @@ get_signal_quality (MMModemGsmNetwork *modem, gpointer user_data) { MMCallbackInfo *info; + MMSerialPort *primary; info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - mm_serial_queue_command (MM_SERIAL (modem), "+CIND?", 3, mbm_cind_done, info); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + mm_serial_port_queue_command (primary, "+CIND?", 3, mbm_cind_done, info); } static int @@ -219,6 +221,20 @@ mbm_parse_network_mode (int network_mode) } static void +mbm_set_network_mode_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) +{ + MMCallbackInfo *info = (MMCallbackInfo *) user_data; + + if (error) + info->error = g_error_copy (error); + + mm_callback_info_schedule (info); +} + +static void set_network_mode (MMModemGsmNetwork *modem, MMModemGsmNetworkMode mode, MMModemFn callback, @@ -226,19 +242,22 @@ set_network_mode (MMModemGsmNetwork *modem, { MMCallbackInfo *info; char *command; + MMSerialPort *primary; info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + g_assert (primary); command = g_strdup_printf ("+CFUN=%d", mbm_parse_network_mode (mode)); - mm_serial_queue_command (MM_SERIAL (modem), command, 3, mbm_set_network_mode_done, info); + mm_serial_port_queue_command (primary, command, 3, mbm_set_network_mode_done, info); g_free (command); } static void -mbm_get_network_mode_done (MMSerial *serial, - GString *response, - GError *error, - gpointer user_data) +get_network_mode_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; char *erinfo; @@ -290,9 +309,12 @@ get_network_mode (MMModemGsmNetwork *modem, gpointer user_data) { MMCallbackInfo *info; + MMSerialPort *primary; info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - mm_serial_queue_command (MM_SERIAL (modem), "*ERINFO?", 3, mbm_get_network_mode_done, info); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + mm_serial_port_queue_command (primary, "*ERINFO?", 3, get_network_mode_done, info); } /*****************************************************************************/ @@ -325,7 +347,10 @@ simple_connect (MMModemSimple *simple, /*****************************************************************************/ static void -mbm_enable_done (MMSerial *serial, GString *response, GError *error, gpointer user_data) +mbm_enable_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; @@ -335,10 +360,13 @@ mbm_enable_done (MMSerial *serial, GString *response, GError *error, gpointer us } static void -mbm_init_done (MMSerial *serial, GString *response, GError *error, gpointer user_data) +mbm_init_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (serial); + MMCallbackInfo *info = user_data; + MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); char *command; if (error) { @@ -348,21 +376,25 @@ mbm_init_done (MMSerial *serial, GString *response, GError *error, gpointer user if (!priv->network_mode) priv->network_mode = MBM_NETWORK_MODE_ANY; command = g_strdup_printf ("+CFUN=%d", priv->network_mode); - mm_serial_queue_command (serial, command, 3, mbm_enable_done, info); + mm_serial_port_queue_command (port, command, 3, mbm_enable_done, info); g_free (command); } } static void -do_init (MMSerial *serial, gpointer user_data) +do_init (MMSerialPort *port, gpointer user_data) { - mm_serial_queue_command (serial, "&F E0 V1 X4 &C1 +CMEE=1", 3, mbm_init_done, user_data); + mm_serial_port_queue_command (port, "&F E0 V1 X4 &C1 +CMEE=1", 3, mbm_init_done, user_data); } static void -mbm_emrdy_done (MMSerial *serial, GString *response, GError *error, gpointer user_data) +mbm_emrdy_done (MMSerialPort *port, + GString *response, + GError *error, + gpointer user_data) { - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (serial); + MMCallbackInfo *info = user_data; + MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); if ( error && error->domain == MM_SERIAL_ERROR @@ -371,39 +403,38 @@ mbm_emrdy_done (MMSerial *serial, GString *response, GError *error, gpointer use } else priv->have_emrdy = TRUE; - do_init (serial, user_data); + do_init (port, user_data); } static void -enable_flash_done (MMSerial *serial, gpointer user_data) +enable_flash_done (MMSerialPort *port, gpointer user_data) { - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (serial); - MMCallbackInfo *info = (MMCallbackInfo *) user_data; + MMCallbackInfo *info = user_data; + MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (info->modem); if (priv->have_emrdy) { /* Modem is ready, no need to check EMRDY */ - do_init (serial, info); + do_init (port, info); } else - mm_serial_queue_command (serial, "*EMRDY?", 5, mbm_emrdy_done, info); + mm_serial_port_queue_command (port, "*EMRDY?", 5, mbm_emrdy_done, info); } static void -disable_done (MMSerial *serial, +disable_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) { - MMCallbackInfo *info = (MMCallbackInfo *) user_data; + MMCallbackInfo *info = user_data; - mm_serial_close (serial); + mm_serial_port_close (port); mm_callback_info_schedule (info); } static void -disable_flash_done (MMSerial *serial, - gpointer user_data) +disable_flash_done (MMSerialPort *port, gpointer user_data) { - mm_serial_queue_command (serial, "+CMER=0", 5, disable_done, user_data); + mm_serial_port_queue_command (port, "+CMER=0", 5, disable_done, user_data); } static void @@ -413,24 +444,28 @@ enable (MMModem *modem, gpointer user_data) { MMCallbackInfo *info; + MMSerialPort *primary; mm_generic_gsm_set_cid (MM_GENERIC_GSM (modem), 0); info = mm_callback_info_new (modem, callback, user_data); + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + if (do_enable) { - if (mm_serial_open (MM_SERIAL (modem), &info->error)) - mm_serial_flash (MM_SERIAL (modem), 100, enable_flash_done, info); + if (mm_serial_port_open (primary, &info->error)) + mm_serial_port_flash (primary, 100, enable_flash_done, info); if (info->error) mm_callback_info_schedule (info); } else { - mm_serial_queue_command (MM_SERIAL (modem), "+CREG=0", 100, NULL, NULL); + mm_serial_port_queue_command (primary, "+CREG=0", 100, NULL, NULL); mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem)); - if (mm_serial_is_connected (MM_SERIAL (modem))) - mm_serial_flash (MM_SERIAL (modem), 1000, disable_flash_done, info); + if (mm_serial_port_is_connected (primary)) + mm_serial_port_flash (primary, 1000, disable_flash_done, info); else - disable_flash_done (MM_SERIAL (modem), info); + disable_flash_done (primary, info); } } @@ -455,39 +490,27 @@ disconnect (MMModem *modem, gpointer user_data) { MMCallbackInfo *info; + MMSerialPort *primary; info = mm_callback_info_new (modem, callback, user_data); - mm_serial_queue_command (MM_SERIAL (modem), "AT*ENAP=0", 3, NULL, info); - + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + mm_serial_port_queue_command (primary, "AT*ENAP=0", 3, NULL, info); mm_callback_info_schedule (info); } /*****************************************************************************/ static void -mbm_set_network_mode_done (MMSerial *serial, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - - if (error) - info->error = g_error_copy (error); - - mm_callback_info_schedule (info); -} - -static void -mbm_emrdy_received (MMSerial *serial, +mbm_emrdy_received (MMSerialPort *port, GMatchInfo *info, gpointer user_data) { - MM_MODEM_MBM_GET_PRIVATE (serial)->have_emrdy = TRUE; + MM_MODEM_MBM_GET_PRIVATE (user_data)->have_emrdy = TRUE; } static void -mbm_pacsp0_received (MMSerial *serial, +mbm_pacsp0_received (MMSerialPort *port, GMatchInfo *info, gpointer user_data) { @@ -495,7 +518,7 @@ mbm_pacsp0_received (MMSerial *serial, } static void -mbm_ciev_received (MMSerial *serial, +mbm_ciev_received (MMSerialPort *port, GMatchInfo *info, gpointer user_data) { @@ -510,7 +533,7 @@ mbm_ciev_received (MMSerial *serial, str = g_match_info_fetch (info, 2); if (str) { quality = atoi (str); - mm_modem_gsm_network_signal_quality (MM_MODEM_GSM_NETWORK(serial), quality * 20); + mm_modem_gsm_network_signal_quality (MM_MODEM_GSM_NETWORK (user_data), quality * 20); } } } @@ -518,13 +541,11 @@ mbm_ciev_received (MMSerial *serial, static void mbm_do_connect_done (MMModemMbm *self) { - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (self); - - mm_callback_info_schedule (priv->do_connect_done_info); + mm_callback_info_schedule (MM_MODEM_MBM_GET_PRIVATE (self)->do_connect_done_info); } static void -mbm_e2nap_received (MMSerial *serial, +mbm_e2nap_received (MMSerialPort *port, GMatchInfo *info, gpointer user_data) { @@ -539,7 +560,7 @@ mbm_e2nap_received (MMSerial *serial, g_debug ("%s, disconnected", __func__); else if (MBM_E2NAP_CONNECTED == state) { g_debug ("%s, connected", __func__); - mbm_do_connect_done (MM_MODEM_MBM (serial)); + mbm_do_connect_done (MM_MODEM_MBM (user_data)); } else if (MBM_E2NAP_CONNECTING == state) g_debug("%s, connecting", __func__); else { @@ -550,7 +571,7 @@ mbm_e2nap_received (MMSerial *serial, } static void -e2nap_done (MMSerial *serial, +e2nap_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -563,15 +584,15 @@ e2nap_done (MMSerial *serial, /* TODO: Fallback to polling of enap status */ mm_callback_info_schedule (info); } else { - guint32 cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (serial)); + guint32 cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (info->modem)); command = g_strdup_printf ("AT*ENAP=1,%d",cid); - mm_serial_queue_command (serial, command, 3, NULL, NULL); + mm_serial_port_queue_command (port, command, 3, NULL, NULL); g_free (command); } } static void -mbm_auth_done (MMSerial *serial, +mbm_auth_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -582,7 +603,7 @@ mbm_auth_done (MMSerial *serial, info->error = g_error_copy (error); mm_callback_info_schedule (info); } else - mm_serial_queue_command (MM_SERIAL (serial), "AT*E2NAP=1", 3, e2nap_done, user_data); + mm_serial_port_queue_command (port, "AT*E2NAP=1", 3, e2nap_done, user_data); } static void @@ -591,6 +612,11 @@ mbm_modem_authenticate (MMModemMbm *self, const char *password, gpointer user_data) { + MMSerialPort *primary; + + primary = mm_generic_gsm_get_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + g_assert (primary); + if (username || password) { char *command; @@ -599,10 +625,10 @@ mbm_modem_authenticate (MMModemMbm *self, username ? username : "", password ? password : ""); - mm_serial_queue_command (MM_SERIAL (self), command, 3, mbm_auth_done, user_data); + mm_serial_port_queue_command (primary, command, 3, mbm_auth_done, user_data); g_free (command); } else - mbm_auth_done (MM_SERIAL (self), NULL, NULL, user_data); + mbm_auth_done (primary, NULL, NULL, user_data); } static const char * @@ -645,6 +671,55 @@ mbm_simple_get_uint_property (GHashTable *properties, const char *name, GError * /*****************************************************************************/ +static gboolean +grab_port (MMModem *modem, + const char *subsys, + const char *name, + gpointer user_data, + GError **error) +{ + MMGenericGsm *gsm = MM_GENERIC_GSM (modem); + MMPortType ptype = MM_PORT_TYPE_IGNORED; + MMPort *port = NULL; + + if (!strcmp (subsys, "tty")) { + if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_PRIMARY)) + ptype = MM_PORT_TYPE_PRIMARY; + else if (!mm_generic_gsm_get_port (gsm, MM_PORT_TYPE_SECONDARY)) + ptype = MM_PORT_TYPE_SECONDARY; + } + + port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); + if (!port) + return FALSE; + + if (MM_IS_SERIAL_PORT (port) && (ptype == MM_PORT_TYPE_PRIMARY)) { + GRegex *regex; + + mm_generic_gsm_set_unsolicited_registration (MM_GENERIC_GSM (modem), TRUE); + + regex = g_regex_new ("\\r\\n\\*EMRDY: \\d\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_emrdy_received, modem, NULL); + g_regex_unref (regex); + + regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_e2nap_received, modem, NULL); + g_regex_unref (regex); + + regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_pacsp0_received, modem, NULL); + g_regex_unref (regex); + + regex = g_regex_new ("\\r\\n\\+CIEV: (\\d),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_serial_port_add_unsolicited_msg_handler (MM_SERIAL_PORT (port), regex, mbm_ciev_received, modem, NULL); + g_regex_unref (regex); + } + + return TRUE; +} + +/*****************************************************************************/ + static void modem_gsm_network_init (MMModemGsmNetwork *class) { @@ -663,6 +738,7 @@ modem_simple_init (MMModemSimple *class) static void modem_init (MMModem *modem_class) { + modem_class->grab_port = grab_port; modem_class->enable = enable; modem_class->connect = do_connect; modem_class->disconnect = disconnect; @@ -671,64 +747,6 @@ modem_init (MMModem *modem_class) static void mm_modem_mbm_init (MMModemMbm *self) { - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (self); - GRegex *emrdy_regex, *e2nap_regex, *pacsp0_regex, *ciev_regex; - - priv->have_emrdy = FALSE; - - mm_generic_gsm_set_unsolicited_registration (MM_GENERIC_GSM (self), TRUE); - - emrdy_regex = g_regex_new ("\\r\\n\\*EMRDY: \\d\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_serial_add_unsolicited_msg_handler (MM_SERIAL (self), emrdy_regex, mbm_emrdy_received, self, NULL); - - e2nap_regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_serial_add_unsolicited_msg_handler (MM_SERIAL (self), e2nap_regex, mbm_e2nap_received, self, NULL); - - pacsp0_regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_serial_add_unsolicited_msg_handler (MM_SERIAL (self), pacsp0_regex, mbm_pacsp0_received, self, NULL); - - ciev_regex = g_regex_new ("\\r\\n\\+CIEV: (\\d),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_serial_add_unsolicited_msg_handler (MM_SERIAL (self), ciev_regex, mbm_ciev_received, self, NULL); - - g_regex_unref (emrdy_regex); - g_regex_unref (e2nap_regex); - g_regex_unref (pacsp0_regex); - g_regex_unref (ciev_regex); -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - MMModemMbmPrivate *priv; - GObject *object; - char *modem_device, *serial_device; - - object = G_OBJECT_CLASS (mm_modem_mbm_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - priv = MM_MODEM_MBM_GET_PRIVATE (object); - - /* Make sure both serial device and data device are provided */ - g_object_get (object, - MM_MODEM_DEVICE, &modem_device, - MM_SERIAL_DEVICE, &serial_device, - NULL); - - if (!modem_device || !serial_device || !strcmp (modem_device, serial_device)) { - g_warning ("No network device provided"); - g_object_unref (object); - object = NULL; - } - - g_free (modem_device); - g_free (serial_device); - - return object; } static void @@ -745,36 +763,6 @@ finalize (GObject *object) } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - MMModemMbmPrivate *priv = MM_MODEM_MBM_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_NETWORK_DEVICE: - /* Construct only */ - priv->network_device = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_NETWORK_DEVICE: - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void mm_modem_mbm_class_init (MMModemMbmClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -783,9 +771,6 @@ mm_modem_mbm_class_init (MMModemMbmClass *klass) g_type_class_add_private (object_class, sizeof (MMModemMbmPrivate)); /* Virtual methods */ - object_class->constructor = constructor; - object_class->set_property = set_property; - object_class->get_property = get_property; object_class->finalize = finalize; } diff --git a/plugins/mm-modem-mbm.h b/plugins/mm-modem-mbm.h index aff0bcc4..8756e477 100644 --- a/plugins/mm-modem-mbm.h +++ b/plugins/mm-modem-mbm.h @@ -35,8 +35,6 @@ #define MM_IS_MODEM_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_MODEM_MBM)) #define MM_MODEM_MBM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_MODEM_MBM, MMModemMbmClass)) -#define MM_MODEM_MBM_NETWORK_DEVICE "network-device" - typedef struct { MMGenericGsm parent; } MMModemMbm; @@ -47,8 +45,8 @@ typedef struct { GType mm_modem_mbm_get_type (void); -MMModem *mm_modem_mbm_new (const char *serial_device, - const char *network_device, - const char *driver); +MMModem *mm_modem_mbm_new (const char *device, + const char *driver, + const char *plugin_name); #endif /* MM_MODEM_MBM_H */ diff --git a/plugins/mm-plugin-mbm.c b/plugins/mm-plugin-mbm.c index c4b58e55..2af7eed7 100644 --- a/plugins/mm-plugin-mbm.c +++ b/plugins/mm-plugin-mbm.c @@ -22,13 +22,14 @@ #include <string.h> #include <gmodule.h> + +#define G_UDEV_API_IS_SUBJECT_TO_CHANGE +#include <gudev/gudev.h> + #include "mm-plugin-mbm.h" #include "mm-modem-mbm.h" -static void plugin_init (MMPlugin *plugin_class); - -G_DEFINE_TYPE_EXTENDED (MMPluginMbm, mm_plugin_mbm, G_TYPE_OBJECT, - 0, G_IMPLEMENT_INTERFACE (MM_TYPE_PLUGIN, plugin_init)) +G_DEFINE_TYPE (MMPluginMbm, mm_plugin_mbm, MM_TYPE_PLUGIN_BASE) int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; @@ -36,196 +37,122 @@ int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { - return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_MBM, NULL)); + return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_MBM, + MM_PLUGIN_BASE_NAME, "Ericsson MBM", + NULL)); } /*****************************************************************************/ -static const char * -get_name (MMPlugin *plugin) +static guint32 +get_level_for_capabilities (guint32 capabilities) { - return "MBM"; + if (capabilities & MM_PLUGIN_BASE_PORT_CAP_GSM) + return 10; + return 0; } -static char ** -list_supported_udis (MMPlugin *plugin, LibHalContext *hal_ctx) +static void +probe_result (MMPluginBase *base, + MMPluginBaseSupportsTask *task, + guint32 capabilities, + gpointer user_data) { - char **supported = NULL; - char **devices; - int num_devices; - int i; - - devices = libhal_find_device_by_capability (hal_ctx, "modem", &num_devices, NULL); - if (devices) { - GPtrArray *array; - - array = g_ptr_array_new (); + mm_plugin_base_supports_task_complete (task, get_level_for_capabilities (capabilities)); +} - for (i = 0; i < num_devices; i++) { - char *udi = devices[i]; +static MMPluginSupportsResult +supports_port (MMPluginBase *base, + MMModem *existing, + MMPluginBaseSupportsTask *task) +{ + GUdevDevice *port, *physdev; + guint32 cached = 0, level; + const char *driver, *subsys; + + /* Can't do anything with non-serial ports */ + port = mm_plugin_base_supports_task_get_port (task); + g_assert (port); + subsys = g_udev_device_get_subsystem (port); + g_assert (subsys); + + if (strcmp (subsys, "tty") && strcmp (subsys, "net")) + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; + + driver = mm_plugin_base_supports_task_get_driver (task); + if (!driver) + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; + + physdev = mm_plugin_base_supports_task_get_physdev (task); + g_assert (physdev); + if (!g_udev_device_get_property_as_boolean (physdev, "ID_MM_ERICSSON_MBM")) + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; + + if (!strcmp (subsys, "net")) { + mm_plugin_base_supports_task_complete (task, 10); + return MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS; + } - if (mm_plugin_supports_udi (plugin, hal_ctx, udi)) - g_ptr_array_add (array, g_strdup (udi)); + if (mm_plugin_base_get_cached_port_capabilities (base, port, &cached)) { + level = get_level_for_capabilities (cached); + if (level) { + mm_plugin_base_supports_task_complete (task, level); + return MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS; } - - if (array->len > 0) { - g_ptr_array_add (array, NULL); - supported = (char **) g_ptr_array_free (array, FALSE); - } else - g_ptr_array_free (array, TRUE); + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; } - g_strfreev (devices); + /* Otherwise kick off a probe */ + if (mm_plugin_base_probe_port (base, task, NULL)) + return MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS; - return supported; + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; } -static char * -get_netdev (LibHalContext *ctx, const char *udi) +static MMModem * +grab_port (MMPluginBase *base, + MMModem *existing, + MMPluginBaseSupportsTask *task, + GError **error) { - char *serial_parent, *serial_parent_parent, *netdev = NULL; - char **netdevs; - int num, i; - - /* Get the origin udi, which is parent of our parent */ - serial_parent = libhal_device_get_property_string (ctx, udi, "info.parent", NULL); - if (!serial_parent) + GUdevDevice *port = NULL, *physdev = NULL; + MMModem *modem = NULL; + const char *name, *subsys, *sysfs_path; + guint32 caps; + + port = mm_plugin_base_supports_task_get_port (task); + g_assert (port); + + physdev = mm_plugin_base_supports_task_get_physdev (task); + g_assert (physdev); + sysfs_path = g_udev_device_get_sysfs_path (physdev); + if (!sysfs_path) { + g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); return NULL; - /* Just attach to first cdc-acm interface */ - if (strncmp (serial_parent + strlen (serial_parent) - 4, "_if1", 4)) - return NULL; - serial_parent_parent = libhal_device_get_property_string (ctx, serial_parent, "info.parent", NULL); - if (!serial_parent_parent) - return NULL; - - /* Look for the originating device's netdev */ - netdevs = libhal_find_device_by_capability (ctx, "net", &num, NULL); - for (i = 0; netdevs && !netdev && (i < num); i++) { - char *netdev_parent, *netdev_parent_parent, *tmp; - - /* Get the origin udi, which also is parent of our parent */ - netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "info.parent", NULL); - if (!netdev_parent) - continue; - netdev_parent_parent = libhal_device_get_property_string (ctx, netdev_parent, "info.parent", NULL); - if (!netdev_parent_parent) - continue; - - if (!strcmp (netdev_parent_parent, serial_parent_parent)) { - /* We found it */ - tmp = libhal_device_get_property_string (ctx, netdevs[i], "net.interface", NULL); - if (tmp) { - netdev = g_strdup (tmp); - libhal_free_string (tmp); - } - } - - libhal_free_string (netdev_parent); - libhal_free_string (netdev_parent_parent); } - libhal_free_string_array (netdevs); - libhal_free_string (serial_parent); - libhal_free_string (serial_parent_parent); - return netdev; -} - -static char * -get_driver (LibHalContext *ctx, const char *udi) -{ - char *serial_parent, *serial_parent_parent, *driver = NULL; - char **netdevs; - int num, i; + subsys = g_udev_device_get_subsystem (port); + name = g_udev_device_get_name (port); - /* Get the origin udi, which is parent of our parent */ - serial_parent = libhal_device_get_property_string (ctx, udi, "info.parent", NULL); - if (!serial_parent) - return NULL; - serial_parent_parent = libhal_device_get_property_string (ctx, serial_parent, "info.parent", NULL); - if (!serial_parent_parent) + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net")) return NULL; - /* Look for the originating device's netdev */ - netdevs = libhal_find_device_by_capability (ctx, "net", &num, NULL); - for (i = 0; netdevs && !driver && (i < num); i++) { - char *netdev_parent, *netdev_parent_parent, *tmp; - - /* Get the origin udi, which also is parent of our parent */ - netdev_parent = libhal_device_get_property_string (ctx, netdevs[i], "info.parent", NULL); - if (!netdev_parent) - continue; - netdev_parent_parent = libhal_device_get_property_string (ctx, netdev_parent, "info.parent", NULL); - if (!netdev_parent_parent) - continue; - - if (!strcmp (netdev_parent_parent, serial_parent_parent)) { - /* We found it */ - tmp = libhal_device_get_property_string (ctx, - netdev_parent, "info.linux.driver", NULL); - if (tmp) { - driver = g_strdup (tmp); - libhal_free_string (tmp); + if (!existing) { + modem = mm_modem_mbm_new (sysfs_path, + mm_plugin_base_supports_task_get_driver (task), + mm_plugin_get_name (MM_PLUGIN (base))); + if (modem) { + if (!mm_modem_grab_port (modem, subsys, name, NULL, error)) { + g_object_unref (modem); + return NULL; } } - - libhal_free_string (netdev_parent); - libhal_free_string (netdev_parent_parent); + } else { + modem = existing; + if (!mm_modem_grab_port (modem, subsys, name, NULL, error)) + return NULL; } - libhal_free_string_array (netdevs); - libhal_free_string (serial_parent); - libhal_free_string (serial_parent_parent); - - return driver; -} - -static gboolean -supports_udi (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi) -{ - char *driver_name; - gboolean supported = FALSE; - - driver_name = get_driver (hal_ctx, udi); - if (driver_name && (!strcmp (driver_name, "cdc_ether") || !strcmp (driver_name, "mbm"))) { - char **capabilities; - char **iter; - - capabilities = libhal_device_get_property_strlist (hal_ctx, udi, "modem.command_sets", NULL); - for (iter = capabilities; iter && *iter && !supported; iter++) { - if (!strcmp (*iter, "GSM-07.07") || !strcmp (*iter, "GSM-07.05")) { - supported = TRUE; - break; - } - } - - libhal_free_string_array (capabilities); - } - - libhal_free_string (driver_name); - - return supported; -} - -static MMModem * -create_modem (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi) -{ - char *serial_device; - char *net_device; - char *driver; - MMModem *modem; - - serial_device = libhal_device_get_property_string (hal_ctx, udi, "serial.device", NULL); - g_return_val_if_fail (serial_device != NULL, NULL); - - net_device = get_netdev (hal_ctx, udi); - g_return_val_if_fail (net_device != NULL, NULL); - - driver = get_driver (hal_ctx, udi); - g_return_val_if_fail (driver != NULL, NULL); - - modem = MM_MODEM (mm_modem_mbm_new (serial_device, net_device, driver)); - - g_free (serial_device); - g_free (net_device); return modem; } @@ -233,21 +160,16 @@ create_modem (MMPlugin *plugin, LibHalContext *hal_ctx, const char *udi) /*****************************************************************************/ static void -plugin_init (MMPlugin *plugin_class) -{ - /* interface implementation */ - plugin_class->get_name = get_name; - plugin_class->list_supported_udis = list_supported_udis; - plugin_class->supports_udi = supports_udi; - plugin_class->create_modem = create_modem; -} - -static void mm_plugin_mbm_init (MMPluginMbm *self) { + g_signal_connect (self, "probe-result", G_CALLBACK (probe_result), NULL); } static void mm_plugin_mbm_class_init (MMPluginMbmClass *klass) { + MMPluginBaseClass *pb_class = MM_PLUGIN_BASE_CLASS (klass); + + pb_class->supports_port = supports_port; + pb_class->grab_port = grab_port; } diff --git a/plugins/mm-plugin-mbm.h b/plugins/mm-plugin-mbm.h index e0d2c56a..c0e73b56 100644 --- a/plugins/mm-plugin-mbm.h +++ b/plugins/mm-plugin-mbm.h @@ -23,22 +23,22 @@ #ifndef MM_PLUGIN_MBM_H #define MM_PLUGIN_MBM_H -#include "mm-plugin.h" +#include "mm-plugin-base.h" #include "mm-generic-gsm.h" -#define MM_TYPE_PLUGIN_MBM (mm_plugin_mbm_get_type ()) -#define MM_PLUGIN_MBM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_MBM, MMPluginMbm)) +#define MM_TYPE_PLUGIN_MBM (mm_plugin_mbm_get_type ()) +#define MM_PLUGIN_MBM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_MBM, MMPluginMbm)) #define MM_PLUGIN_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_MBM, MMPluginMbmClass)) #define MM_IS_PLUGIN_MBM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_MBM)) #define MM_IS_PLUGIN_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_MBM)) #define MM_PLUGIN_MBM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MBM, MMPluginMbmClass)) typedef struct { - GObject parent; + MMPluginBase parent; } MMPluginMbm; typedef struct { - GObjectClass parent; + MMPluginBaseClass parent; } MMPluginMbmClass; GType mm_plugin_mbm_get_type (void); |