static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; GUdevDevice *port; MMPortType port_type; port_type = mm_port_probe_get_port_type (probe); port = mm_port_probe_peek_port (probe); if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_AT_PORT")) { mm_dbg ("(%s/%s)' Port flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_MODEM_PORT")) { mm_dbg ("(%s/%s) Port flagged as PPP", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PPP; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_GPS_PORT")) { mm_dbg ("(%s/%s) Port flagged as GPS", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); port_type = MM_PORT_TYPE_GPS; } else { gchar *str; pflags = (MMPortSerialAtFlag) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (probe), TAG_AT_PORT_FLAGS)); str = mm_port_serial_at_flag_build_string_from_mask (pflags); mm_dbg ("(%s/%s) Port will have AT flags '%s'", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), str); g_free (str); } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), port_type, pflags, error); }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { MMAtPortFlag pflags = MM_AT_PORT_FLAG_NONE; MMPortType ptype; ptype = mm_port_probe_get_port_type (probe); /* Is it a GSM secondary port? */ if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP_PORT)) { if (g_object_get_data (G_OBJECT (probe), TAG_SIERRA_APP1_PPP_OK)) pflags = MM_AT_PORT_FLAG_PPP; else pflags = MM_AT_PORT_FLAG_SECONDARY; } else if (ptype == MM_PORT_TYPE_AT) pflags = MM_AT_PORT_FLAG_PRIMARY; return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), ptype, pflags, error); }
static void propagate_port_mode_results (GList *probes) { MMDevice *device; GList *l; gboolean primary_flagged = FALSE; g_assert (probes != NULL); device = mm_port_probe_peek_device (MM_PORT_PROBE (probes->data)); /* Now we propagate the tags to the specific port probes */ for (l = probes; l; l = g_list_next (l)) { MMPortSerialAtFlag at_port_flags = MM_PORT_SERIAL_AT_FLAG_NONE; gint usbif; usbif = g_udev_device_get_property_as_int (mm_port_probe_peek_port (MM_PORT_PROBE (l->data)), "ID_USB_INTERFACE_NUM"); if (GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED))) { if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_PCUI_PORT))) { at_port_flags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; primary_flagged = TRUE; } else if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT))) at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP; else if (!g_object_get_data (G_OBJECT (device), TAG_HUAWEI_MODEM_PORT) && usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (device), TAG_HUAWEI_NDIS_PORT))) /* If NDIS reported only instead of MDM, use it */ at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP; } else if (usbif == 0 && mm_port_probe_is_at (MM_PORT_PROBE (l->data))) { /* If GETPORTMODE is not supported, we assume usbif 0 is the modem port */ at_port_flags = MM_PORT_SERIAL_AT_FLAG_PPP; /* /\* TODO. */ /* * 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_PORT_SERIAL_AT_FLAG_PRIMARY; */ } g_object_set_data (G_OBJECT (l->data), TAG_AT_PORT_FLAGS, GUINT_TO_POINTER (at_port_flags)); } if (primary_flagged) return; /* For devices exposing a cdc-wdm port, make sure it gets flagged as primary, if there is none * already */ for (l = probes; l; l = g_list_next (l)) { MMPortProbe *probe = MM_PORT_PROBE (l->data); if (mm_port_probe_is_at (probe) && g_str_has_prefix (mm_port_probe_get_port_subsys (probe), "usb") && g_str_has_prefix (mm_port_probe_get_port_name (probe), "cdc-wdm")) { /* Flag as PRIMARY and do nothing else */ g_object_set_data (G_OBJECT (probe), TAG_AT_PORT_FLAGS, GUINT_TO_POINTER (MM_PORT_SERIAL_AT_FLAG_PRIMARY)); break; } } }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { MMPortType ptype; MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; ptype = mm_port_probe_get_port_type (probe); /* Always prefer the ttyACM port as PRIMARY AT port */ if (ptype == MM_PORT_TYPE_AT && g_str_has_prefix (mm_port_probe_get_port_name (probe), "ttyACM")) { pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), ptype, pflags, error); }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { GUdevDevice *port; MMPortType ptype; MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; port = mm_port_probe_peek_port (probe); ptype = mm_port_probe_get_port_type (probe); if (mm_port_probe_is_at (probe)) { /* Look for port type hints; just probing can't distinguish which port should * be the data/primary port on these devices. We have to tag them based on * 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")) { mm_dbg ("Simtech: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_AUX")) { mm_dbg ("Simtech: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; } /* 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 (pflags == MM_PORT_SERIAL_AT_FLAG_NONE && g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), ptype, pflags, error); }
static MMBaseModem * grab_port (MMPluginBase *base, MMBaseModem *existing, MMPortProbe *probe, GError **error) { MMBaseModem *modem = NULL; const gchar *name, *subsys; guint16 vendor = 0, product = 0; /* The Motorola plugin cannot do anything with non-AT ports */ if (!mm_port_probe_is_at (probe)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Ignoring non-AT port"); return NULL; } subsys = mm_port_probe_get_port_subsys (probe); name = mm_port_probe_get_port_name (probe); if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Could not get modem product ID"); return NULL; } /* If this is the first port being grabbed, create a new modem object */ if (!existing) modem = MM_BASE_MODEM (mm_broadband_modem_motorola_new ( mm_port_probe_get_port_physdev (probe), mm_port_probe_get_port_driver (probe), mm_plugin_get_name (MM_PLUGIN (base)), vendor, product)); if (!mm_base_modem_grab_port (existing ? existing : modem, subsys, name, MM_PORT_TYPE_AT, /* we only allow AT ports here */ MM_AT_PORT_FLAG_NONE, error)) { if (modem) g_object_unref (modem); return NULL; } return existing ? existing : modem; }
static MMBaseModem * grab_port (MMPluginBase *base, MMBaseModem *existing, MMPortProbe *probe, GError **error) { MMBaseModem *modem = NULL; const gchar *name, *subsys, *driver; guint16 vendor = 0, product = 0; /* The Gobi plugin only handles AT and QCDM ports (for now) */ if (!mm_port_probe_is_at (probe) && !mm_port_probe_is_qcdm (probe)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Ignoring non-AT/non-QCDM port"); return NULL; } subsys = mm_port_probe_get_port_subsys (probe); name = mm_port_probe_get_port_name (probe); driver = mm_port_probe_get_port_driver (probe); if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Could not get modem product ID"); return NULL; } /* If this is the first port being grabbed, create a new modem object */ if (!existing) modem = MM_BASE_MODEM (mm_broadband_modem_gobi_new (mm_port_probe_get_port_physdev (probe), driver, mm_plugin_get_name (MM_PLUGIN (base)), vendor, product)); if (!mm_base_modem_grab_port (existing ? existing : modem, subsys, name, mm_port_probe_get_port_type (probe), MM_AT_PORT_FLAG_NONE, error)) { if (modem) g_object_unref (modem); return NULL; } return existing ? existing : modem; }
static MMBaseModem * grab_port (MMPluginBase *base, MMBaseModem *existing, MMPortProbe *probe, GError **error) { MMBaseModem *modem = NULL; const gchar *name, *subsys, *driver; guint16 vendor = 0, product = 0; /* The Iridium plugin cannot do anything with non-AT ports */ if (!mm_port_probe_is_at (probe)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Ignoring non-AT port"); return NULL; } subsys = mm_port_probe_get_port_subsys (probe); name = mm_port_probe_get_port_name (probe); driver = mm_port_probe_get_port_driver (probe); /* Try to get Product IDs from udev. Note that it is not an error * if we can't get them in our case, as we also support serial * modems. */ mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product); /* If this is the first port being grabbed, create a new modem object */ if (!existing) modem = MM_BASE_MODEM (mm_broadband_modem_iridium_new ( mm_port_probe_get_port_physdev (probe), driver, mm_plugin_get_name (MM_PLUGIN (base)), vendor, product)); if (!mm_base_modem_grab_port (existing ? existing : modem, subsys, name, MM_PORT_TYPE_AT, /* we only allow AT ports here */ MM_AT_PORT_FLAG_NONE, error)) { if (modem) g_object_unref (modem); return NULL; } return existing ? existing : modem; }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { gchar *str; MMAtPortFlag pflags; pflags = (MMAtPortFlag) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (probe), TAG_AT_PORT_FLAGS)); str = mm_at_port_flag_build_string_from_mask (pflags); mm_dbg ("(%s/%s) Port will have AT flags '%s'", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), str); g_free (str); return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_port_type (probe), pflags, error); }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { if (MM_IS_BROADBAND_MODEM_SIERRA (modem)) return mm_common_sierra_grab_port (self, modem, probe, error); if (MM_IS_BROADBAND_MODEM_TELIT (modem)) return telit_grab_port (self, modem, probe, error); return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), mm_port_probe_get_port_type (probe), MM_PORT_SERIAL_AT_FLAG_NONE, error); }
static void try_next_usbif (MMDevice *device) { FirstInterfaceContext *fi_ctx; GList *l; gint closest; fi_ctx = g_object_get_data (G_OBJECT (device), TAG_FIRST_INTERFACE_CONTEXT); g_assert (fi_ctx != NULL); /* Look for the next closest one among the list of interfaces in the device, * and enable that one as being first */ closest = G_MAXINT; for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) { MMPortProbe *probe = MM_PORT_PROBE (l->data); /* Only expect ttys for next probing attempt */ if (g_str_equal (mm_port_probe_get_port_subsys (probe), "tty")) { gint usbif; usbif = g_udev_device_get_property_as_int (mm_port_probe_peek_port (probe), "ID_USB_INTERFACE_NUM"); if (usbif == fi_ctx->first_usbif) { /* This is the one we just probed, which wasn't yet removed, so just skip it */ } else if (usbif > fi_ctx->first_usbif && usbif < closest) { closest = usbif; } } } if (closest == G_MAXINT) { /* No more ttys to try! Just return something */ closest = 0; mm_dbg ("(Huawei) No more ports to run initial probing"); } else { mm_dbg ("(Huawei) Will try initial probing with interface '%d' instead", closest); } fi_ctx->first_usbif = closest; }
static MMBaseModem * grab_port (MMPluginBase *base, MMBaseModem *existing, MMPortProbe *probe, GError **error) { MMBaseModem *modem = NULL; GUdevDevice *port; MMPortType ptype; const gchar *name, *subsys; guint16 vendor = 0, product = 0; MMAtPortFlag pflags = MM_AT_PORT_FLAG_NONE; /* The Simtech plugin cannot do anything with non-AT non-QCDM ports */ if (!mm_port_probe_is_at (probe) && !mm_port_probe_is_qcdm (probe)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Ignoring non-AT non-QCDM port"); return NULL; } port = mm_port_probe_get_port (probe); /* transfer none */ subsys = mm_port_probe_get_port_subsys (probe); name = mm_port_probe_get_port_name (probe); if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) { g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Could not get modem product ID"); return NULL; } /* Look for port type hints; just probing can't distinguish which port should * be the data/primary port on these devices. We have to tag them based on * 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")) pflags = MM_AT_PORT_FLAG_PRIMARY; else if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_AUX")) pflags = MM_AT_PORT_FLAG_SECONDARY; /* 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 (pflags == MM_AT_PORT_FLAG_NONE && g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; else ptype = mm_port_probe_get_port_type (probe); /* If this is the first port being grabbed, create a new modem object */ if (!existing) modem = MM_BASE_MODEM (mm_broadband_modem_simtech_new (mm_port_probe_get_port_physdev (probe), mm_port_probe_get_port_driver (probe), mm_plugin_get_name (MM_PLUGIN (base)), vendor, product)); if (!mm_base_modem_grab_port (existing ? existing : modem, subsys, name, ptype, pflags, error)) { if (modem) g_object_unref (modem); return NULL; } return existing ? existing : modem; }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { GUdevDevice *port; MMDevice *device; MMPortType ptype; MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; port = mm_port_probe_peek_port (probe); ptype = mm_port_probe_get_port_type (probe); device = mm_port_probe_peek_device (probe); /* Look for port type hints; just probing can't distinguish which port should * be the data/primary port on these devices. We have to tag them based on * what the Windows .INF files say the port layout should be. * * If no udev rules are found, AT#PORTCFG (if supported) can be used for * identifying the port layout */ if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_MODEM_PORT)) { mm_dbg ("telit: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_AUX_PORT)) { mm_dbg ("telit: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; } else if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_NMEA_PORT)) { mm_dbg ("telit: port '%s/%s' flagged as NMEA", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); ptype = MM_PORT_TYPE_GPS; } else if (g_object_get_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED) != NULL) { if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT)) == 0) { mm_dbg ("telit: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_AUX_PORT)) == 0) { mm_dbg ("telit: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; } else if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT)) == 0) { mm_dbg ("telit: port '%s/%s' flagged as NMEA", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); ptype = MM_PORT_TYPE_GPS; } else ptype = MM_PORT_TYPE_IGNORED; } else { /* 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. */ ptype = MM_PORT_TYPE_IGNORED; } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), ptype, pflags, error); }
MMBaseModem * mm_plugin_create_modem (MMPlugin *self, MMDevice *device, GError **error) { MMBaseModem *modem = NULL; GList *port_probes, *l; port_probes = mm_device_peek_port_probe_list (device); /* Let the plugin create the modem from the port probe results */ modem = MM_PLUGIN_GET_CLASS (self)->create_modem (MM_PLUGIN (self), mm_device_get_path (device), mm_device_get_drivers (device), mm_device_get_vendor (device), mm_device_get_product (device), port_probes, error); if (modem) { /* Grab each port */ for (l = port_probes; l; l = g_list_next (l)) { GError *inner_error = NULL; MMPortProbe *probe = MM_PORT_PROBE (l->data); gboolean grabbed; /* If grabbing a port fails, just warn. We'll decide if the modem is * valid or not when all ports get organized */ /* We apply again the subsystem filter, as the port may have been * probed and accepted by the generic plugin, which is overwritten * by the specific one when needed. */ if (apply_subsystem_filter (self, mm_port_probe_peek_port (probe))) { grabbed = FALSE; inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "unsupported subsystem: '%s'", mm_port_probe_get_port_subsys (probe)); } #if !defined WITH_QMI else if (mm_port_probe_get_port_type (probe) == MM_PORT_TYPE_NET && g_str_equal (mm_device_utils_get_port_driver (mm_port_probe_peek_port (probe)), "qmi_wwan")) { grabbed = FALSE; inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "ignoring QMI net port"); } #endif else if (MM_PLUGIN_GET_CLASS (self)->grab_port) grabbed = MM_PLUGIN_GET_CLASS (self)->grab_port (MM_PLUGIN (self), modem, probe, &inner_error); else grabbed = mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_port_type (probe), MM_AT_PORT_FLAG_NONE, &inner_error); if (!grabbed) { mm_warn ("Could not grab port (%s/%s): '%s'", mm_port_probe_get_port_subsys (MM_PORT_PROBE (l->data)), mm_port_probe_get_port_name (MM_PORT_PROBE (l->data)), inner_error ? inner_error->message : "unknown error"); g_clear_error (&inner_error); } } /* If organizing ports fails, consider the modem invalid */ if (!mm_base_modem_organize_ports (modem, error)) g_clear_object (&modem); } return modem; }