static void setup_ports (MMBroadbandModem *self) { gpointer parser; MMAtSerialPort *primary; GRegex *regex; /* Call parent's setup ports first always */ MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_wavecom_parent_class)->setup_ports (self); /* Set 9600 baudrate by default in the AT port */ mm_dbg ("Baudrate will be set to 9600 bps..."); primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); if (!primary) return; /* AT+CPIN? replies will never have an OK appended */ parser = mm_serial_parser_v1_new (); regex = g_regex_new ("\\r\\n\\+CPIN: .*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); mm_serial_parser_v1_set_custom_regex (parser, regex, NULL); g_regex_unref (regex); mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (primary), mm_serial_parser_v1_parse, parser, mm_serial_parser_v1_destroy); }
gboolean mm_plugin_base_probe_port (MMPluginBase *self, MMPluginBaseSupportsTask *task, GError **error) { MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task); MMAtSerialPort *serial; const char *name; GUdevDevice *port; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (MM_IS_PLUGIN_BASE (self), FALSE); g_return_val_if_fail (task != NULL, FALSE); port = mm_plugin_base_supports_task_get_port (task); g_assert (port); name = g_udev_device_get_name (port); g_assert (name); serial = mm_at_serial_port_new (name, MM_PORT_TYPE_PRIMARY); if (serial == NULL) { g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Failed to create new serial port."); return FALSE; } g_object_set (serial, MM_SERIAL_PORT_SEND_DELAY, (guint64) 100000, MM_PORT_CARRIER_DETECT, FALSE, NULL); mm_at_serial_port_set_response_parser (serial, mm_serial_parser_v1_parse, mm_serial_parser_v1_new (), mm_serial_parser_v1_destroy); /* Open the port */ task_priv->probe_port = serial; task_priv->open_id = g_idle_add (try_open, task); return TRUE; }
static gboolean serial_open_at (MMPortProbe *self) { PortProbeRunTask *task = self->priv->task; GError *error = NULL; task->source_id = 0; /* If already cancelled, do nothing else */ if (port_probe_run_is_cancelled (self)) return FALSE; /* Create AT serial port if not done before */ if (!task->serial) { task->serial = MM_SERIAL_PORT (mm_at_serial_port_new (self->priv->name)); if (!task->serial) { port_probe_run_task_complete ( task, FALSE, g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "(%s) couldn't create AT port", self->priv->name)); return FALSE; } g_object_set (task->serial, MM_SERIAL_PORT_SEND_DELAY, task->at_send_delay, MM_PORT_CARRIER_DETECT, FALSE, MM_SERIAL_PORT_SPEW_CONTROL, TRUE, NULL); mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (task->serial), mm_serial_parser_v1_parse, mm_serial_parser_v1_new (), mm_serial_parser_v1_destroy); } /* Try to open the port */ if (!mm_serial_port_open (task->serial, &error)) { /* Abort if maximum number of open tries reached */ if (++task->at_open_tries > 4) { /* took too long to open the port; give up */ port_probe_run_task_complete ( task, FALSE, g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "(%s) failed to open port after 4 tries", self->priv->name)); } else if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_OPEN_FAILED_NO_DEVICE)) { /* this is nozomi being dumb; try again */ task->source_id = g_timeout_add_seconds (1, (GSourceFunc)serial_open_at, self); } else { port_probe_run_task_complete ( task, FALSE, g_error_new (MM_SERIAL_ERROR, MM_SERIAL_ERROR_OPEN_FAILED, "(%s) failed to open port: %s", self->priv->name, (error ? error->message : "unknown error"))); } g_clear_error (&error); return FALSE; } /* success, start probing */ task->buffer_full_id = g_signal_connect (task->serial, "buffer-full", G_CALLBACK (serial_buffer_full), self); mm_serial_port_flash (MM_SERIAL_PORT (task->serial), 100, TRUE, (MMSerialFlashFn)serial_flash_done, self); return FALSE; }
gboolean mm_base_modem_grab_port (MMBaseModem *self, const gchar *subsys, const gchar *name, MMPortType ptype, MMAtPortFlag at_pflags, GError **error) { MMPort *port; gchar *key; g_return_val_if_fail (MM_IS_BASE_MODEM (self), FALSE); g_return_val_if_fail (subsys != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE); /* Only allow 'tty', 'net' and 'cdc-wdm' ports */ if (!g_str_equal (subsys, "net") && !g_str_equal (subsys, "tty") && !(g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', unhandled subsystem", subsys, name); return FALSE; } /* Check whether we already have it stored */ key = get_hash_key (subsys, name); port = g_hash_table_lookup (self->priv->ports, key); if (port) { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', already exists", subsys, name); g_free (key); return FALSE; } /* Serial ports... */ if (g_str_equal (subsys, "tty")) { if (ptype == MM_PORT_TYPE_QCDM) /* QCDM port */ port = MM_PORT (mm_qcdm_serial_port_new (name)); else if (ptype == MM_PORT_TYPE_AT) { /* AT port */ port = MM_PORT (mm_at_serial_port_new (name)); /* Set common response parser */ 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); /* Store flags already */ mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags); } else if (ptype == MM_PORT_TYPE_GPS) { /* Raw GPS port */ port = MM_PORT (mm_gps_serial_port_new (name)); } else { g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', unhandled serial type", subsys, name); g_free (key); return FALSE; } /* For serial ports, enable port timeout checks */ g_signal_connect (port, "timed-out", G_CALLBACK (serial_port_timed_out_cb), self); } /* Net ports... */ else if (g_str_equal (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, MM_PORT_TYPE_NET, NULL)); } /* QMI ports... */ else if (g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm")) { #if defined WITH_QMI port = MM_PORT (mm_qmi_port_new (name)); #else g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, "Cannot add port '%s/%s', QMI support not available", subsys, name); g_free (key); return FALSE; #endif } else /* We already filter out before all non-tty, non-net, non-qmi ports */ g_assert_not_reached(); mm_dbg ("(%s) type '%s' claimed by %s", name, mm_port_type_get_string (ptype), mm_base_modem_get_device (self)); /* Add it to the tracking HT. * Note: 'key' and 'port' now owned by the HT. */ g_hash_table_insert (self->priv->ports, key, port); return TRUE; }