static MMModem * grab_port (MMPluginBase *base, MMModem *existing, MMPluginBaseSupportsTask *task, GError **error) { GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; MMPortType ptype = MM_PORT_TYPE_UNKNOWN; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); devfile = g_udev_device_get_device_file (port); if (!devfile) { g_set_error (error, 0, 0, "Could not get port's sysfs file."); return NULL; } subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); /* Is it a GSM secondary port? */ if (g_object_get_data (G_OBJECT (task), TAG_SIERRA_SECONDARY_PORT)) ptype = MM_PORT_TYPE_SECONDARY; 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)) { modem = mm_modem_sierra_gsm_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), mm_plugin_get_name (MM_PLUGIN (base))); } else if (caps & CAP_CDMA) { modem = mm_modem_sierra_cdma_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), mm_plugin_get_name (MM_PLUGIN (base)), !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856), !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856_A)); } if (modem) { if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) { g_object_unref (modem); return NULL; } } } else if (get_level_for_capabilities (caps) || (ptype != MM_PORT_TYPE_UNKNOWN)) { modem = existing; if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) return NULL; } return modem; }
void mm_plugin_base_supports_task_complete (MMPluginBaseSupportsTask *task, guint32 level) { MMPluginBaseSupportsTaskPrivate *priv; const char *subsys, *name; g_return_if_fail (task != NULL); g_return_if_fail (MM_IS_PLUGIN_BASE_SUPPORTS_TASK (task)); priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task); g_return_if_fail (priv->callback != NULL); if (priv->full_id) { g_source_remove (priv->full_id); priv->full_id = 0; } subsys = g_udev_device_get_subsystem (priv->port); name = g_udev_device_get_name (priv->port); priv->callback (MM_PLUGIN (priv->plugin), subsys, name, level, priv->callback_data); /* Clear out the callback, it shouldn't be called more than once */ priv->callback = NULL; priv->callback_data = NULL; }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_HUAWEI, MM_PLUGIN_BASE_NAME, "Huawei", NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; /* Vendors: Telit */ static const guint16 vendor_ids[] = { 0x1bc7, 0 }; /* Only handle TELIT tagged devices here. */ static const gchar *udev_tags[] = { "ID_MM_TELIT_TAGGED", NULL }; /* Custom init for port identification */ static const MMAsyncMethod custom_init = { .async = G_CALLBACK (telit_custom_init), .finish = G_CALLBACK (telit_custom_init_finish), }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_TELIT, MM_PLUGIN_NAME, "Telit", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_UDEV_TAGS, udev_tags, MM_PLUGIN_CUSTOM_INIT, &custom_init, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_SIERRA, MM_PLUGIN_BASE_NAME, "Sierra", NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_LONGCHEER, MM_PLUGIN_BASE_NAME, "Longcheer", NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; static const guint16 vendors[] = { 0x1410, /* Novatel */ 0x413c, /* Dell */ 0 }; static const mm_uint16_pair forbidden_products[] = { { 0x1410, 0x9010 }, /* Novatel E362 */ { 0, 0 } }; static const MMAsyncMethod custom_init = { .async = G_CALLBACK (novatel_custom_init), .finish = G_CALLBACK (novatel_custom_init_finish), }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_NOVATEL, MM_PLUGIN_NAME, "Novatel", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors, MM_PLUGIN_FORBIDDEN_PRODUCT_IDS, forbidden_products, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_CUSTOM_INIT, &custom_init, MM_PLUGIN_ALLOWED_QCDM, TRUE, MM_PLUGIN_ALLOWED_QMI, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { return MM_PLUGIN (g_object_new (MM_TYPE_PLUGIN_WAVECOM, MM_PLUGIN_BASE_NAME, "Wavecom", NULL)); }
MMPlugin * mm_plugin_base_supports_task_get_plugin (MMPluginBaseSupportsTask *task) { g_return_val_if_fail (task != NULL, NULL); g_return_val_if_fail (MM_IS_PLUGIN_BASE_SUPPORTS_TASK (task), NULL); return MM_PLUGIN (MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->plugin); }
static void finalize (GObject *object) { MMPlugin *self = MM_PLUGIN (object); g_free (self->priv->name); G_OBJECT_CLASS (mm_plugin_parent_class)->finalize (object); }
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 gboolean find_port_support_idle (SupportsInfo *info) { info->source_id = 0; /* Already checked all plugins? */ if (!info->current) { /* Report best plugin in asynchronous result (could be none) */ if (info->best_plugin) g_simple_async_result_set_op_res_gpointer ( info->result, g_object_ref (info->best_plugin), (GDestroyNotify)g_object_unref); else g_simple_async_result_set_op_res_gpointer ( info->result, NULL, NULL); /* We are only giving the plugin as result, so we can now safely remove * the supports info from the manager. Always untrack the supports info * before completing the operation. */ remove_supports_info (info->self, info); /* We are reporting a best plugin found to a port. We can now * 'suggest' this same plugin to other ports of the same device. */ if (info->best_plugin) suggest_supports_info_result (info->self, info->physdev_path, info->best_plugin); /* If ending without a best plugin, we need to cancel all probing tasks * that got deferred until suggested. */ else cancel_all_deferred_supports_info (info->self, info->physdev_path); g_simple_async_result_complete (info->result); supports_info_free (info); return FALSE; } /* Ask the current plugin to check support of this port */ mm_plugin_supports_port (MM_PLUGIN (info->current->data), info->subsys, info->name, info->physdev_path, info->existing, (GAsyncReadyCallback)supports_port_ready_cb, info); return FALSE; }
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; }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_GENERIC, MM_PLUGIN_NAME, MM_PLUGIN_GENERIC_NAME, MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QCDM, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const guint16 vendor_ids[] = { 0x230d, 0 }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_LINKTOP, MM_PLUGIN_BASE_NAME, "Linktop", MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_BASE_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_BASE_ALLOWED_AT, TRUE, NULL)); }
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; }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const guint16 vendor_ids[] = { 0x1a26, 0 }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_THURAYA, MM_PLUGIN_NAME, "Thuraya", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_ALLOWED_AT, TRUE, NULL)); }
static MMModem * grab_port (MMPluginBase *base, MMModem *existing, MMPluginBaseSupportsTask *task, GError **error) { GUdevDevice *port = NULL; MMModem *modem = NULL; 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); 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; } 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) { modem = mm_modem_wavecom_gsm_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), mm_plugin_get_name (MM_PLUGIN (base)), vendor, product); } if (modem) { 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, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) return NULL; } return modem; }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const gchar *drivers[] = { "qcserial", NULL }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_GOBI, MM_PLUGIN_BASE_NAME, "Gobi", MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_BASE_ALLOWED_DRIVERS, drivers, MM_PLUGIN_BASE_ALLOWED_AT, TRUE, MM_PLUGIN_BASE_ALLOWED_QCDM, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const guint16 vendor_ids[] = { 0x1e0e, /* A-Link (for now) */ 0 }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_SIMTECH, MM_PLUGIN_BASE_NAME, "SimTech", MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_BASE_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_BASE_ALLOWED_AT, TRUE, MM_PLUGIN_BASE_ALLOWED_QCDM, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", NULL }; static const gchar *udev_tags[] = { "ID_MM_ERICSSON_MBM", NULL }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_MBM, MM_PLUGIN_NAME, "Ericsson MBM", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_UDEV_TAGS, udev_tags, MM_PLUGIN_ALLOWED_AT, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; static const guint16 vendor_ids[] = { 0x106c, 0 }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_PANTECH, MM_PLUGIN_NAME, "Pantech", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QCDM, TRUE, MM_PLUGIN_ALLOWED_QMI, TRUE, MM_PLUGIN_CUSTOM_AT_PROBE, custom_at_probe, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const mm_uint16_pair product_ids[] = { { 0x22b8, 0x3802 }, /* C330/C350L/C450/EZX GSM Phone */ { 0x22b8, 0x4902 }, /* Triplet GSM Phone */ { 0, 0 } }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_MOTOROLA, MM_PLUGIN_BASE_NAME, "Motorola", MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_BASE_ALLOWED_PRODUCT_IDS, product_ids, MM_PLUGIN_BASE_ALLOWED_AT, TRUE, NULL)); }
static gboolean try_open (gpointer user_data) { MMPluginBaseSupportsTask *task = MM_PLUGIN_BASE_SUPPORTS_TASK (user_data); MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task); GError *error = NULL; task_priv->open_id = 0; if (!mm_serial_port_open (MM_SERIAL_PORT (task_priv->probe_port), &error)) { if (++task_priv->open_tries > 4) { /* took too long to open the port; give up */ g_warning ("(%s): failed to open after 4 tries.", mm_port_get_device (MM_PORT (task_priv->probe_port))); probe_complete (task); } else if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_OPEN_FAILED_NO_DEVICE)) { /* this is nozomi being dumb; try again */ task_priv->open_id = g_timeout_add_seconds (1, try_open, task); } else { /* some other hard error */ probe_complete (task); } g_clear_error (&error); } else { /* success, start probing */ GUdevDevice *port; port = mm_plugin_base_supports_task_get_port (task); g_assert (port); task_priv->full_id = g_signal_connect (task_priv->probe_port, "buffer-full", G_CALLBACK (port_buffer_full), task); g_debug ("(%s): probe requested by plugin '%s'", g_udev_device_get_name (port), mm_plugin_get_name (MM_PLUGIN (task_priv->plugin))); mm_serial_port_flash (MM_SERIAL_PORT (task_priv->probe_port), 100, TRUE, flash_done, task); } return FALSE; }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; static const guint16 vendor_ids[] = { 0x12d1, 0 }; static const MMAsyncMethod custom_init = { .async = G_CALLBACK (huawei_custom_init), .finish = G_CALLBACK (huawei_custom_init_finish), }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_HUAWEI, MM_PLUGIN_NAME, "Huawei", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QCDM, TRUE, MM_PLUGIN_CUSTOM_INIT, &custom_init, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const guint16 vendor_ids[] = { 0x1edd, 0 }; static const gchar *vendor_strings[] = { "iridium", NULL }; /* Also support motorola-branded Iridium modems */ static const mm_str_pair product_strings[] = {{"motorola", "satellite" }, { NULL, NULL }}; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_IRIDIUM, MM_PLUGIN_BASE_NAME, "Iridium", MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_BASE_ALLOWED_VENDOR_STRINGS, vendor_strings, MM_PLUGIN_BASE_ALLOWED_PRODUCT_STRINGS, product_strings, MM_PLUGIN_BASE_ALLOWED_VENDOR_IDS, vendor_ids, MM_PLUGIN_BASE_ALLOWED_AT, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", NULL }; static const guint16 vendors[] = { 0x1410, /* Novatel */ 0x413c, /* Dell */ 0 }; static const mm_uint16_pair forbidden_products[] = { { 0x1410, 0x9010 }, /* Novatel E362 */ {0, 0} }; static const gchar *drivers[] = { "option1", "option", NULL }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_NOVATEL, MM_PLUGIN_NAME, "Novatel", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_DRIVERS, drivers, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors, MM_PLUGIN_FORBIDDEN_PRODUCT_IDS, forbidden_products, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QCDM, TRUE, NULL)); }
G_MODULE_EXPORT MMPlugin * mm_plugin_create (void) { static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; static const gchar *drivers[] = { "sierra", "sierra_net", NULL }; static const MMAsyncMethod custom_init = { .async = G_CALLBACK (sierra_custom_init), .finish = G_CALLBACK (sierra_custom_init_finish), }; return MM_PLUGIN ( g_object_new (MM_TYPE_PLUGIN_SIERRA, MM_PLUGIN_NAME, "Sierra", MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_DRIVERS, drivers, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QCDM, TRUE, MM_PLUGIN_CUSTOM_INIT, &custom_init, MM_PLUGIN_ICERA_PROBE, TRUE, MM_PLUGIN_REMOVE_ECHO, FALSE, NULL)); }
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 void supports_port_ready_cb (MMPlugin *plugin, GAsyncResult *result, SupportsInfo *info) { MMPluginSupportsResult support_result; GError *error = NULL; /* Get supports check results */ support_result = mm_plugin_supports_port_finish (plugin, result, &error); if (error) { mm_warn ("(%s): (%s) error when checking support: '%s'", mm_plugin_get_name (plugin), info->name, error->message); g_error_free (error); } switch (support_result) { case MM_PLUGIN_SUPPORTS_PORT_SUPPORTED: /* Found a best plugin */ info->best_plugin = plugin; if (info->suggested_plugin && info->suggested_plugin != plugin) { /* The last plugin we tried said it supported this port, but it * doesn't correspond with the one we're being suggested. */ g_warn_if_reached (); } mm_dbg ("(%s): (%s) found best plugin for port", mm_plugin_get_name (info->best_plugin), info->name); info->current = NULL; /* Schedule checking support, which will end the operation */ info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle, info); break; case MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED: if (info->suggested_plugin) { if (info->suggested_plugin == plugin) { /* If the plugin that just completed the support check claims * not to support this port, but this plugin is clearly the * right plugin since it claimed this port's physical modem, * just drop the port. */ mm_dbg ("(%s/%s): ignoring port unsupported by physical modem's plugin", info->subsys, info->name); info->best_plugin = NULL; info->current = NULL; } else { /* The last plugin we tried is NOT the one we got suggested, so * directly check support with the suggested plugin. If we * already checked its support, it won't be checked again. */ info->current = g_slist_find (info->current, info->suggested_plugin); } } else { /* If the plugin knows it doesn't support the modem, just keep on * checking the next plugin. */ info->current = g_slist_next (info->current); } info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle, info); break; case MM_PLUGIN_SUPPORTS_PORT_DEFER: /* Try with the suggested one after being deferred */ if (info->suggested_plugin) { mm_dbg ("(%s): (%s) deferring support check, suggested: %s", mm_plugin_get_name (MM_PLUGIN (info->current->data)), info->name, mm_plugin_get_name (MM_PLUGIN (info->suggested_plugin))); info->current = g_slist_find (info->current, info->suggested_plugin); } else { mm_dbg ("(%s): (%s) deferring support check", mm_plugin_get_name (MM_PLUGIN (info->current->data)), info->name); } /* Schedule checking support */ info->source_id = g_timeout_add_seconds (SUPPORTS_DEFER_TIMEOUT_SECS, (GSourceFunc)find_port_support_idle, info); break; case MM_PLUGIN_SUPPORTS_PORT_DEFER_UNTIL_SUGGESTED: /* If we arrived here and we already have a plugin suggested, use it */ if (info->suggested_plugin) { mm_dbg ("(%s): (%s) task completed, got suggested plugin", mm_plugin_get_name (info->suggested_plugin), info->name); /* Schedule checking support, which will end the operation */ info->best_plugin = info->suggested_plugin; info->current = NULL; info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle, info); } else { /* We are deferred until a suggested plugin is given. If last supports task * of a given device is finished without finding a best plugin, this task * will get finished reporting unsupported. */ mm_dbg ("(%s) deferring support check until result suggested", info->name); info->defer_until_suggested = TRUE; } break; } }