diff options
55 files changed, 1144 insertions, 1045 deletions
diff --git a/plugins/mm-modem-anydata-cdma.c b/plugins/mm-modem-anydata-cdma.c index d26d3ec0..5f2277fb 100644 --- a/plugins/mm-modem-anydata-cdma.c +++ b/plugins/mm-modem-anydata-cdma.c @@ -307,19 +307,15 @@ reset (MMModem *modem, mm_callback_info_schedule (info); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericCdma *cdma, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMPort *port = NULL; GRegex *regex; - port = mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { + if (MM_IS_AT_SERIAL_PORT (port)) { /* Data state notifications */ /* Data call has connected */ @@ -337,7 +333,7 @@ grab_port (MMModem *modem, mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); g_regex_unref (regex); - /* Abnomral state notifications + /* Abnormal state notifications * * FIXME: set 1X/EVDO registration state to UNKNOWN when these * notifications are received? @@ -358,8 +354,6 @@ grab_port (MMModem *modem, mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); g_regex_unref (regex); } - - return !!port; } /*****************************************************************************/ @@ -367,7 +361,6 @@ grab_port (MMModem *modem, static void modem_init (MMModem *modem_class) { - modem_class->grab_port = grab_port; modem_class->reset = reset; } @@ -384,6 +377,7 @@ mm_modem_anydata_cdma_class_init (MMModemAnydataCdmaClass *klass) mm_modem_anydata_cdma_parent_class = g_type_class_peek_parent (klass); cdma_class->query_registration_state = query_registration_state; + cdma_class->port_grabbed = port_grabbed; #if 0 /* FIXME: maybe use AT*SLEEP=0/1 to disable/enable slotted mode for powersave */ diff --git a/plugins/mm-modem-cinterion-gsm.c b/plugins/mm-modem-cinterion-gsm.c index 97afb9f5..9220539f 100644 --- a/plugins/mm-modem-cinterion-gsm.c +++ b/plugins/mm-modem-cinterion-gsm.c @@ -28,11 +28,9 @@ #include "mm-serial-parsers.h" #include "mm-log.h" -static void modem_init (MMModem *modem_class); static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); G_DEFINE_TYPE_EXTENDED (MMModemCinterionGsm, mm_modem_cinterion_gsm, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)) /* Mask of all bands supported in 2G devices */ @@ -138,35 +136,16 @@ mm_modem_cinterion_gsm_new (const char *device, NULL)); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { + if (MM_IS_AT_SERIAL_PORT (port)) { /* Set RTS/CTS flow control by default */ - g_object_set (G_OBJECT (port), - MM_SERIAL_PORT_RTS_CTS, TRUE, - NULL); + g_object_set (G_OBJECT (port), MM_SERIAL_PORT_RTS_CTS, TRUE, NULL); } - - return !!port; } static void @@ -1080,12 +1059,6 @@ finalize (GObject *object) /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void modem_gsm_network_init (MMModemGsmNetwork *network_class) { network_class->set_band = set_band; @@ -1118,6 +1091,7 @@ mm_modem_cinterion_gsm_class_init (MMModemCinterionGsmClass *klass) object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; + gsm_class->port_grabbed = port_grabbed; g_object_class_override_property (object_class, MM_GENERIC_GSM_PROP_FLOW_CONTROL_CMD, diff --git a/plugins/mm-modem-hso.c b/plugins/mm-modem-hso.c index e3d4dce7..acb9d849 100644 --- a/plugins/mm-modem-hso.c +++ b/plugins/mm-modem-hso.c @@ -151,7 +151,7 @@ _internal_hso_modem_authenticate (MMModemHso *self, MMCallbackInfo *info) gint cid; char *command; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); cid = hso_get_cid (self); @@ -291,7 +291,7 @@ hso_call_control (MMModemHso *self, mm_callback_info_set_data (info, IGNORE_ERRORS_TAG, GUINT_TO_POINTER (ignore_errors), NULL); command = g_strdup_printf ("AT_OWANCALL=%d,%d,1", hso_get_cid (self), activate ? 1 : 0); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, command, 3, hso_call_control_done, info); g_free (command); @@ -567,7 +567,7 @@ get_ip4_config (MMModem *modem, info = mm_callback_info_new_full (modem, ip4_config_invoke, G_CALLBACK (callback), user_data); command = g_strdup_printf ("AT_OWANDATA=%d", hso_get_cid (MM_MODEM_HSO (modem))); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info); g_free (command); @@ -603,7 +603,7 @@ do_disconnect (MMGenericGsm *gsm, info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); command = g_strdup_printf ("AT_OWANCALL=%d,0,0", cid); @@ -724,80 +724,34 @@ get_access_technology (MMGenericGsm *gsm, /*****************************************************************************/ -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) -{ - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - const char *sys[] = { "tty", "net", NULL }; - GUdevClient *client; - GUdevDevice *device = NULL; - MMPort *port = NULL; - const char *sysfs_path; - - client = g_udev_client_new (sys); - if (!client) { - g_set_error (error, 0, 0, "Could not get udev client."); - return FALSE; - } - - device = g_udev_client_query_by_subsystem_and_name (client, subsys, name); - if (!device) { - g_set_error (error, 0, 0, "Could not get udev device."); - goto out; - } - - sysfs_path = g_udev_device_get_sysfs_path (device); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get udev device sysfs path."); - goto out; - } - - if (!strcmp (subsys, "tty")) { - char *hsotype_path; - char *contents = NULL; - - hsotype_path = g_build_filename (sysfs_path, "hsotype", NULL); - if (g_file_get_contents (hsotype_path, &contents, NULL, NULL)) { - if (g_str_has_prefix (contents, "Control")) - ptype = MM_PORT_TYPE_PRIMARY; - else if (g_str_has_prefix (contents, "Application") || g_str_has_prefix (contents, "Application2")) - ptype = MM_PORT_TYPE_SECONDARY; - g_free (contents); - } - g_free (hsotype_path); - } - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (!port) - goto out; +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) +{ + GRegex *regex; if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (G_OBJECT (port), MM_SERIAL_PORT_SEND_DELAY, (guint64) 0, NULL); - if (ptype == MM_PORT_TYPE_PRIMARY) { - GRegex *regex; - regex = g_regex_new ("_OWANCALL: (\\d),\\s*(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, connection_enabled, modem, NULL); - g_regex_unref (regex); + regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); + g_regex_unref (regex); - regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); - g_regex_unref (regex); - } option_register_unsolicted_handlers (gsm, MM_AT_SERIAL_PORT (port)); } +} + + +static void +ports_organized (MMGenericGsm *gsm, MMAtSerialPort *primary) +{ + GRegex *regex; -out: - if (device) - g_object_unref (device); - g_object_unref (client); - return !!port; + regex = g_regex_new ("_OWANCALL: (\\d),\\s*(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (primary, regex, connection_enabled, gsm, NULL); + g_regex_unref (regex); } /*****************************************************************************/ @@ -819,7 +773,6 @@ modem_init (MMModem *modem_class) modem_class->disable = disable; modem_class->connect = do_connect; modem_class->get_ip4_config = get_ip4_config; - modem_class->grab_port = grab_port; } static void @@ -848,6 +801,8 @@ mm_modem_hso_class_init (MMModemHsoClass *klass) /* Virtual methods */ object_class->finalize = finalize; + gsm_class->port_grabbed = port_grabbed; + gsm_class->ports_organized = ports_organized; gsm_class->do_disconnect = do_disconnect; gsm_class->do_enable_power_up_done = real_do_enable_power_up_done; gsm_class->set_allowed_mode = set_allowed_mode; diff --git a/plugins/mm-modem-huawei-cdma.c b/plugins/mm-modem-huawei-cdma.c index b24ec64b..bdf9898e 100644 --- a/plugins/mm-modem-huawei-cdma.c +++ b/plugins/mm-modem-huawei-cdma.c @@ -29,10 +29,7 @@ #include "mm-serial-parsers.h" #include "mm-log.h" -static void modem_init (MMModem *modem_class); - -G_DEFINE_TYPE_EXTENDED (MMModemHuaweiCdma, mm_modem_huawei_cdma, MM_TYPE_GENERIC_CDMA, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)) +G_DEFINE_TYPE (MMModemHuaweiCdma, mm_modem_huawei_cdma, MM_TYPE_GENERIC_CDMA) MMModem * @@ -256,29 +253,24 @@ query_registration_state (MMGenericCdma *cdma, /*****************************************************************************/ -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericCdma *cdma, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMPort *port = NULL; GRegex *regex; + gboolean evdo0 = FALSE, evdoA = FALSE; - port = mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { - gboolean evdo0 = FALSE, evdoA = FALSE; - + if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); /* 1x signal level */ regex = g_regex_new ("\\r\\n\\^RSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_1x_quality_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_1x_quality_change, cdma, NULL); g_regex_unref (regex); - g_object_get (G_OBJECT (modem), + g_object_get (G_OBJECT (cdma), MM_GENERIC_CDMA_EVDO_REV0, &evdo0, MM_GENERIC_CDMA_EVDO_REVA, &evdoA, NULL); @@ -286,23 +278,15 @@ grab_port (MMModem *modem, if (evdo0 || evdoA) { /* EVDO signal level */ regex = g_regex_new ("\\r\\n\\^HRSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_evdo_quality_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_evdo_quality_change, cdma, NULL); g_regex_unref (regex); } } - - return !!port; } /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void mm_modem_huawei_cdma_init (MMModemHuaweiCdma *self) { } @@ -314,6 +298,7 @@ mm_modem_huawei_cdma_class_init (MMModemHuaweiCdmaClass *klass) mm_modem_huawei_cdma_parent_class = g_type_class_peek_parent (klass); + cdma_class->port_grabbed = port_grabbed; cdma_class->query_registration_state = query_registration_state; } diff --git a/plugins/mm-modem-huawei-gsm.c b/plugins/mm-modem-huawei-gsm.c index ad392218..eea0629c 100644 --- a/plugins/mm-modem-huawei-gsm.c +++ b/plugins/mm-modem-huawei-gsm.c @@ -726,9 +726,10 @@ do_enable_power_up_done (MMGenericGsm *gsm, MMAtSerialPort *primary; /* Enable unsolicited result codes */ - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); + mm_at_serial_port_queue_command (primary, "^PORTSEL=0", 5, NULL, NULL); mm_at_serial_port_queue_command (primary, "^CURC=1", 5, NULL, NULL); } @@ -783,7 +784,7 @@ disable (MMModem *modem, (GCallback)callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Turn off unsolicited responses */ @@ -792,77 +793,33 @@ disable (MMModem *modem, /*****************************************************************************/ -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) -{ - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - const char *sys[] = { "tty", NULL }; - GUdevClient *client; - GUdevDevice *device = NULL; - MMPort *port = NULL; - int usbif; - - client = g_udev_client_new (sys); - if (!client) { - g_set_error (error, 0, 0, "Could not get udev client."); - return FALSE; - } - - device = g_udev_client_query_by_subsystem_and_name (client, subsys, name); - if (!device) { - g_set_error (error, 0, 0, "Could not get udev device."); - goto out; - } - - usbif = g_udev_device_get_property_as_int (device, "ID_USB_INTERFACE_NUM"); - if (usbif < 0) { - g_set_error (error, 0, 0, "Could not get USB device interface number."); - goto out; - } - - if (usbif == 0) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - } else if (suggested_type == MM_PORT_TYPE_SECONDARY) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - - if (port && MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) +{ + GRegex *regex; + if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); regex = g_regex_new ("\\r\\n\\^RSSI:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_signal_quality_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_signal_quality_change, gsm, NULL); g_regex_unref (regex); regex = g_regex_new ("\\r\\n\\^MODE:(\\d),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_mode_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_mode_change, gsm, NULL); g_regex_unref (regex); regex = g_regex_new ("\\r\\n\\^DSFLOWRPT:(.+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_status_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_status_change, gsm, NULL); g_regex_unref (regex); regex = g_regex_new ("\\r\\n\\^BOOT:.+\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, gsm, NULL); g_regex_unref (regex); } - -out: - if (device) - g_object_unref (device); - g_object_unref (client); - return !!port; } /* Encode to packed GSM - this is what Huawei supports on all known models */ @@ -919,7 +876,6 @@ ussd_decode (MMModemGsmUssd *self, const char* reply, guint scheme) static void modem_init (MMModem *modem_class) { - modem_class->grab_port = grab_port; modem_class->disable = disable; } @@ -957,6 +913,7 @@ mm_modem_huawei_gsm_class_init (MMModemHuaweiGsmClass *klass) mm_modem_huawei_gsm_parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (object_class, sizeof (MMModemHuaweiGsmPrivate)); + gsm_class->port_grabbed = port_grabbed; gsm_class->set_allowed_mode = set_allowed_mode; gsm_class->get_allowed_mode = get_allowed_mode; gsm_class->get_access_technology = get_access_technology; diff --git a/plugins/mm-modem-icera.c b/plugins/mm-modem-icera.c index 8dd75da4..915447ef 100644 --- a/plugins/mm-modem-icera.c +++ b/plugins/mm-modem-icera.c @@ -325,7 +325,7 @@ mm_modem_icera_do_disconnect (MMGenericGsm *gsm, info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); command = g_strdup_printf ("%%IPDPACT=%d,0", cid); @@ -445,7 +445,7 @@ connection_enabled (MMAtSerialPort *port, break; case 3: /* Call setup failure? */ - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM(self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM(self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Get additional error details */ mm_at_serial_port_queue_command (primary, "AT%IER?", 3, @@ -481,7 +481,7 @@ icera_call_control (MMModemIcera *self, char *command; MMAtSerialPort *primary; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); command = g_strdup_printf ("%%IPDPACT=%d,%d", _get_cid (self), activate ? 1 : 0); @@ -600,7 +600,7 @@ mm_modem_icera_do_connect (MMModemIcera *self, info = mm_callback_info_new (modem, callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); cid = _get_cid (self); @@ -721,7 +721,7 @@ mm_modem_icera_get_ip4_config (MMModemIcera *self, G_CALLBACK (callback), user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); command = g_strdup_printf ("%%IPDPADDR=%d", _get_cid (self)); @@ -814,7 +814,7 @@ mm_modem_icera_get_local_timestamp (MMModemIcera *self, info = mm_callback_info_icera_timestamp_new (self, callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "*TLTS", 3, get_local_timestamp_done, info); @@ -876,7 +876,7 @@ mm_modem_icera_change_unsolicited_messages (MMModemIcera *self, gboolean enabled { MMAtSerialPort *primary; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, enabled ? "%NWSTATE=1" : "%NWSTATE=0", 3, NULL, NULL); diff --git a/plugins/mm-modem-linktop.c b/plugins/mm-modem-linktop.c index cfe0c0de..a263dd0a 100644 --- a/plugins/mm-modem-linktop.c +++ b/plugins/mm-modem-linktop.c @@ -26,10 +26,7 @@ #define LINKTOP_NETWORK_MODE_2G 5 #define LINKTOP_NETWORK_MODE_3G 6 -static void modem_init (MMModem *modem_class); - -G_DEFINE_TYPE_EXTENDED (MMModemLinktop, mm_modem_linktop, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)) +G_DEFINE_TYPE (MMModemLinktop, mm_modem_linktop, MM_TYPE_GENERIC_GSM) MMModem * @@ -52,35 +49,18 @@ mm_modem_linktop_new (const char *device, NULL)); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { + if (MM_IS_AT_SERIAL_PORT (port)) { mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port), mm_serial_parser_v1_e1_parse, mm_serial_parser_v1_e1_new (), mm_serial_parser_v1_e1_destroy); } - - return !!port; } static int @@ -197,12 +177,6 @@ get_allowed_mode (MMGenericGsm *gsm, /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void mm_modem_linktop_init (MMModemLinktop *self) { } @@ -212,6 +186,7 @@ mm_modem_linktop_class_init (MMModemLinktopClass *klass) { MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); + gsm_class->port_grabbed = port_grabbed; gsm_class->get_allowed_mode = get_allowed_mode; gsm_class->set_allowed_mode = set_allowed_mode; } diff --git a/plugins/mm-modem-mbm.c b/plugins/mm-modem-mbm.c index 65283e47..07fd389a 100644 --- a/plugins/mm-modem-mbm.c +++ b/plugins/mm-modem-mbm.c @@ -473,7 +473,7 @@ do_enable (MMGenericGsm *self, MMModemFn callback, gpointer user_data) info = mm_callback_info_new (MM_MODEM (self), callback, user_data); - primary = mm_generic_gsm_get_at_port (self, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (self, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); if (priv->have_emrdy) { @@ -530,7 +530,7 @@ disable (MMModem *modem, (GCallback)callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Turn off unsolicited responses */ @@ -562,7 +562,7 @@ do_disconnect (MMGenericGsm *gsm, { MMAtSerialPort *primary; - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "*ENAP=0", 3, NULL, NULL); @@ -756,7 +756,7 @@ enap_poll (gpointer user_data) MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMAtSerialPort *port; - port = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (info->modem), MM_PORT_TYPE_PRIMARY); + port = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (info->modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (port); mm_at_serial_port_queue_command (port, "AT*ENAP?", 3, enap_poll_response, user_data); @@ -818,7 +818,7 @@ mbm_modem_authenticate (MMModemMbm *self, { MMAtSerialPort *primary; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); if (username || password) { @@ -944,32 +944,15 @@ mbm_get_unlock_retries (MMModemGsmCard *modem, /*****************************************************************************/ -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (!strcmp (subsys, "tty")) { - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - } - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; + GRegex *regex; + if (MM_IS_AT_SERIAL_PORT (port)) { /* The Ericsson modems always have a free AT command port, so we * don't need to flash the ports when disconnecting to get back to * command mode. F5521gw R2A07 resets port properties like echo when @@ -977,23 +960,12 @@ grab_port (MMModem *modem, */ g_object_set (G_OBJECT (port), MM_SERIAL_PORT_FLASH_OK, FALSE, NULL); - if (ptype == MM_PORT_TYPE_PRIMARY) { - regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_e2nap_received, modem, NULL); - g_regex_unref (regex); - - /* Catch the extended error status bit of the command too */ - regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d),.*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_e2nap_received, modem, NULL); - g_regex_unref (regex); - } - regex = g_regex_new ("\\r\\n\\*EMRDY: \\d\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_emrdy_received, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_emrdy_received, gsm, NULL); g_regex_unref (regex); regex = g_regex_new ("\\r\\n\\+PACSP(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_pacsp_received, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_pacsp_received, gsm, NULL); g_regex_unref (regex); /* also consume unsolicited mbm messages we are not interested in them - see LP: #416418 */ @@ -1006,11 +978,25 @@ grab_port (MMModem *modem, g_regex_unref (regex); regex = g_regex_new ("\\r\\n\\*ERINFO:\\s*(\\d),(\\d),(\\d).*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_erinfo_received, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, mbm_erinfo_received, gsm, NULL); g_regex_unref (regex); } +} - return TRUE; +static void +ports_organized (MMGenericGsm *gsm, MMAtSerialPort *primary) +{ + GRegex *regex; + + /* Only listen on the primary port for connect status responses */ + regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (primary, regex, mbm_e2nap_received, gsm, NULL); + g_regex_unref (regex); + + /* Catch the extended error status bit of the command too */ + regex = g_regex_new ("\\r\\n\\*E2NAP: (\\d),.*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (primary, regex, mbm_e2nap_received, gsm, NULL); + g_regex_unref (regex); } /*****************************************************************************/ @@ -1036,7 +1022,6 @@ modem_simple_init (MMModemSimple *class) static void modem_init (MMModem *modem_class) { - modem_class->grab_port = grab_port; modem_class->disable = disable; modem_class->connect = do_connect; modem_class->reset = reset; @@ -1073,6 +1058,8 @@ mm_modem_mbm_class_init (MMModemMbmClass *klass) /* Virtual methods */ object_class->finalize = finalize; + gsm_class->port_grabbed = port_grabbed; + gsm_class->ports_organized = ports_organized; gsm_class->do_enable = do_enable; gsm_class->do_disconnect = do_disconnect; gsm_class->get_allowed_mode = get_allowed_mode; diff --git a/plugins/mm-modem-nokia.c b/plugins/mm-modem-nokia.c index 9476f615..e4f2317a 100644 --- a/plugins/mm-modem-nokia.c +++ b/plugins/mm-modem-nokia.c @@ -21,10 +21,7 @@ #include "mm-modem-nokia.h" #include "mm-serial-parsers.h" -static void modem_init (MMModem *modem_class); - -G_DEFINE_TYPE_EXTENDED (MMModemNokia, mm_modem_nokia, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)) +G_DEFINE_TYPE (MMModemNokia, mm_modem_nokia, MM_TYPE_GENERIC_GSM) MMModem * @@ -47,46 +44,23 @@ mm_modem_nokia_new (const char *device, NULL)); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { + if (MM_IS_AT_SERIAL_PORT (port)) { mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port), mm_serial_parser_v1_e1_parse, mm_serial_parser_v1_e1_new (), mm_serial_parser_v1_e1_destroy); } - - return !!port; } /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void mm_modem_nokia_init (MMModemNokia *self) { } @@ -134,11 +108,13 @@ static void mm_modem_nokia_class_init (MMModemNokiaClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); mm_modem_nokia_parent_class = g_type_class_peek_parent (klass); object_class->get_property = get_property; object_class->set_property = set_property; + gsm_class->port_grabbed = port_grabbed; g_object_class_override_property (object_class, MM_GENERIC_GSM_PROP_INIT_CMD, diff --git a/plugins/mm-modem-novatel-gsm.c b/plugins/mm-modem-novatel-gsm.c index 05eb8e15..70d31cad 100644 --- a/plugins/mm-modem-novatel-gsm.c +++ b/plugins/mm-modem-novatel-gsm.c @@ -24,10 +24,13 @@ #include "mm-callback-info.h" #include "mm-modem-helpers.h" -static void modem_init (MMModem *modem_class); +G_DEFINE_TYPE (MMModemNovatelGsm, mm_modem_novatel_gsm, MM_TYPE_GENERIC_GSM) -G_DEFINE_TYPE_EXTENDED (MMModemNovatelGsm, mm_modem_novatel_gsm, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)) +#define MM_MODEM_NOVATEL_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_NOVATEL_GSM, MMModemNovatelGsmPrivate)) + +typedef struct { + gboolean dmat_sent; +} MMModemNovatelGsmPrivate; MMModem * @@ -78,34 +81,22 @@ dmat_callback (MMAtSerialPort *port, mm_serial_port_close (MM_SERIAL_PORT (port)); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port) && (ptype == MM_PORT_TYPE_PRIMARY)) { + MMModemNovatelGsm *self = MM_MODEM_NOVATEL_GSM (gsm); + MMModemNovatelGsmPrivate *priv = MM_MODEM_NOVATEL_GSM_GET_PRIVATE (self); + + if (MM_IS_AT_SERIAL_PORT (port) && !priv->dmat_sent) { /* Flip secondary ports to AT mode */ - if (mm_serial_port_open (MM_SERIAL_PORT (port), NULL)) + if (mm_serial_port_open (MM_SERIAL_PORT (port), NULL)) { mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "$NWDMAT=1", 2, dmat_callback, NULL); + priv->dmat_sent = TRUE; + } } - - return !!port; } /*****************************************************************************/ @@ -315,12 +306,6 @@ get_access_technology (MMGenericGsm *modem, /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void mm_modem_novatel_gsm_init (MMModemNovatelGsm *self) { } @@ -360,10 +345,12 @@ mm_modem_novatel_gsm_class_init (MMModemNovatelGsmClass *klass) MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); mm_modem_novatel_gsm_parent_class = g_type_class_peek_parent (klass); + g_type_class_add_private (object_class, sizeof (MMModemNovatelGsmPrivate)); object_class->get_property = get_property; object_class->set_property = set_property; + gsm_class->port_grabbed = port_grabbed; gsm_class->set_allowed_mode = set_allowed_mode; gsm_class->get_allowed_mode = get_allowed_mode; gsm_class->get_access_technology = get_access_technology; diff --git a/plugins/mm-modem-option-utils.c b/plugins/mm-modem-option-utils.c index 2316ee41..c4c39b27 100644 --- a/plugins/mm-modem-option-utils.c +++ b/plugins/mm-modem-option-utils.c @@ -430,7 +430,7 @@ option_change_unsolicited_messages (MMGenericGsm *modem, mm_callback_info_chain_start (info, 4); } - primary = mm_generic_gsm_get_at_port (modem, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (modem, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, enabled ? "_OSSYS=1" : "_OSSYS=0", 3, unsolicited_msg_done, info); diff --git a/plugins/mm-modem-option.c b/plugins/mm-modem-option.c index b15e7045..1b0d3631 100644 --- a/plugins/mm-modem-option.c +++ b/plugins/mm-modem-option.c @@ -179,30 +179,21 @@ disable (MMModem *modem, option_change_unsolicited_messages (MM_GENERIC_GSM (modem), FALSE, unsolicited_disable_done, info); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPort *port = NULL; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, suggested_type, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { - if (mm_port_get_port_type (port) == MM_PORT_TYPE_PRIMARY) { - GRegex *regex; - - regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); - g_regex_unref (regex); - } + GRegex *regex; + + if (MM_IS_AT_SERIAL_PORT (port)) { + regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); + g_regex_unref (regex); + option_register_unsolicted_handlers (gsm, MM_AT_SERIAL_PORT (port)); } - - return !!port; } /*****************************************************************************/ @@ -211,7 +202,6 @@ static void modem_init (MMModem *modem_class) { modem_class->disable = disable; - modem_class->grab_port = grab_port; } static void @@ -238,6 +228,7 @@ mm_modem_option_class_init (MMModemOptionClass *klass) g_type_class_add_private (object_class, sizeof (MMModemOptionPrivate)); object_class->dispose = dispose; + gsm_class->port_grabbed = port_grabbed; gsm_class->do_enable_power_up_done = real_do_enable_power_up_done; gsm_class->set_allowed_mode = set_allowed_mode; gsm_class->get_allowed_mode = get_allowed_mode; diff --git a/plugins/mm-modem-samsung-gsm.c b/plugins/mm-modem-samsung-gsm.c index 192a35b6..9162f213 100755 --- a/plugins/mm-modem-samsung-gsm.c +++ b/plugins/mm-modem-samsung-gsm.c @@ -428,7 +428,7 @@ disable (MMModem *modem, (GCallback)callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* @@ -533,7 +533,7 @@ do_enable (MMGenericGsm *modem, MMModemFn callback, gpointer user_data) info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); - primary = mm_generic_gsm_get_at_port (modem, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (modem, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "Z", 3, init_reset_done, info); } @@ -580,30 +580,13 @@ simple_connect (MMModemSimple *simple, parent_iface->connect (MM_MODEM_SIMPLE (simple), properties, callback, info); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) -{ - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!strcmp (subsys, "tty")) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) +{ + if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (port, MM_PORT_CARRIER_DETECT, FALSE, MM_SERIAL_PORT_SEND_DELAY, (guint64) 0, @@ -612,8 +595,6 @@ grab_port (MMModem *modem, /* Add Icera-specific handlers */ mm_modem_icera_register_unsolicted_handlers (MM_MODEM_ICERA (gsm), MM_AT_SERIAL_PORT (port)); } - - return !!port; } static void @@ -669,7 +650,6 @@ modem_init (MMModem *modem_class) modem_class->disable = disable; modem_class->connect = do_connect; modem_class->get_ip4_config = get_ip4_config; - modem_class->grab_port = grab_port; } static void @@ -728,7 +708,6 @@ mm_modem_samsung_gsm_class_init (MMModemSamsungGsmClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - MMGenericGsmClass *gsm_class = MM_GENERIC_GSM_CLASS (klass); mm_modem_samsung_gsm_parent_class = g_type_class_peek_parent (klass); @@ -737,9 +716,9 @@ mm_modem_samsung_gsm_class_init (MMModemSamsungGsmClass *klass) object_class->dispose = dispose; + gsm_class->port_grabbed = port_grabbed; gsm_class->do_disconnect = do_disconnect; gsm_class->do_enable = do_enable; - gsm_class->set_allowed_mode = set_allowed_mode; gsm_class->get_allowed_mode = get_allowed_mode; gsm_class->get_access_technology = get_access_technology; diff --git a/plugins/mm-modem-sierra-cdma.c b/plugins/mm-modem-sierra-cdma.c index faf36757..eccb3529 100644 --- a/plugins/mm-modem-sierra-cdma.c +++ b/plugins/mm-modem-sierra-cdma.c @@ -370,7 +370,7 @@ post_enable (MMGenericCdma *cdma, info = mm_callback_info_new (MM_MODEM (cdma), callback, user_data); - primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_cdma_get_at_port (cdma, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "!pcstate=1", 5, pcstate_done, info); @@ -386,7 +386,7 @@ post_disable (MMGenericCdma *cdma, info = mm_callback_info_new (MM_MODEM (cdma), callback, user_data); - primary = mm_generic_cdma_get_at_port (cdma, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_cdma_get_at_port (cdma, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "!pcstate=0", 5, pcstate_done, info); diff --git a/plugins/mm-modem-sierra-gsm.c b/plugins/mm-modem-sierra-gsm.c index 1a9b7351..9247eaed 100644 --- a/plugins/mm-modem-sierra-gsm.c +++ b/plugins/mm-modem-sierra-gsm.c @@ -163,7 +163,7 @@ get_allowed_mode (MMGenericGsm *gsm, info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); /* Sierra secondary ports don't have full AT command interpreters */ - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); if (!primary || mm_port_get_connected (MM_PORT (primary))) { g_set_error_literal (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED, "Cannot perform this operation while connected"); @@ -213,7 +213,7 @@ set_allowed_mode (MMGenericGsm *gsm, info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); /* Sierra secondary ports don't have full AT command interpreters */ - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); if (!primary || mm_port_get_connected (MM_PORT (primary))) { g_set_error_literal (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED, "Cannot perform this operation while connected"); @@ -433,6 +433,7 @@ real_do_enable_power_up_done (MMGenericGsm *gsm, MMCallbackInfo *info) { MMModemSierraGsmPrivate *priv = MM_MODEM_SIERRA_GSM_GET_PRIVATE (gsm); + char *driver = NULL; if (error) { /* Chain up to parent */ @@ -440,11 +441,17 @@ real_do_enable_power_up_done (MMGenericGsm *gsm, return; } - /* Some Sierra devices return OK on +CFUN=1 right away but need some time - * to finish initialization. + /* Old Sierra devices (like the PCMCIA-based 860) return OK on +CFUN=1 right + * away but need some time to finish initialization. Anything driven by + * 'sierra' is new enough to need no delay. */ - g_warn_if_fail (priv->enable_wait_id == 0); - priv->enable_wait_id = g_timeout_add_seconds (10, sierra_enabled, info); + g_object_get (G_OBJECT (gsm), MM_MODEM_DRIVER, &driver, NULL); + if (g_strcmp0 (driver, "sierra") == 0) + sierra_enabled (info); + else { + g_warn_if_fail (priv->enable_wait_id == 0); + priv->enable_wait_id = g_timeout_add_seconds (10, sierra_enabled, info); + } } static void @@ -497,7 +504,7 @@ do_enable_power_up_check_needed (MMGenericGsm *self, info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data); /* Get port */ - primary = mm_generic_gsm_get_at_port (self, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (self, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Get current functionality status */ @@ -505,47 +512,27 @@ do_enable_power_up_check_needed (MMGenericGsm *self, mm_at_serial_port_queue_command (primary, "+CFUN?", 3, get_current_functionality_status_cb, info); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) -{ - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - - if (port) { - if (MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) +{ + GRegex *regex; - g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); + if (MM_IS_AT_SERIAL_PORT (port)) { + g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); - regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); - g_regex_unref (regex); + regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL); + g_regex_unref (regex); - /* Add Icera-specific handlers */ - mm_modem_icera_register_unsolicted_handlers (MM_MODEM_ICERA (gsm), MM_AT_SERIAL_PORT (port)); - } else if (mm_port_get_subsys (port) == MM_PORT_SUBSYS_NET) { - MM_MODEM_SIERRA_GSM_GET_PRIVATE (gsm)->has_net = TRUE; - g_object_set (G_OBJECT (gsm), MM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_DHCP, NULL); - } + /* Add Icera-specific handlers */ + mm_modem_icera_register_unsolicted_handlers (MM_MODEM_ICERA (gsm), MM_AT_SERIAL_PORT (port)); + } else if (mm_port_get_subsys (port) == MM_PORT_SUBSYS_NET) { + MM_MODEM_SIERRA_GSM_GET_PRIVATE (gsm)->has_net = TRUE; + g_object_set (G_OBJECT (gsm), MM_MODEM_IP_METHOD, MM_MODEM_IP_METHOD_DHCP, NULL); } - - return !!port; } static void @@ -740,7 +727,7 @@ do_disconnect (MMGenericGsm *gsm, MMAtSerialPort *primary; char *command; - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* If we have a net interface, deactivate it */ @@ -801,7 +788,7 @@ do_disable (MMModem *modem, (GCallback)callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Turn off unsolicited responses */ @@ -872,7 +859,6 @@ get_icera_private (MMModemIcera *icera) static void modem_init (MMModem *modem_class) { - modem_class->grab_port = grab_port; modem_class->connect = do_connect; modem_class->disable = do_disable; modem_class->get_ip4_config = get_ip4_config; @@ -919,6 +905,7 @@ mm_modem_sierra_gsm_class_init (MMModemSierraGsmClass *klass) g_type_class_add_private (object_class, sizeof (MMModemSierraGsmPrivate)); object_class->dispose = dispose; + gsm_class->port_grabbed = port_grabbed; gsm_class->do_enable_power_up_check_needed = do_enable_power_up_check_needed; gsm_class->do_enable_power_up_done = real_do_enable_power_up_done; gsm_class->set_allowed_mode = set_allowed_mode; diff --git a/plugins/mm-modem-simtech-gsm.c b/plugins/mm-modem-simtech-gsm.c index 18df9c42..5b442d77 100644 --- a/plugins/mm-modem-simtech-gsm.c +++ b/plugins/mm-modem-simtech-gsm.c @@ -383,7 +383,7 @@ real_do_enable_power_up_done (MMGenericGsm *gsm, MMAtSerialPort *primary; /* Enable unsolicited result codes */ - primary = mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (gsm, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Autoreport access technology changes */ @@ -444,44 +444,26 @@ disable (MMModem *modem, (GCallback)callback, user_data); - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Turn off unsolicited responses */ mm_at_serial_port_queue_command (primary, "+CNSMOD=0;+AUTOCSQ=0", 5, disable_unsolicited_done, info); } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - - if (port && MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; + GRegex *regex; + if (MM_IS_AT_SERIAL_PORT (port)) { regex = g_regex_new ("\\r\\n\\+CNSMOD:\\s*(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_act_change, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_act_change, gsm, NULL); g_regex_unref (regex); } - - return !!port; } /*****************************************************************************/ @@ -490,7 +472,6 @@ static void modem_init (MMModem *modem_class) { modem_class->disable = disable; - modem_class->grab_port = grab_port; } static void @@ -505,6 +486,7 @@ mm_modem_simtech_gsm_class_init (MMModemSimtechGsmClass *klass) mm_modem_simtech_gsm_parent_class = g_type_class_peek_parent (klass); + gsm_class->port_grabbed = port_grabbed; gsm_class->do_enable_power_up_done = real_do_enable_power_up_done; gsm_class->set_allowed_mode = set_allowed_mode; gsm_class->get_allowed_mode = get_allowed_mode; diff --git a/plugins/mm-modem-wavecom-gsm.c b/plugins/mm-modem-wavecom-gsm.c index cba5288b..8b65426e 100644 --- a/plugins/mm-modem-wavecom-gsm.c +++ b/plugins/mm-modem-wavecom-gsm.c @@ -27,11 +27,9 @@ #include "mm-serial-parsers.h" #include "mm-log.h" -static void modem_init (MMModem *modem_class); static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class); G_DEFINE_TYPE_EXTENDED (MMModemWavecomGsm, mm_modem_wavecom_gsm, MM_TYPE_GENERIC_GSM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init) G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)) /* Bit flags for mobile station classes supported by the modem */ @@ -159,31 +157,16 @@ wavecom_ms_class_to_str (WavecomMSClass class) } } -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) { - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { - gpointer parser; - GRegex *regex; + gpointer parser; + GRegex *regex; + if (MM_IS_AT_SERIAL_PORT (port)) { parser = mm_serial_parser_v1_new (); /* AT+CPIN? replies will never have an OK appended */ @@ -198,8 +181,6 @@ grab_port (MMModem *modem, parser, mm_serial_parser_v1_destroy); } - - return !!port; } static void @@ -1131,7 +1112,7 @@ do_enable_power_up_check_needed (MMGenericGsm *self, info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data); /* Get port */ - primary = mm_generic_gsm_get_at_port (self, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (self, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Get current functionality status */ @@ -1142,12 +1123,6 @@ do_enable_power_up_check_needed (MMGenericGsm *self, /*****************************************************************************/ static void -modem_init (MMModem *modem_class) -{ - modem_class->grab_port = grab_port; -} - -static void modem_gsm_network_init (MMModemGsmNetwork *network_class) { network_class->set_band = set_band; @@ -1189,6 +1164,7 @@ mm_modem_wavecom_gsm_class_init (MMModemWavecomGsmClass *klass) MM_GENERIC_GSM_PROP_POWER_DOWN_CMD, MM_GENERIC_GSM_POWER_DOWN_CMD); + gsm_class->port_grabbed = port_grabbed; gsm_class->do_enable_power_up_check_needed = do_enable_power_up_check_needed; gsm_class->do_enable_power_up_done = do_enable_power_up_done; gsm_class->set_allowed_mode = set_allowed_mode; diff --git a/plugins/mm-modem-zte.c b/plugins/mm-modem-zte.c index 88ef7344..1a473f0b 100644 --- a/plugins/mm-modem-zte.c +++ b/plugins/mm-modem-zte.c @@ -352,7 +352,7 @@ cpms_timeout_cb (gpointer user_data) if (modem) { MM_MODEM_ZTE_GET_PRIVATE (modem)->cpms_timeout = 0; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); mm_at_serial_port_queue_command (primary, "+CPMS?", 10, cpms_try_done, info); } @@ -495,7 +495,7 @@ do_enable (MMGenericGsm *modem, MMModemFn callback, gpointer user_data) priv->init_retried = FALSE; - primary = mm_generic_gsm_get_at_port (modem, MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (modem, MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); info = mm_callback_info_new (MM_MODEM (modem), callback, user_data); @@ -552,7 +552,7 @@ disable (MMModem *modem, priv->init_retried = FALSE; - primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_PORT_TYPE_PRIMARY); + primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (modem), MM_AT_PORT_FLAG_PRIMARY); g_assert (primary); /* Turn off unsolicited responses */ @@ -620,30 +620,15 @@ simple_connect (MMModemSimple *simple, /*****************************************************************************/ -static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) -{ - MMGenericGsm *gsm = MM_GENERIC_GSM (modem); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port = NULL; - - if (suggested_type == MM_PORT_TYPE_UNKNOWN) { - if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY)) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY)) - ptype = MM_PORT_TYPE_SECONDARY; - } else - ptype = suggested_type; - - port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error); - if (port && MM_IS_AT_SERIAL_PORT (port)) { - GRegex *regex; +static void +port_grabbed (MMGenericGsm *gsm, + MMPort *port, + MMAtPortFlags pflags, + gpointer user_data) +{ + GRegex *regex; + if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (port, MM_PORT_CARRIER_DETECT, FALSE, NULL); regex = g_regex_new ("\\r\\n\\+ZUSIMR:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); @@ -657,7 +642,7 @@ grab_port (MMModem *modem, /* Current network and service domain */ regex = g_regex_new ("\\r\\n\\+ZPASR:\\s*(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, zte_access_tech_changed, modem, NULL); + mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, zte_access_tech_changed, gsm, NULL); g_regex_unref (regex); /* SIM request to Build Main Menu */ @@ -673,8 +658,6 @@ grab_port (MMModem *modem, /* Add Icera-specific handlers */ mm_modem_icera_register_unsolicted_handlers (MM_MODEM_ICERA (gsm), MM_AT_SERIAL_PORT (port)); } - - return !!port; } /*****************************************************************************/ @@ -706,7 +689,6 @@ modem_init (MMModem *modem_class) modem_class->disable = disable; modem_class->connect = do_connect; modem_class->get_ip4_config = get_ip4_config; - modem_class->grab_port = grab_port; } static void @@ -760,6 +742,7 @@ mm_modem_zte_class_init (MMModemZteClass *klass) g_type_class_add_private (object_class, sizeof (MMModemZtePrivate)); object_class->dispose = dispose; + gsm_class->port_grabbed = port_grabbed; gsm_class->do_enable = do_enable; gsm_class->do_disconnect = do_disconnect; gsm_class->set_allowed_mode = set_allowed_mode; diff --git a/plugins/mm-plugin-anydata.c b/plugins/mm-plugin-anydata.c index 90f05de0..8c701927 100644 --- a/plugins/mm-plugin-anydata.c +++ b/plugins/mm-plugin-anydata.c @@ -114,6 +114,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -138,6 +139,7 @@ grab_port (MMPluginBase *base, return NULL; } + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & CAP_CDMA) { @@ -151,19 +153,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; - - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-cinterion.c b/plugins/mm-plugin-cinterion.c index 5c14722f..9d0fb529 100644 --- a/plugins/mm-plugin-cinterion.c +++ b/plugins/mm-plugin-cinterion.c @@ -166,6 +166,7 @@ grab_port (MMPluginBase *base, guint32 caps; guint16 vendor = 0x1e2d; guint16 product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -178,6 +179,7 @@ grab_port (MMPluginBase *base, mm_plugin_base_get_device_ids (base, subsys, name, NULL, &product); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -189,14 +191,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-generic.c b/plugins/mm-plugin-generic.c index 54726202..46b9824a 100644 --- a/plugins/mm-plugin-generic.c +++ b/plugins/mm-plugin-generic.c @@ -117,6 +117,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path, *driver; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -144,6 +145,7 @@ grab_port (MMPluginBase *base, } caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & CAP_CDMA) { @@ -163,19 +165,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; - - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-gobi.c b/plugins/mm-plugin-gobi.c index 402f6b19..997c3836 100644 --- a/plugins/mm-plugin-gobi.c +++ b/plugins/mm-plugin-gobi.c @@ -50,6 +50,8 @@ get_level_for_capabilities (guint32 capabilities) return 10; if (capabilities & CAP_CDMA) return 10; + if (capabilities & MM_PLUGIN_BASE_PORT_CAP_QCDM) + return 10; return 0; } @@ -110,6 +112,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -123,6 +126,7 @@ grab_port (MMPluginBase *base, } caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -142,14 +146,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-hso.c b/plugins/mm-plugin-hso.c index 60d9863b..2b1a64c2 100644 --- a/plugins/mm-plugin-hso.c +++ b/plugins/mm-plugin-hso.c @@ -109,6 +109,8 @@ grab_port (MMPluginBase *base, char *devfile; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -140,11 +142,29 @@ grab_port (MMPluginBase *base, } } + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + + /* Detect port types */ + if (!strcmp (subsys, "tty")) { + char *hsotype_path; + char *contents = NULL; + + hsotype_path = g_build_filename (sysfs_path, "hsotype", NULL); + if (g_file_get_contents (hsotype_path, &contents, NULL, NULL)) { + if (g_str_has_prefix (contents, "Control")) + pflags = MM_AT_PORT_FLAG_PRIMARY; + else if (g_str_has_prefix (contents, "Application") || g_str_has_prefix (contents, "Application2")) + pflags = MM_AT_PORT_FLAG_SECONDARY; /* secondary */ + g_free (contents); + } + g_free (hsotype_path); + } + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net")) goto out; - sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { modem = mm_modem_hso_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), @@ -152,14 +172,14 @@ grab_port (MMPluginBase *base, vendor, product); if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-huawei.c b/plugins/mm-plugin-huawei.c index e6c02d47..7eebc330 100644 --- a/plugins/mm-plugin-huawei.c +++ b/plugins/mm-plugin-huawei.c @@ -17,6 +17,7 @@ #include <string.h> #include <stdlib.h> #include <gmodule.h> +#include <errno.h> #define G_UDEV_API_IS_SUBJECT_TO_CHANGE #include <gudev/gudev.h> @@ -47,6 +48,9 @@ mm_plugin_create (void) /*****************************************************************************/ #define TAG_HUAWEI_PCUI_PORT "huawei-pcui-port" +#define TAG_HUAWEI_MODEM_PORT "huawei-modem-port" +#define TAG_HUAWEI_DIAG_PORT "huawei-diag-port" +#define TAG_GETPORTMODE_SUPPORTED "getportmode-supported" #define CAP_CDMA (MM_PLUGIN_BASE_PORT_CAP_IS707_A | \ MM_PLUGIN_BASE_PORT_CAP_IS707_P | \ @@ -74,6 +78,23 @@ probe_result (MMPluginBase *base, mm_plugin_base_supports_task_complete (task, get_level_for_capabilities (capabilities)); } +static void +cache_port_mode (MMPlugin *plugin, const char *reply, const char *type, const char *tag) +{ + char *p; + long i; + + /* Get the USB interface number of the PCUI port */ + p = strstr (reply, type); + if (p) { + errno = 0; + /* shift by 1 so NULL return from g_object_get_data() means no tag */ + i = 1 + strtol (p + strlen (type), NULL, 10); + if (i > 0 && i < 256 && errno == 0) + g_object_set_data (G_OBJECT (plugin), tag, GINT_TO_POINTER ((int) i)); + } +} + static gboolean getportmode_response_cb (MMPluginBaseSupportsTask *task, GString *response, @@ -90,21 +111,13 @@ getportmode_response_cb (MMPluginBaseSupportsTask *task, if (g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_UNKNOWN) == FALSE) return tries <= 4 ? TRUE : FALSE; } else { - MMPlugin *plugin; - char *p; - int i = 0; - - /* Get the USB interface number of the PCUI port */ - p = strstr (response->str, "PCUI:"); - if (p) - i = atoi (p + strlen ("PCUI:")); - - if (i) { - /* Save they PCUI port number for later */ - plugin = mm_plugin_base_supports_task_get_plugin (task); - g_assert (plugin); - g_object_set_data (G_OBJECT (plugin), TAG_HUAWEI_PCUI_PORT, GINT_TO_POINTER (i)); - } + MMPlugin *plugin = mm_plugin_base_supports_task_get_plugin (task); + + cache_port_mode (plugin, response->str, "PCUI:", TAG_HUAWEI_PCUI_PORT); + cache_port_mode (plugin, response->str, "MDM:", TAG_HUAWEI_MODEM_PORT); + cache_port_mode (plugin, response->str, "DIAG:", TAG_HUAWEI_DIAG_PORT); + + g_object_set_data (G_OBJECT (plugin), TAG_GETPORTMODE_SUPPORTED, GUINT_TO_POINTER (1)); } /* No error or if ^GETPORTMODE is not supported, assume success */ @@ -221,6 +234,9 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; + int usbif; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -239,7 +255,32 @@ grab_port (MMPluginBase *base, return NULL; } + usbif = g_udev_device_get_property_as_int (port, "ID_USB_INTERFACE_NUM"); + if (usbif < 0) { + g_set_error (error, 0, 0, "Could not get USB device interface number."); + return NULL; + } + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); + + if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (base), TAG_HUAWEI_PCUI_PORT))) + pflags = MM_AT_PORT_FLAG_PRIMARY; + else if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (base), TAG_HUAWEI_MODEM_PORT))) + pflags = MM_AT_PORT_FLAG_PPP; + else if (!g_object_get_data (G_OBJECT (base), TAG_GETPORTMODE_SUPPORTED)) { + /* If GETPORTMODE is not supported, we assume usbif 0 is the modem port */ + if ((usbif == 0) && (ptype == MM_PORT_TYPE_AT)) { + pflags = MM_AT_PORT_FLAG_PPP; + + /* For CDMA modems we assume usbif0 is both primary and PPP, since + * they don't have problems with talking on secondary ports. + */ + if (caps & CAP_CDMA) + pflags |= MM_AT_PORT_FLAG_PRIMARY; + } + } + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -259,32 +300,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else { - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; - int pcui_usbif, port_usbif; - - /* Any additional AT ports can be secondary ports, but we want to ensure - * that the "pcui" port found from ^GETPORTMODE above is always set as - * a secondary port too. - */ - - port_usbif = g_udev_device_get_property_as_int (port, "ID_USB_INTERFACE_NUM"); - pcui_usbif = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (base), TAG_HUAWEI_PCUI_PORT)); - - if ( (port_usbif == pcui_usbif) - || (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) - || (caps & CAP_CDMA)) - ptype = MM_PORT_TYPE_SECONDARY; - else if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-linktop.c b/plugins/mm-plugin-linktop.c index 0421dfd6..874e355a 100644 --- a/plugins/mm-plugin-linktop.c +++ b/plugins/mm-plugin-linktop.c @@ -105,6 +105,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -124,6 +125,7 @@ grab_port (MMPluginBase *base, } caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -135,14 +137,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-longcheer.c b/plugins/mm-plugin-longcheer.c index 1570cf4b..5a93d468 100644 --- a/plugins/mm-plugin-longcheer.c +++ b/plugins/mm-plugin-longcheer.c @@ -173,7 +173,8 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; guint16 vendor = 0, product = 0; port = mm_plugin_base_supports_task_get_port (task); @@ -184,15 +185,18 @@ grab_port (MMPluginBase *base, * what the Windows .INF files say the port layout should be. */ if (g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_PORT_TYPE_MODEM")) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_PORT_TYPE_AUX")) - ptype = MM_PORT_TYPE_SECONDARY; + pflags = MM_AT_PORT_FLAG_SECONDARY; - /* If the device was tagged by the udev rules, then ignore any other ports - * to guard against race conditions if a device just happens to show up - * with more than two AT-capable ports. + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); + + /* If the port was tagged by the udev rules but isn't a primary or secondary, + * then ignore it to guard against race conditions if a device just happens + * to show up with more than two AT-capable ports. */ - if ( (ptype == MM_PORT_TYPE_UNKNOWN) + if ( (pflags == MM_AT_PORT_FLAG_NONE) && g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; @@ -204,7 +208,6 @@ grab_port (MMPluginBase *base, return NULL; } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -224,17 +227,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-mbm.c b/plugins/mm-plugin-mbm.c index 20ee99e9..b6da50bb 100644 --- a/plugins/mm-plugin-mbm.c +++ b/plugins/mm-plugin-mbm.c @@ -136,6 +136,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -153,6 +154,7 @@ grab_port (MMPluginBase *base, } sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { modem = mm_modem_mbm_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), @@ -160,14 +162,14 @@ grab_port (MMPluginBase *base, vendor, product); if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-moto-c.c b/plugins/mm-plugin-moto-c.c index 265630c0..e8cfe0e3 100644 --- a/plugins/mm-plugin-moto-c.c +++ b/plugins/mm-plugin-moto-c.c @@ -109,6 +109,8 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint16 vendor = 0, product = 0; + guint32 caps; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -127,6 +129,8 @@ grab_port (MMPluginBase *base, return NULL; } + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { modem = mm_modem_moto_c_gsm_new (sysfs_path, @@ -136,14 +140,14 @@ grab_port (MMPluginBase *base, product); if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-nokia.c b/plugins/mm-plugin-nokia.c index 8cfa9936..493400ca 100644 --- a/plugins/mm-plugin-nokia.c +++ b/plugins/mm-plugin-nokia.c @@ -135,7 +135,8 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -156,12 +157,13 @@ grab_port (MMPluginBase *base, /* Look for port type hints */ if (g_udev_device_get_property_as_boolean (port, "ID_MM_NOKIA_PORT_TYPE_MODEM")) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_NOKIA_PORT_TYPE_AUX")) - ptype = MM_PORT_TYPE_SECONDARY; + pflags = MM_AT_PORT_FLAG_SECONDARY; caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_nokia_new (sysfs_path, @@ -180,14 +182,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-novatel.c b/plugins/mm-plugin-novatel.c index 3b2b780f..7c10f3e0 100644 --- a/plugins/mm-plugin-novatel.c +++ b/plugins/mm-plugin-novatel.c @@ -119,6 +119,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -139,6 +140,7 @@ grab_port (MMPluginBase *base, caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_novatel_gsm_new (sysfs_path, @@ -157,19 +159,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; - - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-option.c b/plugins/mm-plugin-option.c index 8c16879a..0f90a4e7 100644 --- a/plugins/mm-plugin-option.c +++ b/plugins/mm-plugin-option.c @@ -110,7 +110,8 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; int usbif; - MMPortType ptype = MM_PORT_TYPE_SECONDARY; + MMPortType ptype; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; guint16 vendor = 0, product = 0; port = mm_plugin_base_supports_task_get_port (task); @@ -122,9 +123,6 @@ grab_port (MMPluginBase *base, return NULL; } - subsys = g_udev_device_get_subsystem (port); - name = g_udev_device_get_name (port); - /* This is the MM equivalent of NM commit 9d7f5b3d084eee2ccfff721c4beca3e3f34bdc50; * Genuine Option NV devices are always supposed to use USB interface 0 as * the modem/data port, per mail with Option engineers. Only this port @@ -132,8 +130,10 @@ grab_port (MMPluginBase *base, */ usbif = g_udev_device_get_property_as_int (port, "ID_USB_INTERFACE_NUM"); if (usbif == 0) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY | MM_AT_PORT_FLAG_PPP; + subsys = g_udev_device_get_subsystem (port); + name = g_udev_device_get_name (port); if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) { g_set_error (error, 0, 0, "Could not get modem product ID."); return NULL; @@ -141,6 +141,7 @@ grab_port (MMPluginBase *base, caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_option_new (sysfs_path, @@ -151,17 +152,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-samsung.c b/plugins/mm-plugin-samsung.c index 9ea2051e..6c39cded 100755 --- a/plugins/mm-plugin-samsung.c +++ b/plugins/mm-plugin-samsung.c @@ -110,6 +110,7 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; guint32 caps; const char *name, *subsys, *sysfs_path; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -123,6 +124,7 @@ grab_port (MMPluginBase *base, return NULL; } + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { modem = mm_modem_samsung_gsm_new (sysfs_path, @@ -130,14 +132,14 @@ grab_port (MMPluginBase *base, mm_plugin_get_name (MM_PLUGIN (base))); if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-sierra.c b/plugins/mm-plugin-sierra.c index 9f786b74..4565c68e 100644 --- a/plugins/mm-plugin-sierra.c +++ b/plugins/mm-plugin-sierra.c @@ -35,7 +35,8 @@ mm_plugin_create (void) /*****************************************************************************/ -#define TAG_SIERRA_SECONDARY_PORT "sierra-secondary-port" +#define TAG_SIERRA_APP1_PORT "sierra-app1-port" +#define TAG_SIERRA_APP_PPP_OK "sierra-app-ppp-ok" #define CAP_CDMA (MM_PLUGIN_BASE_PORT_CAP_IS707_A | \ MM_PLUGIN_BASE_PORT_CAP_IS707_P | \ @@ -64,8 +65,16 @@ handle_probe_response (MMPluginBase *self, return; } - if (strstr (response, "APP1") || strstr (response, "APP2") || strstr (response, "APP3")) { - g_object_set_data (G_OBJECT (task), TAG_SIERRA_SECONDARY_PORT, GUINT_TO_POINTER (TRUE)); + if (strstr (response, "APP1")) { + g_object_set_data (G_OBJECT (task), TAG_SIERRA_APP1_PORT, GUINT_TO_POINTER (TRUE)); + + /* 885 can handle PPP on the APP ports, leaving the primary port open + * for command and status while connected. Older modems (ie 8775) say + * they can but fail during PPP. + */ + if (strstr (response, "C885")) + g_object_set_data (G_OBJECT (task), TAG_SIERRA_APP_PPP_OK, GUINT_TO_POINTER (TRUE)); + mm_plugin_base_supports_task_complete (task, 10); return; } @@ -141,8 +150,9 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; guint16 vendor = 0, product = 0; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -150,16 +160,29 @@ grab_port (MMPluginBase *base, subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); + /* Is it a GSM secondary port? */ - if (g_object_get_data (G_OBJECT (task), TAG_SIERRA_SECONDARY_PORT)) - ptype = MM_PORT_TYPE_SECONDARY; + if (g_object_get_data (G_OBJECT (task), TAG_SIERRA_APP1_PORT)) { + if (g_object_get_data (G_OBJECT (task), TAG_SIERRA_APP_PPP_OK)) + pflags = MM_AT_PORT_FLAG_PPP; + else + pflags = MM_AT_PORT_FLAG_SECONDARY; + + /* Secondary ports may not be tagged as AT since they only speak a + * limited command set. But we know they're AT if they are tagged + * as secondary ports. + */ + ptype = MM_PORT_TYPE_AT; + } else if (ptype == MM_PORT_TYPE_AT) + pflags = MM_AT_PORT_FLAG_PRIMARY; if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) { g_set_error (error, 0, 0, "Could not get modem product ID."); return NULL; } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if ((caps & MM_PLUGIN_BASE_PORT_CAP_GSM) || (ptype != MM_PORT_TYPE_UNKNOWN)) { @@ -179,7 +202,7 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } @@ -195,7 +218,7 @@ grab_port (MMPluginBase *base, return modem; modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-simtech.c b/plugins/mm-plugin-simtech.c index 76ab33d2..1eb28229 100644 --- a/plugins/mm-plugin-simtech.c +++ b/plugins/mm-plugin-simtech.c @@ -116,8 +116,9 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; guint16 vendor = 0, product = 0; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -127,15 +128,18 @@ grab_port (MMPluginBase *base, * what the Windows .INF files say the port layout should be. */ if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_MODEM")) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_AUX")) - ptype = MM_PORT_TYPE_SECONDARY; + pflags = MM_AT_PORT_FLAG_SECONDARY; - /* If the device was tagged by the udev rules, then ignore any other ports - * to guard against race conditions if a device just happens to show up - * with more than two AT-capable ports. + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); + + /* If the port was tagged by the udev rules but isn't a primary or secondary, + * then ignore it to guard against race conditions if a device just happens + * to show up with more than two AT-capable ports. */ - if ( (ptype == MM_PORT_TYPE_UNKNOWN) + if ( (pflags == MM_AT_PORT_FLAG_NONE) && g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; @@ -147,7 +151,6 @@ grab_port (MMPluginBase *base, return NULL; } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -167,17 +170,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-wavecom.c b/plugins/mm-plugin-wavecom.c index f17aa988..3bd82cbd 100644 --- a/plugins/mm-plugin-wavecom.c +++ b/plugins/mm-plugin-wavecom.c @@ -110,6 +110,7 @@ grab_port (MMPluginBase *base, const char *name, *subsys, *sysfs_path; guint32 caps; guint16 vendor = 0, product = 0; + MMPortType ptype; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -123,6 +124,7 @@ grab_port (MMPluginBase *base, } caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -134,14 +136,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, MM_PORT_TYPE_UNKNOWN, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-x22x.c b/plugins/mm-plugin-x22x.c index 10a1b4c8..dfac6649 100644 --- a/plugins/mm-plugin-x22x.c +++ b/plugins/mm-plugin-x22x.c @@ -168,8 +168,9 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; guint16 vendor = 0, product = 0; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); @@ -179,15 +180,18 @@ grab_port (MMPluginBase *base, * what the Windows .INF files say the port layout should be. */ if (g_udev_device_get_property_as_boolean (port, "ID_MM_X22X_PORT_TYPE_MODEM")) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_X22X_PORT_TYPE_AUX")) - ptype = MM_PORT_TYPE_SECONDARY; + pflags = MM_AT_PORT_FLAG_SECONDARY; - /* If the device was tagged by the udev rules, then ignore any other ports - * to guard against race conditions if a device just happens to show up - * with more than two AT-capable ports. + caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); + + /* If the port was tagged by the udev rules but isn't a primary or secondary, + * then ignore it to guard against race conditions if a device just happens + * to show up with more than two AT-capable ports. */ - if ( (ptype == MM_PORT_TYPE_UNKNOWN) + if ( (pflags == MM_AT_PORT_FLAG_NONE) && g_udev_device_get_property_as_boolean (port, "ID_MM_X22X_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; @@ -199,7 +203,6 @@ grab_port (MMPluginBase *base, return NULL; } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { @@ -211,17 +214,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps)) { - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/plugins/mm-plugin-zte.c b/plugins/mm-plugin-zte.c index 6329c3ab..3db4936d 100644 --- a/plugins/mm-plugin-zte.c +++ b/plugins/mm-plugin-zte.c @@ -156,7 +156,8 @@ grab_port (MMPluginBase *base, MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; - MMPortType ptype = MM_PORT_TYPE_UNKNOWN; + MMPortType ptype; + MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE; guint16 vendor = 0, product = 0; port = mm_plugin_base_supports_task_get_port (task); @@ -164,9 +165,9 @@ grab_port (MMPluginBase *base, /* Look for port type hints */ if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_MODEM")) - ptype = MM_PORT_TYPE_PRIMARY; + pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX")) - ptype = MM_PORT_TYPE_SECONDARY; + pflags = MM_AT_PORT_FLAG_SECONDARY; subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -178,6 +179,7 @@ grab_port (MMPluginBase *base, caps = mm_plugin_base_supports_task_get_probed_capabilities (task); sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); + ptype = mm_plugin_base_probed_capabilities_to_port_type (caps); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_zte_new (sysfs_path, @@ -196,17 +198,14 @@ grab_port (MMPluginBase *base, } if (modem) { - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps) || (!strcmp (subsys, "net"))) { - if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) - ptype = MM_PORT_TYPE_QCDM; - modem = existing; - if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) + if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) return NULL; } diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c index cd4bb133..378c79f0 100644 --- a/src/mm-at-serial-port.c +++ b/src/mm-at-serial-port.c @@ -35,6 +35,7 @@ typedef struct { gpointer response_parser_user_data; GDestroyNotify response_parser_notify; GSList *unsolicited_msg_handlers; + MMAtPortFlags flags; } MMAtSerialPortPrivate; @@ -325,15 +326,34 @@ debug_log (MMSerialPort *port, const char *prefix, const char *buf, gsize len) g_string_truncate (debug, 0); } +void +mm_at_serial_port_set_flags (MMAtSerialPort *self, MMAtPortFlags flags) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_AT_SERIAL_PORT (self)); + g_return_if_fail (flags <= (MM_AT_PORT_FLAG_PRIMARY | MM_AT_PORT_FLAG_SECONDARY | MM_AT_PORT_FLAG_PPP)); + + MM_AT_SERIAL_PORT_GET_PRIVATE (self)->flags = flags; +} + +MMAtPortFlags +mm_at_serial_port_get_flags (MMAtSerialPort *self) +{ + g_return_val_if_fail (self != NULL, MM_AT_PORT_FLAG_NONE); + g_return_val_if_fail (MM_IS_AT_SERIAL_PORT (self), MM_AT_PORT_FLAG_NONE); + + return MM_AT_SERIAL_PORT_GET_PRIVATE (self)->flags; +} + /*****************************************************************************/ MMAtSerialPort * -mm_at_serial_port_new (const char *name, MMPortType ptype) +mm_at_serial_port_new (const char *name) { return MM_AT_SERIAL_PORT (g_object_new (MM_TYPE_AT_SERIAL_PORT, MM_PORT_DEVICE, name, MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY, - MM_PORT_TYPE, ptype, + MM_PORT_TYPE, MM_PORT_TYPE_AT, NULL)); } diff --git a/src/mm-at-serial-port.h b/src/mm-at-serial-port.h index 689c184f..5a631f95 100644 --- a/src/mm-at-serial-port.h +++ b/src/mm-at-serial-port.h @@ -32,6 +32,24 @@ typedef struct _MMAtSerialPort MMAtSerialPort; typedef struct _MMAtSerialPortClass MMAtSerialPortClass; +/* AT port flags; for example consider a device with two AT ports (ACM0 and ACM1) + * which could have the following layouts: + * + * ACM0(PRIMARY | PPP), ACM1(SECONDARY): port 0 is used for command and status + * and for PPP data; while connected port 1 is used for command and status + * ACM0(PPP), ACM1(PRIMARY): port 1 is always used for command and status, and + * only when connecting is port 0 opened for dialing (ATD) and PPP + */ +typedef enum { + MM_AT_PORT_FLAG_NONE = 0x0000, + /* This port is preferred for command and status */ + MM_AT_PORT_FLAG_PRIMARY = 0x0001, + /* Use port for command and status if the primary port is connected */ + MM_AT_PORT_FLAG_SECONDARY = 0x0002, + /* This port should be used for PPP */ + MM_AT_PORT_FLAG_PPP = 0x0004 +} MMAtPortFlags; + typedef gboolean (*MMAtSerialResponseParserFn) (gpointer user_data, GString *response, GError **error); @@ -55,7 +73,7 @@ struct _MMAtSerialPortClass { GType mm_at_serial_port_get_type (void); -MMAtSerialPort *mm_at_serial_port_new (const char *name, MMPortType ptype); +MMAtSerialPort *mm_at_serial_port_new (const char *name); void mm_at_serial_port_add_unsolicited_msg_handler (MMAtSerialPort *self, GRegex *regex, @@ -83,4 +101,9 @@ void mm_at_serial_port_queue_command_cached (MMAtSerialPort *self, /* Just for unit tests */ void mm_at_serial_port_remove_echo (GByteArray *response); +void mm_at_serial_port_set_flags (MMAtSerialPort *self, + MMAtPortFlags flags); + +MMAtPortFlags mm_at_serial_port_get_flags (MMAtSerialPort *self); + #endif /* MM_AT_SERIAL_PORT_H */ diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index 523ddee0..5397ce95 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -97,6 +97,7 @@ typedef struct { MMAtSerialPort *secondary; MMQcdmSerialPort *qcdm; MMPort *data; + gboolean data_opened_at_connect; } MMGenericCdmaPrivate; enum { @@ -230,85 +231,56 @@ owns_port (MMModem *modem, const char *subsys, const char *name) return !!mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name); } -MMPort * -mm_generic_cdma_grab_port (MMGenericCdma *self, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +static void +port_grabbed (MMModemBase *base, + MMPort *port, + MMAtPortFlags at_pflags, + gpointer user_data) { - MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - MMPort *port; - - g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), FALSE); - if (priv->primary) - g_return_val_if_fail (suggested_type != MM_PORT_TYPE_PRIMARY, FALSE); - - if (!strcmp (subsys, "tty")) { - if (suggested_type != MM_PORT_TYPE_UNKNOWN) - ptype = suggested_type; - else { - if (!priv->primary) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!priv->secondary) - ptype = MM_PORT_TYPE_SECONDARY; - } - } - - port = mm_modem_base_add_port (MM_MODEM_BASE (self), subsys, name, ptype); - if (!port) { - g_warn_if_fail (port != NULL); - return NULL; - } + MMGenericCdma *self = MM_GENERIC_CDMA (base); if (MM_IS_AT_SERIAL_PORT (port)) { g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL); + mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags); + mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port), mm_serial_parser_v1_e1_parse, mm_serial_parser_v1_e1_new (), mm_serial_parser_v1_e1_destroy); - - if (ptype == MM_PORT_TYPE_PRIMARY) { - priv->primary = MM_AT_SERIAL_PORT (port); - if (!priv->data) { - priv->data = port; - g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); - } - - /* Get the modem's general info */ - initial_info_check (self); - - /* Get modem's ESN number */ - initial_esn_check (self); - - } else if (ptype == MM_PORT_TYPE_SECONDARY) - priv->secondary = MM_AT_SERIAL_PORT (port); - } else if (MM_IS_QCDM_SERIAL_PORT (port)) { - if (!priv->qcdm) - priv->qcdm = MM_QCDM_SERIAL_PORT (port); - } else if (!strcmp (subsys, "net")) { - /* Net device (if any) is the preferred data port */ - if (!priv->data || MM_IS_AT_SERIAL_PORT (priv->data)) { - priv->data = port; - g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); - check_valid (self); - } } - return port; + if (MM_GENERIC_CDMA_GET_CLASS (self)->port_grabbed) + MM_GENERIC_CDMA_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data); } static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +organize_ports (MMModem *modem, GError **error) { - return !!mm_generic_cdma_grab_port (MM_GENERIC_CDMA (modem), subsys, name, suggested_type, user_data, error); + MMGenericCdma *self = MM_GENERIC_CDMA (modem); + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + + if (!mm_modem_base_organize_ports (MM_MODEM_BASE (modem), + &priv->primary, + &priv->secondary, + &priv->data, + &priv->qcdm, + error)) + return FALSE; + + /* Let subclasses twiddle ports if they want */ + if (MM_GENERIC_CDMA_GET_CLASS (self)->ports_organized) + MM_GENERIC_CDMA_GET_CLASS (self)->ports_organized (self, priv->primary); + + g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); + + /* Get the modem's general info */ + initial_info_check (self); + + /* Get modem's ESN number */ + initial_esn_check (self); + + check_valid (self); + return TRUE; } static void @@ -346,15 +318,26 @@ release_port (MMModem *modem, const char *subsys, const char *name) MMAtSerialPort * mm_generic_cdma_get_at_port (MMGenericCdma *modem, - MMPortType ptype) + MMAtPortFlags flag) { + MMGenericCdmaPrivate *priv; + g_return_val_if_fail (MM_IS_GENERIC_CDMA (modem), NULL); - g_return_val_if_fail (ptype != MM_PORT_TYPE_UNKNOWN, NULL); - if (ptype == MM_PORT_TYPE_PRIMARY) - return MM_GENERIC_CDMA_GET_PRIVATE (modem)->primary; - else if (ptype == MM_PORT_TYPE_SECONDARY) - return MM_GENERIC_CDMA_GET_PRIVATE (modem)->secondary; + /* We only search for a single value even though it's a bitfield */ + g_return_val_if_fail ( flag == MM_AT_PORT_FLAG_NONE + || flag == MM_AT_PORT_FLAG_PRIMARY + || flag == MM_AT_PORT_FLAG_SECONDARY + || flag == MM_AT_PORT_FLAG_PPP, NULL); + + priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); + + if (flag == MM_AT_PORT_FLAG_SECONDARY) + return priv->secondary; + else if (flag == MM_AT_PORT_FLAG_PRIMARY) + return priv->primary; + else if ((flag == MM_AT_PORT_FLAG_PPP) && MM_IS_AT_SERIAL_PORT (priv->data)) + return MM_AT_SERIAL_PORT (priv->data); return NULL; } @@ -872,12 +855,31 @@ connect (MMModem *modem, MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; char *command; + MMAtSerialPort *dial_port; + + info = mm_callback_info_new (modem, callback, user_data); + + /* Dial port might not be the primary port*/ + priv->data_opened_at_connect = FALSE; + dial_port = priv->primary; + if (MM_IS_AT_SERIAL_PORT (priv->data)) { + dial_port = MM_AT_SERIAL_PORT (priv->data); + + if (!mm_serial_port_open (MM_SERIAL_PORT (dial_port), &info->error)) { + g_warning ("%s: failed to open dial port: (%d) %s", + __func__, + info->error ? info->error->code : -1, + info->error && info->error->message ? info->error->message : "(unknown)"); + mm_callback_info_schedule (info); + return; + } + priv->data_opened_at_connect = TRUE; + } mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE); - info = mm_callback_info_new (modem, callback, user_data); command = g_strconcat ("DT", number, NULL); - mm_at_serial_port_queue_command (priv->primary, command, 90, dial_done, info); + mm_at_serial_port_queue_command (dial_port, command, 90, dial_done, info); g_free (command); } @@ -887,6 +889,8 @@ disconnect_flash_done (MMSerialPort *port, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; + MMGenericCdma *self; + MMGenericCdmaPrivate *priv; MMModemState prev_state; /* If the modem has already been removed, return without @@ -894,6 +898,8 @@ disconnect_flash_done (MMSerialPort *port, if (mm_callback_info_check_modem_removed (info)) return; + self = MM_GENERIC_CDMA (info->modem); + priv = MM_GENERIC_CDMA_GET_PRIVATE (self); if (error) { info->error = g_error_copy (error); @@ -903,8 +909,18 @@ disconnect_flash_done (MMSerialPort *port, prev_state, MM_MODEM_STATE_REASON_NONE); } else { - mm_port_set_connected (MM_GENERIC_CDMA_GET_PRIVATE (info->modem)->data, FALSE); - update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE); + mm_port_set_connected (priv->data, FALSE); + update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE); + } + + /* Balance any open from connect(); subclasses may not use the generic + * class' connect function and so the dial port may not have been + * opened at all. + */ + if (priv->data_opened_at_connect) { + if (MM_IS_AT_SERIAL_PORT (port)) + mm_serial_port_close (port); + priv->data_opened_at_connect = FALSE; } mm_callback_info_schedule (info); @@ -918,6 +934,7 @@ disconnect (MMModem *modem, MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; MMModemState state; + MMAtSerialPort *dial_port; g_return_if_fail (priv->primary != NULL); @@ -931,7 +948,12 @@ disconnect (MMModem *modem, NULL); mm_modem_set_state (modem, MM_MODEM_STATE_DISCONNECTING, MM_MODEM_STATE_REASON_NONE); - mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, TRUE, disconnect_flash_done, info); + + dial_port = priv->primary; + if (MM_IS_AT_SERIAL_PORT (priv->data)) + dial_port = MM_AT_SERIAL_PORT (priv->data); + + mm_serial_port_flash (MM_SERIAL_PORT (dial_port), 1000, TRUE, disconnect_flash_done, info); } static void @@ -2439,7 +2461,7 @@ static void modem_init (MMModem *modem_class) { modem_class->owns_port = owns_port; - modem_class->grab_port = grab_port; + modem_class->organize_ports = organize_ports; modem_class->release_port = release_port; modem_class->enable = enable; modem_class->disable = disable; @@ -2551,18 +2573,20 @@ dispose (GObject *object) } static void -mm_generic_cdma_class_init (MMGenericCdmaClass *klass) +mm_generic_cdma_class_init (MMGenericCdmaClass *generic_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (generic_class); + MMModemBaseClass *base_class = MM_MODEM_BASE_CLASS (generic_class); - mm_generic_cdma_parent_class = g_type_class_peek_parent (klass); + mm_generic_cdma_parent_class = g_type_class_peek_parent (generic_class); g_type_class_add_private (object_class, sizeof (MMGenericCdmaPrivate)); /* Virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; - klass->query_registration_state = real_query_registration_state; + base_class->port_grabbed = port_grabbed; + generic_class->query_registration_state = real_query_registration_state; /* Properties */ g_object_class_override_property (object_class, diff --git a/src/mm-generic-cdma.h b/src/mm-generic-cdma.h index 350c58ed..ba7b76f8 100644 --- a/src/mm-generic-cdma.h +++ b/src/mm-generic-cdma.h @@ -43,6 +43,23 @@ typedef struct { typedef struct { MMModemBaseClass parent; + /* Called to allow subclasses to update port flags, attach unsolicited + * result code handlers, change port attributes, etc. This is called + * after the generic class has installed it's own handlers; if the + * generic class' behavior is not desired, subclasses can override the + * port_grabbed() method of MMModemBase. + */ + void (*port_grabbed) (MMGenericCdma *self, + MMPort *port, + MMAtPortFlags at_pflags, + gpointer user_data); + + /* Called after all ports have been organized to allow subclasses to + * make changes to ports after we've assigned primary, secondary, and data + * designations. + */ + void (*ports_organized) (MMGenericCdma *self, MMAtSerialPort *primary); + /* Subclasses should implement this function if they can more accurately * determine the registration state and/or roaming status than the base * class can (by using manufacturer custom AT commands or whatever). @@ -94,14 +111,8 @@ MMModem *mm_generic_cdma_new (const char *device, /* Private, for subclasses */ -MMPort * mm_generic_cdma_grab_port (MMGenericCdma *self, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error); - -MMAtSerialPort *mm_generic_cdma_get_at_port (MMGenericCdma *modem, MMPortType ptype); +/* Returns the first port (if any) which has the given flag */ +MMAtSerialPort *mm_generic_cdma_get_at_port (MMGenericCdma *modem, MMAtPortFlags flag); MMAtSerialPort *mm_generic_cdma_get_best_at_port (MMGenericCdma *modem, GError **error); diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 568cc8fd..0a0a2a1a 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -11,7 +11,7 @@ * GNU General Public License for more details: * * Copyright (C) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2012 Red Hat, Inc. * Copyright (C) 2009 - 2010 Ericsson */ @@ -116,6 +116,7 @@ typedef struct { MMAtSerialPort *secondary; MMQcdmSerialPort *qcdm; MMPort *data; + gboolean data_opened_at_connect; /* Location API */ guint32 loc_caps; @@ -843,39 +844,28 @@ owns_port (MMModem *modem, const char *subsys, const char *name) return !!mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name); } -MMPort * -mm_generic_gsm_grab_port (MMGenericGsm *self, - const char *subsys, - const char *name, - MMPortType ptype, - GError **error) +static void +port_grabbed (MMModemBase *base, + MMPort *port, + MMAtPortFlags at_pflags, + gpointer user_data) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); - MMPort *port = NULL; + MMGenericGsm *self = MM_GENERIC_GSM (base); + GPtrArray *array; GRegex *regex; - - g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), FALSE); - - port = mm_modem_base_add_port (MM_MODEM_BASE (self), subsys, name, ptype); - if (!port) { - g_warn_if_fail (port != NULL); - return NULL; - } + int i; if (MM_IS_AT_SERIAL_PORT (port)) { - GPtrArray *array; - int i; - mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port), mm_serial_parser_v1_parse, mm_serial_parser_v1_new (), mm_serial_parser_v1_destroy); + mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags); /* Set up CREG unsolicited message handlers */ array = mm_gsm_creg_regex_get (FALSE); for (i = 0; i < array->len; i++) { regex = g_ptr_array_index (array, i); - mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, reg_state_changed, self, NULL); } mm_gsm_creg_regex_destroy (array); @@ -891,72 +881,48 @@ mm_generic_gsm_grab_port (MMGenericGsm *self, regex = g_regex_new ("\\r\\n\\+CUSD:\\s*(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, cusd_received, self, NULL); g_regex_unref (regex); - - if (ptype == MM_PORT_TYPE_PRIMARY) { - priv->primary = MM_AT_SERIAL_PORT (port); - if (!priv->data) { - priv->data = port; - g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); - } - - /* Get the modem's general info */ - initial_info_check (self); - - /* Get modem's IMEI */ - initial_imei_check (self); - - /* Get modem's initial lock/unlock state; this also ensures the - * SIM is ready by waiting if necessary for the SIM to initalize. - */ - initial_pin_check (self); - - /* Determine what facility locks are supported */ - initial_facility_lock_check (self); - - } else if (ptype == MM_PORT_TYPE_SECONDARY) - priv->secondary = MM_AT_SERIAL_PORT (port); - } else if (MM_IS_QCDM_SERIAL_PORT (port)) { - if (!priv->qcdm) - priv->qcdm = MM_QCDM_SERIAL_PORT (port); - } else if (!strcmp (subsys, "net")) { - /* Net device (if any) is the preferred data port */ - if (!priv->data || MM_IS_AT_SERIAL_PORT (priv->data)) { - priv->data = port; - g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); - check_valid (self); - } } - return port; + if (MM_GENERIC_GSM_GET_CLASS (self)->port_grabbed) + MM_GENERIC_GSM_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data); } static gboolean -grab_port (MMModem *modem, - const char *subsys, - const char *name, - MMPortType suggested_type, - gpointer user_data, - GError **error) +organize_ports (MMModem *modem, GError **error) { MMGenericGsm *self = MM_GENERIC_GSM (modem); MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); - MMPortType ptype = MM_PORT_TYPE_IGNORED; - if (priv->primary) - g_return_val_if_fail (suggested_type != MM_PORT_TYPE_PRIMARY, FALSE); + if (!mm_modem_base_organize_ports (MM_MODEM_BASE (modem), + &priv->primary, + &priv->secondary, + &priv->data, + &priv->qcdm, + error)) + return FALSE; + + /* Let subclasses twiddle ports if they want */ + if (MM_GENERIC_GSM_GET_CLASS (self)->ports_organized) + MM_GENERIC_GSM_GET_CLASS (self)->ports_organized (self, priv->primary); - if (!strcmp (subsys, "tty")) { - if (suggested_type != MM_PORT_TYPE_UNKNOWN) - ptype = suggested_type; - else { - if (!priv->primary) - ptype = MM_PORT_TYPE_PRIMARY; - else if (!priv->secondary) - ptype = MM_PORT_TYPE_SECONDARY; - } - } + g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); + + /* Get the modem's general info */ + initial_info_check (self); + + /* Get modem's IMEI */ + initial_imei_check (self); - return !!mm_generic_gsm_grab_port (self, subsys, name, ptype, error); + /* Get modem's initial lock/unlock state; this also ensures the + * SIM is ready by waiting if necessary for the SIM to initalize. + */ + initial_pin_check (self); + + /* Determine what facility locks are supported */ + initial_facility_lock_check (self); + + check_valid (self); + return TRUE; } static void @@ -3824,9 +3790,27 @@ connect (MMModem *modem, MMCallbackInfo *info; char *command; gint cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (modem)); + MMAtSerialPort *dial_port; info = mm_callback_info_new (modem, callback, user_data); + /* Dial port might not be the primary port*/ + priv->data_opened_at_connect = FALSE; + dial_port = priv->primary; + if (MM_IS_AT_SERIAL_PORT (priv->data)) { + dial_port = MM_AT_SERIAL_PORT (priv->data); + + if (!mm_serial_port_open (MM_SERIAL_PORT (dial_port), &info->error)) { + g_warning ("%s: failed to open dial port: (%d) %s", + __func__, + info->error ? info->error->code : -1, + info->error && info->error->message ? info->error->message : "(unknown)"); + mm_callback_info_schedule (info); + return; + } + priv->data_opened_at_connect = TRUE; + } + mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE); if (cid > 0) { @@ -3843,7 +3827,7 @@ connect (MMModem *modem, } else command = g_strconcat ("DT", number, NULL); - mm_at_serial_port_queue_command (priv->primary, command, 60, connect_done, info); + mm_at_serial_port_queue_command (dial_port, command, 60, connect_done, info); g_free (command); } @@ -3854,11 +3838,13 @@ disconnect_done (MMModem *modem, { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemState prev_state; + MMGenericGsmPrivate *priv; /* Do nothing if modem removed */ if (!modem || mm_callback_info_check_modem_removed (info)) return; + priv = MM_GENERIC_GSM_GET_PRIVATE (modem); if (error) { info->error = g_error_copy (error); /* Reset old state since the operation failed */ @@ -3867,12 +3853,19 @@ disconnect_done (MMModem *modem, prev_state, MM_MODEM_STATE_REASON_NONE); } else { - MMGenericGsm *self = MM_GENERIC_GSM (modem); - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); - mm_port_set_connected (priv->data, FALSE); priv->cid = -1; - mm_generic_gsm_update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE); + mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (modem), FALSE, MM_MODEM_STATE_REASON_NONE); + } + + /* Balance any open from connect(); subclasses may not use the generic + * class' connect function and so the dial port may not have been + * opened at all. + */ + if (priv->data_opened_at_connect) { + if (MM_IS_AT_SERIAL_PORT (priv->data)) + mm_serial_port_close (MM_SERIAL_PORT (priv->data)); + priv->data_opened_at_connect = FALSE; } mm_callback_info_schedule (info); @@ -3965,6 +3958,7 @@ disconnect_secondary_cgact_done (MMAtSerialPort *port, MMCallbackInfo *info = user_data; MMGenericGsm *self; MMGenericGsmPrivate *priv; + MMSerialPort *dial_port; /* If the modem has already been removed, return without * scheduling callback */ @@ -3980,7 +3974,11 @@ disconnect_secondary_cgact_done (MMAtSerialPort *port, if (!error) mm_callback_info_set_data (info, DISCONNECT_CGACT_DONE_TAG, GUINT_TO_POINTER (TRUE), NULL); - mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, TRUE, disconnect_flash_done, info); + dial_port = MM_SERIAL_PORT (priv->primary); + if (MM_IS_AT_SERIAL_PORT (priv->data)) + dial_port = MM_SERIAL_PORT (priv->data); + + mm_serial_port_flash (dial_port, 1000, TRUE, disconnect_flash_done, info); } static void @@ -3991,6 +3989,7 @@ real_do_disconnect (MMGenericGsm *self, { MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self); MMCallbackInfo *info; + MMSerialPort *dial_port; info = mm_callback_info_new (MM_MODEM (self), callback, user_data); @@ -4007,8 +4006,12 @@ real_do_disconnect (MMGenericGsm *self, disconnect_secondary_cgact_done, info); } else { - /* Just flash the primary port */ - mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, TRUE, disconnect_flash_done, info); + /* Just flash the dial port */ + dial_port = MM_SERIAL_PORT (priv->primary); + if (MM_IS_AT_SERIAL_PORT (priv->data)) + dial_port = MM_SERIAL_PORT (priv->data); + + mm_serial_port_flash (dial_port, 1000, TRUE, disconnect_flash_done, info); } } @@ -5487,15 +5490,26 @@ sms_list (MMModemGsmSms *modem, MMAtSerialPort * mm_generic_gsm_get_at_port (MMGenericGsm *modem, - MMPortType ptype) + MMAtPortFlags flag) { + MMGenericGsmPrivate *priv; + g_return_val_if_fail (MM_IS_GENERIC_GSM (modem), NULL); - g_return_val_if_fail (ptype != MM_PORT_TYPE_UNKNOWN, NULL); - if (ptype == MM_PORT_TYPE_PRIMARY) - return MM_GENERIC_GSM_GET_PRIVATE (modem)->primary; - else if (ptype == MM_PORT_TYPE_SECONDARY) - return MM_GENERIC_GSM_GET_PRIVATE (modem)->secondary; + /* We only search for a single value even though it's a bitfield */ + g_return_val_if_fail ( flag == MM_AT_PORT_FLAG_NONE + || flag == MM_AT_PORT_FLAG_PRIMARY + || flag == MM_AT_PORT_FLAG_SECONDARY + || flag == MM_AT_PORT_FLAG_PPP, NULL); + + priv = MM_GENERIC_GSM_GET_PRIVATE (modem); + + if (flag == MM_AT_PORT_FLAG_SECONDARY) + return priv->secondary; + else if (flag == MM_AT_PORT_FLAG_PRIMARY) + return priv->primary; + else if ((flag == MM_AT_PORT_FLAG_PPP) && MM_IS_AT_SERIAL_PORT (priv->data)) + return MM_AT_SERIAL_PORT (priv->data); return NULL; } @@ -6481,7 +6495,7 @@ static void modem_init (MMModem *modem_class) { modem_class->owns_port = owns_port; - modem_class->grab_port = grab_port; + modem_class->organize_ports = organize_ports; modem_class->release_port = release_port; modem_class->enable = enable; modem_class->disable = disable; @@ -6817,11 +6831,12 @@ finalize (GObject *object) } static void -mm_generic_gsm_class_init (MMGenericGsmClass *klass) +mm_generic_gsm_class_init (MMGenericGsmClass *generic_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (generic_class); + MMModemBaseClass *base_class = MM_MODEM_BASE_CLASS (generic_class); - mm_generic_gsm_parent_class = g_type_class_peek_parent (klass); + mm_generic_gsm_parent_class = g_type_class_peek_parent (generic_class); g_type_class_add_private (object_class, sizeof (MMGenericGsmPrivate)); /* Virtual methods */ @@ -6829,12 +6844,14 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass) object_class->get_property = get_property; object_class->finalize = finalize; - klass->do_enable = real_do_enable; - klass->do_enable_power_up_done = real_do_enable_power_up_done; - klass->do_disconnect = real_do_disconnect; - klass->get_sim_iccid = real_get_sim_iccid; - klass->get_operator_name = real_get_operator_name; - klass->get_operator_code = real_get_operator_code; + base_class->port_grabbed = port_grabbed; + + generic_class->do_enable = real_do_enable; + generic_class->do_enable_power_up_done = real_do_enable_power_up_done; + generic_class->do_disconnect = real_do_disconnect; + generic_class->get_sim_iccid = real_get_sim_iccid; + generic_class->get_operator_name = real_get_operator_name; + generic_class->get_operator_code = real_get_operator_code; /* Properties */ g_object_class_override_property (object_class, diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h index 92ab7b94..e0c3e6dd 100644 --- a/src/mm-generic-gsm.h +++ b/src/mm-generic-gsm.h @@ -83,6 +83,23 @@ typedef struct { typedef struct { MMModemBaseClass parent; + /* Called to allow subclasses to update port flags, attach unsolicited + * result code handlers, change port attributes, etc. This is called + * after the generic class has installed it's own handlers; if the + * generic class' behavior is not desired, subclasses can override the + * port_grabbed() method of MMModemBase. + */ + void (*port_grabbed) (MMGenericGsm *self, + MMPort *port, + MMAtPortFlags at_pflags, + gpointer user_data); + + /* Called after all ports have been organized to allow subclasses to + * make changes to ports after we've assigned primary, secondary, and data + * designations. + */ + void (*ports_organized) (MMGenericGsm *self, MMAtSerialPort *primary); + /* Called after opening the primary serial port and updating the modem's * state to ENABLING, but before sending any commands to the device. Modems * that need to perform custom initialization sequences or other setup should @@ -211,18 +228,13 @@ void mm_generic_gsm_update_access_technology (MMGenericGsm *modem, */ void mm_generic_gsm_update_signal_quality (MMGenericGsm *modem, guint32 quality); +/* Returns the first port (if any) which has the given flag */ MMAtSerialPort *mm_generic_gsm_get_at_port (MMGenericGsm *modem, - MMPortType ptype); + MMAtPortFlags flag); MMAtSerialPort *mm_generic_gsm_get_best_at_port (MMGenericGsm *modem, GError **error); -MMPort *mm_generic_gsm_grab_port (MMGenericGsm *modem, - const char *subsys, - const char *name, - MMPortType ptype, - GError **error); - /* stay_connected should be TRUE for unsolicited registration updates, otherwise * the registration update will clear connected/connecting/disconnecting state * which we don't want. stay_connected should be FALSE for other cases like diff --git a/src/mm-manager.c b/src/mm-manager.c index 6767353e..5f114bba 100644 --- a/src/mm-manager.c +++ b/src/mm-manager.c @@ -247,13 +247,36 @@ remove_modem (MMManager *manager, MMModem *modem) g_free (device); } +/* Return the first outstanding supports task */ +static SupportsInfo * +find_supports_info (MMManager *self, MMModem *modem) +{ + char *modem_physdev; + GHashTableIter iter; + SupportsInfo *info, *ret = NULL; + + modem_physdev = mm_modem_get_device (modem); + g_assert (modem_physdev); + + /* Check for ports that are in the process of being interrogated by plugins */ + g_hash_table_iter_init (&iter, MM_MANAGER_GET_PRIVATE (self)->supports); + while (!ret && g_hash_table_iter_next (&iter, NULL, (gpointer) &info)) { + if (g_strcmp0 (info->physdev_path, modem_physdev) == 0) + ret = info; + } + g_free (modem_physdev); + return ret; +} + static void check_export_modem (MMManager *self, MMModem *modem) { MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (self); - char *modem_physdev; - GHashTableIter iter; - gpointer value; + SupportsInfo *info; + static guint32 id = 0, vid = 0, pid = 0; + char *path, *data_device = NULL, *modem_physdev; + GUdevDevice *physdev; + const char *subsys = NULL; /* A modem is only exported to D-Bus when both of the following are true: * @@ -269,63 +292,46 @@ check_export_modem (MMManager *self, MMModem *modem) * all other ports are already handled. That chance is very small though. */ - modem_physdev = mm_modem_get_device (modem); - g_assert (modem_physdev); - - /* Check for ports that are in the process of being interrogated by plugins */ - g_hash_table_iter_init (&iter, priv->supports); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - SupportsInfo *info = value; - - if (!strcmp (info->physdev_path, modem_physdev)) { - mm_dbg ("(%s/%s): outstanding support task prevents export of %s", - info->subsys, info->name, modem_physdev); - goto out; - } + info = find_supports_info (self, modem); + if (info) { + mm_dbg ("(%s/%s): outstanding support task prevents export of %s", + info->subsys, info->name, info->physdev_path); + return; } - /* Already exported? This can happen if the modem is exported and the kernel - * discovers another of the modem's ports. - */ - if (g_object_get_data (G_OBJECT (modem), DBUS_PATH_TAG)) - goto out; + /* Obviously don't re-export a modem, or try to export one that's not valid */ + if ( g_object_get_data (G_OBJECT (modem), DBUS_PATH_TAG) + || !mm_modem_get_valid (modem)) + return; + + path = g_strdup_printf (MM_DBUS_PATH "/Modems/%d", id++); + dbus_g_connection_register_g_object (priv->connection, path, G_OBJECT (modem)); + g_object_set_data_full (G_OBJECT (modem), DBUS_PATH_TAG, path, (GDestroyNotify) g_free); - /* No outstanding port tasks, so if the modem is valid we can export it */ - if (mm_modem_get_valid (modem)) { - static guint32 id = 0, vid = 0, pid = 0; - char *path, *data_device = NULL; - GUdevDevice *physdev; - const char *subsys = NULL; - - path = g_strdup_printf (MM_DBUS_PATH"/Modems/%d", id++); - dbus_g_connection_register_g_object (priv->connection, path, G_OBJECT (modem)); - g_object_set_data_full (G_OBJECT (modem), DBUS_PATH_TAG, path, (GDestroyNotify) g_free); - - mm_dbg ("Exported modem %s as %s", modem_physdev, path); - - physdev = g_udev_client_query_by_sysfs_path (priv->udev, modem_physdev); - if (physdev) - subsys = g_udev_device_get_subsystem (physdev); - - g_object_get (G_OBJECT (modem), - MM_MODEM_DATA_DEVICE, &data_device, - MM_MODEM_HW_VID, &vid, - MM_MODEM_HW_PID, &pid, - NULL); - mm_dbg ("(%s): VID 0x%04X PID 0x%04X (%s)", - path, (vid & 0xFFFF), (pid & 0xFFFF), - subsys ? subsys : "unknown"); - mm_dbg ("(%s): data port is %s", path, data_device); - g_free (data_device); - - if (physdev) - g_object_unref (physdev); - - g_signal_emit (self, signals[DEVICE_ADDED], 0, modem); - } + modem_physdev = mm_modem_get_device (modem); + g_assert (modem_physdev); + mm_dbg ("Exported modem %s as %s", modem_physdev, path); -out: + physdev = g_udev_client_query_by_sysfs_path (priv->udev, modem_physdev); g_free (modem_physdev); + if (physdev) + subsys = g_udev_device_get_subsystem (physdev); + + g_object_get (G_OBJECT (modem), + MM_MODEM_DATA_DEVICE, &data_device, + MM_MODEM_HW_VID, &vid, + MM_MODEM_HW_PID, &pid, + NULL); + mm_dbg ("(%s): VID 0x%04X PID 0x%04X (%s)", + path, (vid & 0xFFFF), (pid & 0xFFFF), + subsys ? subsys : "unknown"); + mm_dbg ("(%s): data port is %s", path, data_device); + g_free (data_device); + + if (physdev) + g_object_unref (physdev); + + g_signal_emit (self, signals[DEVICE_ADDED], 0, modem); } static void @@ -548,6 +554,7 @@ supports_cleanup (MMManager *self, { MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (self); char *key; + GError *error = NULL; g_return_if_fail (subsys != NULL); g_return_if_fail (name != NULL); @@ -556,15 +563,35 @@ supports_cleanup (MMManager *self, g_hash_table_remove (priv->supports, key); g_free (key); + if (modem == NULL) + return; + + if ( (find_supports_info (self, modem) == NULL) + && !g_object_get_data (G_OBJECT (modem), "organized")) { + /* Yay, we're done with supports tasks, tell the modem to organize + * all its ports. Guard against multiple organize calls though since + * if the kernel or udev is slow, ports may show up long after the + * first bunch of supports tasks is done. + */ + g_object_set_data (G_OBJECT (modem), "organized", GUINT_TO_POINTER (1)); + if (!mm_modem_organize_ports (modem, &error)) { + mm_err ("Failed to organize modem ports: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + remove_modem (self, modem); + return; + } + } + /* Each time a supports task is cleaned up, check whether the modem is * now completely probed/handled and should be exported to D-Bus clients. * - * IMPORTANT: this must be done after removing the supports into from + * IMPORTANT: this must be done after removing the supports info from * priv->supports since check_export_modem() searches through priv->supports * for outstanding supports tasks. */ - if (modem) - check_export_modem (self, modem); + check_export_modem (self, modem); } static gboolean diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index b3b1db2c..bd1943e7 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -113,14 +113,21 @@ mm_modem_base_get_port (MMModemBase *self, return port; } -static void -find_primary (gpointer key, gpointer data, gpointer user_data) +GSList * +mm_modem_base_get_ports (MMModemBase *self) { - MMPort **found = user_data; - MMPort *port = MM_PORT (data); + GHashTableIter iter; + MMPort *port; + GSList *list = NULL; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL); - if (!*found && (mm_port_get_port_type (port) == MM_PORT_TYPE_PRIMARY)) - *found = port; + g_hash_table_iter_init (&iter, MM_MODEM_BASE_GET_PRIVATE (self)->ports); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &port)) + list = g_slist_append (list, port); + + return list; } static gboolean @@ -159,68 +166,6 @@ serial_port_timed_out_cb (MMSerialPort *port, } } -MMPort * -mm_modem_base_add_port (MMModemBase *self, - const char *subsys, - const char *name, - MMPortType ptype) -{ - MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self); - MMPort *port = NULL; - char *key, *device; - - g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL); - g_return_val_if_fail (subsys != NULL, NULL); - g_return_val_if_fail (name != NULL, NULL); - g_return_val_if_fail (ptype != MM_PORT_TYPE_UNKNOWN, NULL); - - g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), NULL); - - key = get_hash_key (subsys, name); - port = g_hash_table_lookup (priv->ports, key); - g_free (key); - g_return_val_if_fail (port == NULL, NULL); - - if (ptype == MM_PORT_TYPE_PRIMARY) { - g_hash_table_foreach (priv->ports, find_primary, &port); - g_return_val_if_fail (port == NULL, FALSE); - } - - if (!strcmp (subsys, "tty")) { - if (ptype == MM_PORT_TYPE_QCDM) - port = MM_PORT (mm_qcdm_serial_port_new (name, ptype)); - else - port = MM_PORT (mm_at_serial_port_new (name, ptype)); - - /* For serial ports, enable port timeout checks */ - if (port) - g_signal_connect (port, - "timed-out", - G_CALLBACK (serial_port_timed_out_cb), - self); - } else if (!strcmp (subsys, "net")) { - port = MM_PORT (g_object_new (MM_TYPE_PORT, - MM_PORT_DEVICE, name, - MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET, - MM_PORT_TYPE, ptype, - NULL)); - } - - if (!port) - return NULL; - - device = mm_modem_get_device (MM_MODEM (self)); - mm_dbg ("(%s) type %s claimed by %s", - name, - mm_port_type_to_name (ptype), - device); - g_free (device); - - key = get_hash_key (subsys, name); - g_hash_table_insert (priv->ports, key, port); - return port; -} - gboolean mm_modem_base_remove_port (MMModemBase *self, MMPort *port) { @@ -252,6 +197,142 @@ mm_modem_base_remove_port (MMModemBase *self, MMPort *port) return removed; } +static inline void +log_port (MMPort *port, const char *device, const char *desc) +{ + if (port) { + mm_dbg ("(%s) %s/%s %s", + device, + mm_port_subsys_to_name (mm_port_get_subsys (port)), + mm_port_get_device (port), + desc); + } +} + +gboolean +mm_modem_base_organize_ports (MMModemBase *self, + MMAtSerialPort **out_primary, + MMAtSerialPort **out_secondary, + MMPort **out_data, + MMQcdmSerialPort **out_qcdm, + GError **error) +{ + GSList *ports, *iter; + MMAtPortFlags flags; + MMAtSerialPort *backup_primary = NULL; + MMAtSerialPort *primary = NULL; + MMAtSerialPort *secondary = NULL; + MMAtSerialPort *backup_secondary = NULL; + MMQcdmSerialPort *qcdm = NULL; + MMPort *data = NULL; + char *device; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (out_primary != NULL, FALSE); + g_return_val_if_fail (out_secondary != NULL, FALSE); + g_return_val_if_fail (out_data != NULL, FALSE); + + ports = mm_modem_base_get_ports (self); + for (iter = ports; iter; iter = g_slist_next (iter)) { + MMPort *candidate = iter->data; + MMPortSubsys subsys = mm_port_get_subsys (candidate); + + if (MM_IS_AT_SERIAL_PORT (candidate)) { + flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (candidate)); + + if (flags & MM_AT_PORT_FLAG_PRIMARY) { + if (!primary) + primary = MM_AT_SERIAL_PORT (candidate); + else if (!backup_primary) { + /* Just in case the plugin gave us more than one primary + * and no secondaries, treat additional primary ports as + * secondary. + */ + backup_primary = MM_AT_SERIAL_PORT (candidate); + } + } + + if (!data && (flags & MM_AT_PORT_FLAG_PPP)) + data = candidate; + + /* Explicitly flagged secondary ports trump NONE ports for secondary */ + if (flags & MM_AT_PORT_FLAG_SECONDARY) { + if (!secondary || !(mm_at_serial_port_get_flags (secondary) & MM_AT_PORT_FLAG_SECONDARY)) + secondary = MM_AT_SERIAL_PORT (candidate); + } + + /* Fallback secondary */ + if (flags == MM_AT_PORT_FLAG_NONE) { + if (!secondary) + secondary = MM_AT_SERIAL_PORT (candidate); + else if (!backup_secondary) + backup_secondary = MM_AT_SERIAL_PORT (candidate); + } + } else if (MM_IS_QCDM_SERIAL_PORT (candidate)) { + if (!qcdm) + qcdm = MM_QCDM_SERIAL_PORT (candidate); + } else if (subsys == MM_PORT_SUBSYS_NET) { + /* Net device (if any) is the preferred data port */ + if (!data || MM_IS_AT_SERIAL_PORT (data)) + data = candidate; + } + } + g_slist_free (ports); + + /* Fall back to a secondary port if we didn't find a primary port */ + if (!primary) { + if (!secondary) { + g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Failed to find primary port."); + return FALSE; + } + primary = secondary; + secondary = NULL; + } + g_assert (primary); + + /* If the plugin didn't give us any secondary ports, use any additional + * primary ports or backup secondary ports as secondary. + */ + if (!secondary) + secondary = backup_primary ? backup_primary : backup_secondary; + + /* Data port defaults to primary AT port */ + if (!data) + data = MM_PORT (primary); + g_assert (data); + + /* Reset flags on all ports; clear data port first since it might also + * be the primary or secondary port. + */ + if (MM_IS_AT_SERIAL_PORT (data)) + mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data), MM_AT_PORT_FLAG_NONE); + + mm_at_serial_port_set_flags (primary, MM_AT_PORT_FLAG_PRIMARY); + if (secondary) + mm_at_serial_port_set_flags (secondary, MM_AT_PORT_FLAG_SECONDARY); + + if (MM_IS_AT_SERIAL_PORT (data)) { + flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (data)); + mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data), flags | MM_AT_PORT_FLAG_PPP); + } + + device = mm_modem_get_device (MM_MODEM (self)); + log_port (MM_PORT (primary), device, "primary"); + log_port (MM_PORT (secondary), device, "secondary"); + log_port (MM_PORT (data), device, "data"); + log_port (MM_PORT (qcdm), device, "qcdm"); + g_free (device); + + *out_primary = primary; + *out_secondary = secondary; + *out_data = data; + if (out_qcdm) + *out_qcdm = qcdm; + + return TRUE; +} + void mm_modem_base_set_valid (MMModemBase *self, gboolean new_valid) { @@ -786,6 +867,77 @@ mm_modem_base_get_card_info (MMModemBase *self, /*****************************************************************************/ static gboolean +grab_port (MMModem *modem, + const char *subsys, + const char *name, + MMPortType ptype, + MMAtPortFlags at_pflags, + gpointer user_data, + GError **error) +{ + MMModemBase *self = MM_MODEM_BASE (modem); + MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self); + MMPort *port = NULL; + char *key, *device; + + g_return_val_if_fail (MM_IS_MODEM_BASE (self), FALSE); + g_return_val_if_fail (subsys != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), FALSE); + + key = get_hash_key (subsys, name); + port = g_hash_table_lookup (priv->ports, key); + g_free (key); + g_return_val_if_fail (port == NULL, FALSE); + + if (!strcmp (subsys, "tty")) { + if (ptype == MM_PORT_TYPE_QCDM) + port = MM_PORT (mm_qcdm_serial_port_new (name)); + else if (ptype == MM_PORT_TYPE_AT) + port = MM_PORT (mm_at_serial_port_new (name)); + + /* For serial ports, enable port timeout checks */ + if (port) { + g_signal_connect (port, + "timed-out", + G_CALLBACK (serial_port_timed_out_cb), + self); + } + } else if (!strcmp (subsys, "net")) { + port = MM_PORT (g_object_new (MM_TYPE_PORT, + MM_PORT_DEVICE, name, + MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET, + NULL)); + } + + if (!port) { + g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "Failed to grab port %s/%s: unknown type?", + subsys, name); + mm_dbg ("(%s/%s): failed to create %s port", + subsys, name, mm_port_type_to_name (ptype)); + return FALSE; + } + + device = mm_modem_get_device (MM_MODEM (self)); + mm_dbg ("(%s) type %s claimed by %s", + name, + mm_port_type_to_name (ptype), + device); + g_free (device); + + key = get_hash_key (subsys, name); + g_hash_table_insert (priv->ports, key, port); + + /* Let subclasses know we've grabbed it */ + if (MM_MODEM_BASE_GET_CLASS (self)->port_grabbed) + MM_MODEM_BASE_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data); + + return TRUE; +} + +static gboolean modem_auth_request (MMModem *modem, const char *authorization, DBusGMethodInvocation *context, @@ -876,6 +1028,7 @@ mm_modem_base_init (MMModemBase *self) static void modem_init (MMModem *modem_class) { + modem_class->grab_port = grab_port; modem_class->auth_request = modem_auth_request; modem_class->auth_finish = modem_auth_finish; } diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h index a386bd76..b3bd679e 100644 --- a/src/mm-modem-base.h +++ b/src/mm-modem-base.h @@ -22,6 +22,7 @@ #include "mm-port.h" #include "mm-at-serial-port.h" +#include "mm-qcdm-serial-port.h" #include "mm-modem.h" #define MM_TYPE_MODEM_BASE (mm_modem_base_get_type ()) @@ -42,6 +43,14 @@ struct _MMModemBase { struct _MMModemBaseClass { GObjectClass parent; + + /* Called after the base class grabs a port so that subclasses can + * set port flags and other properties on the new port. + */ + void (*port_grabbed) (MMModemBase *self, + MMPort *port, + MMAtPortFlags at_pflags, + gpointer user_data); }; GType mm_modem_base_get_type (void); @@ -50,14 +59,18 @@ MMPort *mm_modem_base_get_port (MMModemBase *self, const char *subsys, const char *name); -MMPort *mm_modem_base_add_port (MMModemBase *self, - const char *subsys, - const char *name, - MMPortType ptype); +GSList *mm_modem_base_get_ports (MMModemBase *self); gboolean mm_modem_base_remove_port (MMModemBase *self, MMPort *port); +gboolean mm_modem_base_organize_ports (MMModemBase *self, + MMAtSerialPort **out_primary, + MMAtSerialPort **out_secondary, + MMPort **out_data, + MMQcdmSerialPort **out_qcdm, + GError **error); + void mm_modem_base_set_valid (MMModemBase *self, gboolean valid); diff --git a/src/mm-modem.c b/src/mm-modem.c index adfbeb26..012e3203 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -633,7 +633,8 @@ gboolean mm_modem_grab_port (MMModem *self, const char *subsys, const char *name, - MMPortType suggested_type, + MMPortType ptype, + MMAtPortFlags at_pflags, gpointer user_data, GError **error) { @@ -643,7 +644,17 @@ mm_modem_grab_port (MMModem *self, g_return_val_if_fail (name, FALSE); g_assert (MM_MODEM_GET_INTERFACE (self)->grab_port); - return MM_MODEM_GET_INTERFACE (self)->grab_port (self, subsys, name, suggested_type, user_data, error); + return MM_MODEM_GET_INTERFACE (self)->grab_port (self, subsys, name, ptype, at_pflags, user_data, error); +} + +gboolean +mm_modem_organize_ports (MMModem *self, GError **error) +{ + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (MM_IS_MODEM (self), FALSE); + + g_assert (MM_MODEM_GET_INTERFACE (self)->organize_ports); + return MM_MODEM_GET_INTERFACE (self)->organize_ports (self, error); } void diff --git a/src/mm-modem.h b/src/mm-modem.h index 19640ac8..c4200645 100644 --- a/src/mm-modem.h +++ b/src/mm-modem.h @@ -23,6 +23,7 @@ #include <ModemManager.h> #include "mm-port.h" +#include "mm-at-serial-port.h" #include "mm-auth-provider.h" #include "mm-charsets.h" @@ -118,13 +119,23 @@ struct _MMModem { const char *subsys, const char *name); + /* Subclasses use this function to claim a particular port */ gboolean (*grab_port) (MMModem *self, const char *subsys, const char *name, - MMPortType suggested_type, + MMPortType ptype, + MMAtPortFlags at_pflags, gpointer user_data, GError **error); + /* Subclasses use this function to determine which of their + * grabbed ports should be used for data, command and status, + * PPP, etc. Called after all ports have been detected and + * grabbed by the modem. + */ + gboolean (*organize_ports) (MMModem *self, + GError **error); + void (*release_port) (MMModem *self, const char *subsys, const char *name); @@ -204,10 +215,14 @@ gboolean mm_modem_owns_port (MMModem *self, gboolean mm_modem_grab_port (MMModem *self, const char *subsys, const char *name, - MMPortType suggested_type, + MMPortType ptype, + MMAtPortFlags at_pflags, gpointer user_data, GError **error); +gboolean mm_modem_organize_ports (MMModem *self, + GError **error); + void mm_modem_release_port (MMModem *self, const char *subsys, const char *name); diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c index 2c56c7b4..c4b514bb 100644 --- a/src/mm-plugin-base.c +++ b/src/mm-plugin-base.c @@ -261,6 +261,16 @@ mm_plugin_base_supports_task_get_probed_capabilities (MMPluginBaseSupportsTask * return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->probed_caps; } +MMPortType +mm_plugin_base_probed_capabilities_to_port_type (guint32 caps) +{ + if (caps & MM_PLUGIN_BASE_PORT_CAP_AT) + return MM_PORT_TYPE_AT; + else if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM) + return MM_PORT_TYPE_QCDM; + return MM_PORT_TYPE_UNKNOWN; +} + const gchar * mm_plugin_base_supports_task_get_probed_vendor (MMPluginBaseSupportsTask *task) { @@ -680,7 +690,7 @@ try_qcdm_probe (MMPluginBaseSupportsTask *task) /* Open the QCDM port */ name = g_udev_device_get_name (priv->port); g_assert (name); - priv->qcdm_port = mm_qcdm_serial_port_new (name, MM_PORT_TYPE_PRIMARY); + priv->qcdm_port = mm_qcdm_serial_port_new (name); if (priv->qcdm_port == NULL) { g_warning ("(%s) failed to create new QCDM serial port.", name); probe_complete (task); @@ -1064,7 +1074,7 @@ mm_plugin_base_probe_port (MMPluginBase *self, name = g_udev_device_get_name (port); g_assert (name); - serial = mm_at_serial_port_new (name, MM_PORT_TYPE_PRIMARY); + serial = mm_at_serial_port_new (name); if (serial == NULL) { g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Failed to create new serial port."); diff --git a/src/mm-plugin-base.h b/src/mm-plugin-base.h index 48bec97e..46254749 100644 --- a/src/mm-plugin-base.h +++ b/src/mm-plugin-base.h @@ -87,6 +87,8 @@ const char *mm_plugin_base_supports_task_get_driver (MMPluginBaseSupportsTask *t guint32 mm_plugin_base_supports_task_get_probed_capabilities (MMPluginBaseSupportsTask *task); +MMPortType mm_plugin_base_probed_capabilities_to_port_type (guint32 caps); + const gchar *mm_plugin_base_supports_task_get_probed_vendor (MMPluginBaseSupportsTask *task); const gchar *mm_plugin_base_supports_task_get_probed_product (MMPluginBaseSupportsTask *task); diff --git a/src/mm-port.c b/src/mm-port.c index a1291d0b..720b9c35 100644 --- a/src/mm-port.c +++ b/src/mm-port.c @@ -64,10 +64,8 @@ const char * mm_port_type_to_name (MMPortType ptype) { switch (ptype) { - case MM_PORT_TYPE_PRIMARY: - return "primary"; - case MM_PORT_TYPE_SECONDARY: - return "secondary"; + case MM_PORT_TYPE_AT: + return "AT"; case MM_PORT_TYPE_IGNORED: return "ignored"; case MM_PORT_TYPE_QCDM: @@ -108,7 +106,9 @@ constructor (GType type, return NULL; } - if (priv->ptype == MM_PORT_TYPE_UNKNOWN) { + /* Can't have a TTY subsystem port that's unknown */ + if ( priv->subsys != MM_PORT_SUBSYS_NET + && priv->ptype == MM_PORT_TYPE_UNKNOWN) { g_warning ("MMPort: invalid port type"); g_object_unref (object); return NULL; diff --git a/src/mm-port.h b/src/mm-port.h index df935db2..21e2f605 100644 --- a/src/mm-port.h +++ b/src/mm-port.h @@ -29,8 +29,7 @@ typedef enum { typedef enum { MM_PORT_TYPE_UNKNOWN = 0x0, - MM_PORT_TYPE_PRIMARY, - MM_PORT_TYPE_SECONDARY, + MM_PORT_TYPE_AT, MM_PORT_TYPE_IGNORED, MM_PORT_TYPE_QCDM, diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c index 0d763bf5..d209dbb7 100644 --- a/src/mm-qcdm-serial-port.c +++ b/src/mm-qcdm-serial-port.c @@ -216,17 +216,17 @@ config_fd (MMSerialPort *port, int fd, GError **error) /*****************************************************************************/ MMQcdmSerialPort * -mm_qcdm_serial_port_new (const char *name, MMPortType ptype) +mm_qcdm_serial_port_new (const char *name) { return MM_QCDM_SERIAL_PORT (g_object_new (MM_TYPE_QCDM_SERIAL_PORT, MM_PORT_DEVICE, name, MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY, - MM_PORT_TYPE, ptype, + MM_PORT_TYPE, MM_PORT_TYPE_QCDM, NULL)); } MMQcdmSerialPort * -mm_qcdm_serial_port_new_fd (int fd, MMPortType ptype) +mm_qcdm_serial_port_new_fd (int fd) { MMQcdmSerialPort *port; char *name; @@ -235,7 +235,7 @@ mm_qcdm_serial_port_new_fd (int fd, MMPortType ptype) port = MM_QCDM_SERIAL_PORT (g_object_new (MM_TYPE_QCDM_SERIAL_PORT, MM_PORT_DEVICE, name, MM_PORT_SUBSYS, MM_PORT_SUBSYS_TTY, - MM_PORT_TYPE, ptype, + MM_PORT_TYPE, MM_PORT_TYPE_QCDM, MM_SERIAL_PORT_FD, fd, NULL)); g_free (name); diff --git a/src/mm-qcdm-serial-port.h b/src/mm-qcdm-serial-port.h index 605016d3..5efccdb1 100644 --- a/src/mm-qcdm-serial-port.h +++ b/src/mm-qcdm-serial-port.h @@ -47,9 +47,9 @@ struct _MMQcdmSerialPortClass { GType mm_qcdm_serial_port_get_type (void); -MMQcdmSerialPort *mm_qcdm_serial_port_new (const char *name, MMPortType ptype); +MMQcdmSerialPort *mm_qcdm_serial_port_new (const char *name); -MMQcdmSerialPort *mm_qcdm_serial_port_new_fd (int fd, MMPortType ptype); +MMQcdmSerialPort *mm_qcdm_serial_port_new_fd (int fd); void mm_qcdm_serial_port_queue_command (MMQcdmSerialPort *self, GByteArray *command, diff --git a/src/tests/test-qcdm-serial-port.c b/src/tests/test-qcdm-serial-port.c index c31011b3..8965c66a 100644 --- a/src/tests/test-qcdm-serial-port.c +++ b/src/tests/test-qcdm-serial-port.c @@ -215,7 +215,7 @@ qcdm_test_child (int fd, VerInfoCb cb) loop = g_main_loop_new (NULL, FALSE); - port = mm_qcdm_serial_port_new_fd (fd, MM_PORT_TYPE_PRIMARY); + port = mm_qcdm_serial_port_new_fd (fd); g_assert (port); success = mm_serial_port_open (MM_SERIAL_PORT (port), &error); |