예제 #1
0
static void
remove_modem (MMManager *manager,
              MMBaseModem *modem)
{
    gchar *path;
    gchar *device;

    device = g_strdup (mm_base_modem_get_device (modem));
    path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (modem)));

    /* If we get DBus object path, modem was exported */
    if (path) {
        g_dbus_object_manager_server_unexport (manager->priv->object_manager, path);
        g_object_set (modem,
                      MM_BASE_MODEM_CONNECTION, NULL,
                      NULL);

        mm_dbg ("Unexported modem '%s' from path '%s'", device, path);
        g_free (path);
    } else {
        mm_dbg ("Removing modem '%s', which wasn't exported yet", device);
    }

    /* Run dispose before unref-ing, in order to cleanup the SIM object,
     * if any (which also holds a reference to the modem object) */
    g_object_run_dispose (G_OBJECT (modem));
    g_hash_table_remove (manager->priv->modems, device);
    g_free (device);
}
예제 #2
0
static void
curc_ready (MMAtSerialPort *port,
            GString *response,
            GError *error,
            HuaweiCustomInitContext *ctx)
{
    if (error) {
        /* Retry if we get a timeout error */
        if (g_error_matches (error,
                             MM_SERIAL_ERROR,
                             MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) {
            huawei_custom_init_step (ctx);
            return;
        }

        mm_dbg ("(Huawei) couldn't turn off unsolicited messages in"
                "secondary ports: '%s'",
                error->message);
    }

    mm_dbg ("(Huawei) unsolicited messages in secondary ports turned off");

    ctx->curc_done = TRUE;
    huawei_custom_init_step (ctx);
}
static gboolean
modem_load_access_technologies_finish (MMIfaceModem *self,
                                       GAsyncResult *res,
                                       MMModemAccessTechnology *access_technologies,
                                       guint *mask,
                                       GError **error)
{
    SnapshotResult *r;
    MMModemAccessTechnology act;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    r = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));

    act = r->generic_act;
    if (act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK) {
        /* Update access technology with specific EVDO revision from QCDM */
        if (r->hdr_revision == QCDM_HDR_REV_0) {
            mm_dbg ("Novatel Modem Snapshot EVDO revision: 0");
            act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK;
            act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
        } else if (r->hdr_revision == QCDM_HDR_REV_A) {
            mm_dbg ("Novatel Modem Snapshot EVDO revision: A");
            act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK;
            act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDOA;
        } else
            mm_dbg ("Novatel Modem Snapshot EVDO revision: %d (unknown)", r->hdr_revision);
    }

    *access_technologies = act;
    *mask = r->mask;
    return TRUE;
}
예제 #4
0
void
mm_port_probe_set_result_qmi (MMPortProbe *self,
                              gboolean qmi)
{
    self->priv->is_qmi = qmi;
    self->priv->flags |= MM_PORT_PROBE_QMI;

    if (self->priv->is_qmi) {
        mm_dbg ("(%s/%s) port is QMI-capable",
                g_udev_device_get_subsystem (self->priv->port),
                g_udev_device_get_name (self->priv->port));

        /* Also set as not an AT/QCDM port */
        self->priv->is_at = FALSE;
        self->priv->is_qcdm = FALSE;
        self->priv->vendor = NULL;
        self->priv->product = NULL;
        self->priv->flags |= (MM_PORT_PROBE_AT |
                              MM_PORT_PROBE_AT_VENDOR |
                              MM_PORT_PROBE_AT_PRODUCT |
                              MM_PORT_PROBE_AT_ICERA |
                              MM_PORT_PROBE_QCDM);
    } else
        mm_dbg ("(%s/%s) port is not QMI-capable",
                g_udev_device_get_subsystem (self->priv->port),
                g_udev_device_get_name (self->priv->port));
}
예제 #5
0
static void
sierra_custom_init_step (SierraCustomInitContext *ctx)
{
    /* If cancelled, end */
    if (g_cancellable_is_cancelled (ctx->cancellable)) {
        mm_dbg ("(Sierra) no need to keep on running custom init in (%s)",
                mm_port_get_device (MM_PORT (ctx->port)));
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "Custom initialization cancelled");
        sierra_custom_init_context_complete_and_free (ctx);
        return;
    }

    if (ctx->retries == 0) {
        mm_dbg ("(Sierra) Couldn't get port type hints");
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        sierra_custom_init_context_complete_and_free (ctx);
        return;
    }

    ctx->retries--;
    mm_at_serial_port_queue_command (
        ctx->port,
        "ATI",
        3,
        FALSE, /* raw */
        ctx->cancellable,
        (MMAtSerialResponseFn)gcap_ready,
        ctx);
}
예제 #6
0
static void
initialize_ready (MMBaseModem *self,
                  GAsyncResult *res)
{
    GError *error = NULL;

    if (mm_base_modem_initialize_finish (self, res, &error)) {
        mm_dbg ("modem properly initialized");
        mm_base_modem_set_valid (self, TRUE);
        return;
    }

    /* Wrong state is returned when modem is found locked */
    if (g_error_matches (error, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE)) {
        /* Even with initialization errors, we do set the state to valid, so
         * that the modem gets exported and the failure notified to the user.
         */
        mm_dbg ("Couldn't finish initialization in the current state: '%s'",
                error->message);
        g_error_free (error);
        mm_base_modem_set_valid (self, TRUE);
        return;
    }

    /* Really fatal, we cannot even export the failed modem (e.g. error before
     * even trying to enable the Modem interface */
    mm_warn ("couldn't initialize the modem: '%s'", error->message);
    g_error_free (error);
}
예제 #7
0
void
mm_port_probe_set_result_at (MMPortProbe *self,
                             gboolean at)
{
    self->priv->is_at = at;
    self->priv->flags |= MM_PORT_PROBE_AT;

    if (self->priv->is_at) {
        mm_dbg ("(%s/%s) port is AT-capable",
                g_udev_device_get_subsystem (self->priv->port),
                g_udev_device_get_name (self->priv->port));

        /* Also set as not a QCDM/QMI port */
        self->priv->is_qcdm = FALSE;
        self->priv->is_qmi = FALSE;
        self->priv->flags |= (MM_PORT_PROBE_QCDM | MM_PORT_PROBE_QMI);
    } else {
        mm_dbg ("(%s/%s) port is not AT-capable",
                g_udev_device_get_subsystem (self->priv->port),
                g_udev_device_get_name (self->priv->port));
        self->priv->vendor = NULL;
        self->priv->product = NULL;
        self->priv->is_icera = FALSE;
        self->priv->flags |= (MM_PORT_PROBE_AT_VENDOR |
                              MM_PORT_PROBE_AT_PRODUCT |
                              MM_PORT_PROBE_AT_ICERA);
    }
}
예제 #8
0
static void
print_address6 (gboolean success,
                const char *tag,
                GArray *array,
                guint32 prefix,
                GError *error)
{
    struct in6_addr a;
    char buf[INET6_ADDRSTRLEN + 1];
    guint32 i;

    if (success) {
        g_assert (array);
        g_assert (array->len == 8);

        memset (buf, 0, sizeof (buf));
        for (i = 0; i < array->len; i++)
            a.s6_addr16[i] = GUINT16_TO_BE (g_array_index (array, guint16, i));

        if (inet_ntop (AF_INET6, &a, buf, sizeof (buf) - 1))
            mm_dbg ("    %s: %s/%d", tag, buf, prefix);
        else
            mm_dbg ("    %s: failed (address conversion error)", tag);

        g_array_free (array, TRUE);
        return;
    }

    mm_dbg ("    %s: failed (%s)", tag, error ? error->message : "unknown");
}
static void
nw_snapshot_old_cb (MMPortSerialQcdm *port,
                    GAsyncResult *res,
                    SnapshotContext *ctx)
{
    QcdmResult *result;
    guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        /* Just ignore the error and complete with the input info */
        mm_dbg ("Couldn't run QCDM Novatel Modem MSM6500 snapshot: '%s'", error->message);
        g_error_free (error);
        snapshot_context_complete_and_free (ctx, QCDM_HDR_REV_UNKNOWN);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const gchar *) response->data, response->len, NULL);
    g_byte_array_unref (response);
    if (result) {
        qcdm_result_get_u8 (result, QCDM_CMD_NW_SUBSYS_MODEM_SNAPSHOT_CDMA_ITEM_HDR_REV, &hdr_revision);
        qcdm_result_unref (result);
    } else
        mm_dbg ("Failed to get QCDM Novatel Modem MSM6500 snapshot.");

    snapshot_context_complete_and_free (ctx, hdr_revision);
}
예제 #10
0
static void
curc_ready (MMPortSerialAt *port,
            GAsyncResult *res,
            HuaweiCustomInitContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_port_serial_at_command_finish (port, res, &error);
    if (error) {
        /* Retry if we get a timeout error */
        if (g_error_matches (error,
                             MM_SERIAL_ERROR,
                             MM_SERIAL_ERROR_RESPONSE_TIMEOUT))
            goto out;

        mm_dbg ("(Huawei) couldn't turn off unsolicited messages in secondary ports: '%s'",
                error->message);
    }

    mm_dbg ("(Huawei) unsolicited messages in secondary ports turned off");

    ctx->curc_done = TRUE;

out:
    if (error)
        g_error_free (error);

    huawei_custom_init_step (ctx);
}
예제 #11
0
void
mm_manager_start (MMManager *manager)
{
    GList *devices, *iter;

    g_return_if_fail (manager != NULL);
    g_return_if_fail (MM_IS_MANAGER (manager));

    mm_dbg ("Starting device scan...");

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "tty");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        device_added (manager, G_UDEV_DEVICE (iter->data));
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "net");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        device_added (manager, G_UDEV_DEVICE (iter->data));
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    mm_dbg ("Finished device scan...");
}
예제 #12
0
static void
device_removed (MMBaseManager *self,
                GUdevDevice *udev_device)
{
    MMDevice *device;
    const gchar *subsys;
    const gchar *name;

    g_return_if_fail (udev_device != NULL);

    subsys = g_udev_device_get_subsystem (udev_device);
    name = g_udev_device_get_name (udev_device);

    if (!g_str_has_prefix (subsys, "usb") ||
        (name && g_str_has_prefix (name, "cdc-wdm"))) {
        /* Handle tty/net/wdm port removal */
        device = find_device_by_port (self, udev_device);
        if (device) {
            mm_info ("(%s/%s): released by modem %s",
                     subsys,
                     name,
                     g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
            mm_device_release_port (device, udev_device);

            /* If port probe list gets empty, remove the device object iself */
            if (!mm_device_peek_port_probe_list (device)) {
                mm_dbg ("Removing empty device '%s'", mm_device_get_path (device));
                if (mm_plugin_manager_device_support_check_cancel (self->priv->plugin_manager, device))
                    mm_dbg ("Device support check has been cancelled");
                mm_device_remove_modem (device);
                g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
            }
        }

        return;
    }

    /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging
     * an in-use ttyACMx device results in udev generating remove events for the usb, but the
     * ttyACMx device (subsystem tty) is not removed, since it was in-use.  So if we have not
     * found a modem for the port (above), we're going to look here to see if we have a modem
     * associated with the newly removed device.  If so, we'll remove the modem, since the
     * device has been removed.  That way, if the device is reinserted later, we'll go through
     * the process of exporting it.
     */
    device = find_device_by_udev_device (self, udev_device);
    if (device) {
        mm_dbg ("Removing device '%s'", mm_device_get_path (device));
        mm_device_remove_modem (device);
        g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
        return;
    }

    /* Maybe a plugin is checking whether or not the port is supported.
     * TODO: Cancel every possible supports check in this port. */
}
static void
supported_ms_classes_query_ready (MMBaseModem *self,
                                  GAsyncResult *res,
                                  GSimpleAsyncResult *simple)
{
    const gchar *response;
    GError *error = NULL;
    MMModemMode mode;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!response) {
        /* Let the error be critical. */
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    response = mm_strip_tag (response, "+CGCLASS:");
    mode = MM_MODEM_MODE_NONE;

    if (strstr (response, WAVECOM_MS_CLASS_A_IDSTR)) {
        mm_dbg ("Modem supports Class A mobile station");
        mode |= MM_MODEM_MODE_3G;
    }

    if (strstr (response, WAVECOM_MS_CLASS_B_IDSTR)) {
        mm_dbg ("Modem supports Class B mobile station");
        mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_CS);
    }

    if (strstr (response, WAVECOM_MS_CLASS_CG_IDSTR)) {
        mm_dbg ("Modem supports Class CG mobile station");
        mode |= MM_MODEM_MODE_2G;
    }

    if (strstr (response, WAVECOM_MS_CLASS_CC_IDSTR)) {
        mm_dbg ("Modem supports Class CC mobile station");
        mode |= MM_MODEM_MODE_CS;
    }

    /* If none received, error */
    if (mode == MM_MODEM_MODE_NONE)
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Couldn't get supported mobile station classes: '%s'",
                                         response);
    else
        g_simple_async_result_set_op_res_gpointer (simple,
                                                   GUINT_TO_POINTER (mode),
                                                   NULL);

    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}
예제 #14
0
void
mm_base_manager_start (MMBaseManager *manager,
                       gboolean manual_scan)
{
    GList *devices, *iter;

    g_return_if_fail (manager != NULL);
    g_return_if_fail (MM_IS_BASE_MANAGER (manager));

    if (!manager->priv->auto_scan && !manual_scan)
        return;

    mm_dbg ("Starting %s device scan...", manual_scan ? "manual" : "automatic");

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "tty");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        start_device_added (manager, G_UDEV_DEVICE (iter->data), manual_scan);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "net");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        start_device_added (manager, G_UDEV_DEVICE (iter->data), manual_scan);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usb");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        const gchar *name;

        name = g_udev_device_get_name (G_UDEV_DEVICE (iter->data));
        if (name && g_str_has_prefix (name, "cdc-wdm"))
            start_device_added (manager, G_UDEV_DEVICE (iter->data), manual_scan);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    /* Newer kernels report 'usbmisc' subsystem */
    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usbmisc");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        const gchar *name;

        name = g_udev_device_get_name (G_UDEV_DEVICE (iter->data));
        if (name && g_str_has_prefix (name, "cdc-wdm"))
            start_device_added (manager, G_UDEV_DEVICE (iter->data), manual_scan);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    mm_dbg ("Finished device scan...");
}
예제 #15
0
static void
getportmode_ready (MMPortSerialAt *port,
                   GAsyncResult *res,
                   HuaweiCustomInitContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_port_serial_at_command_finish (port, res, &error);
    if (error) {
        mm_dbg ("(Huawei) couldn't get port mode: '%s'",
                error->message);

        /* If any error occurred that was not ERROR or COMMAND NOT SUPPORT then
         * retry the command.
         */
        if (!g_error_matches (error,
                              MM_MOBILE_EQUIPMENT_ERROR,
                              MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN))
            goto out;

        /* Port mode not supported */
    } else {
        MMDevice *device;

        mm_dbg ("(Huawei) port mode layout retrieved");

        /* Results are cached in the parent device object */
        device = mm_port_probe_peek_device (ctx->probe);
        cache_port_mode (device, response, "PCUI:", TAG_HUAWEI_PCUI_PORT);
        cache_port_mode (device, response, "MDM:",  TAG_HUAWEI_MODEM_PORT);
        cache_port_mode (device, response, "NDIS:", TAG_HUAWEI_NDIS_PORT);
        cache_port_mode (device, response, "DIAG:", TAG_HUAWEI_DIAG_PORT);
        /* GETPORTMODE response format in newer devices... (e.g. E3372) */
        cache_port_mode (device, response, "pcui:",  TAG_HUAWEI_PCUI_PORT);
        cache_port_mode (device, response, "modem:", TAG_HUAWEI_MODEM_PORT);

        g_object_set_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED, GUINT_TO_POINTER (TRUE));

        /* Mark port as being AT already */
        mm_port_probe_set_result_at (ctx->probe, TRUE);
    }

    ctx->getportmode_done = TRUE;

out:
    if (error)
        g_error_free (error);

    huawei_custom_init_step (ctx);
}
예제 #16
0
void
mm_port_probe_set_result_at_product (MMPortProbe *self,
                                     const gchar *at_product)
{
    if (at_product) {
        mm_dbg ("(%s) product probing finished", self->priv->name);
        self->priv->product = g_utf8_casefold (at_product, -1);
        self->priv->flags |= MM_PORT_PROBE_AT_PRODUCT;
    } else {
        mm_dbg ("(%s) couldn't probe for product string", self->priv->name);
        self->priv->product = NULL;
        self->priv->flags |= MM_PORT_PROBE_AT_PRODUCT;
    }
}
예제 #17
0
void
mm_manager_start (MMManager *manager)
{
    GList *devices, *iter;

    g_return_if_fail (manager != NULL);
    g_return_if_fail (MM_IS_MANAGER (manager));

    mm_dbg ("Starting device scan...");

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "tty");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        device_added (manager, G_UDEV_DEVICE (iter->data), FALSE);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "net");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        device_added (manager, G_UDEV_DEVICE (iter->data), FALSE);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usb");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        const gchar *name;

        name = g_udev_device_get_name (G_UDEV_DEVICE (iter->data));
        if (name && g_str_has_prefix (name, "cdc-wdm"))
            device_added (manager, G_UDEV_DEVICE (iter->data), FALSE);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    /* Newer kernels report 'usbmisc' subsystem */
    devices = g_udev_client_query_by_subsystem (manager->priv->udev, "usbmisc");
    for (iter = devices; iter; iter = g_list_next (iter)) {
        const gchar *name;

        name = g_udev_device_get_name (G_UDEV_DEVICE (iter->data));
        if (name && g_str_has_prefix (name, "cdc-wdm"))
            device_added (manager, G_UDEV_DEVICE (iter->data), FALSE);
        g_object_unref (G_OBJECT (iter->data));
    }
    g_list_free (devices);

    mm_dbg ("Finished device scan...");
}
예제 #18
0
void
mm_port_probe_set_result_at_vendor (MMPortProbe *self,
                                    const gchar *at_vendor)
{
    if (at_vendor) {
        mm_dbg ("(%s) vendor probing finished", self->priv->name);
        self->priv->vendor = g_utf8_casefold (at_vendor, -1);
        self->priv->flags |= MM_PORT_PROBE_AT_VENDOR;
    } else {
        mm_dbg ("(%s) couldn't probe for vendor string", self->priv->name);
        self->priv->vendor = NULL;
        self->priv->product = NULL;
        self->priv->flags |= (MM_PORT_PROBE_AT_VENDOR | MM_PORT_PROBE_AT_PRODUCT);
    }
}
예제 #19
0
static void
find_port_support_ready_cb (MMPluginManager *plugin_manager,
                            GAsyncResult *result,
                            FindPortSupportContext *ctx)
{
    GError *error = NULL;
    MMPlugin *best_plugin;

    best_plugin = mm_plugin_manager_find_port_support_finish (plugin_manager,
                                                              result,
                                                              &error);
    if (!best_plugin) {
        MMBaseModem *existing;

        if (error) {
            mm_dbg ("(%s/%s): error checking support: '%s'",
                    g_udev_device_get_subsystem (ctx->device),
                    g_udev_device_get_name (ctx->device),
                    error->message);
            g_error_free (error);
        } else {
            mm_dbg ("(%s/%s): not supported by any plugin",
                    g_udev_device_get_subsystem (ctx->device),
                    g_udev_device_get_name (ctx->device));
        }

        /* So we couldn't get a plugin for this port, we should anyway check if
         * there is already an existing modem for the physical device, and if
         * so, check if it can already be exported. */
        existing = find_modem_for_device (
            ctx->manager,
            g_udev_device_get_sysfs_path (ctx->physical_device));
        if (existing)
            check_export_modem (ctx->manager, existing);
    } else {
        mm_dbg ("(%s/%s): found plugin '%s' giving best support",
                g_udev_device_get_subsystem (ctx->device),
                g_udev_device_get_name (ctx->device),
                mm_plugin_get_name ((MMPlugin *)best_plugin));

        grab_port (ctx->manager,
                   best_plugin,
                   ctx->device,
                   ctx->physical_device);
    }

    find_port_support_context_free (ctx);
}
예제 #20
0
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);
}
예제 #21
0
MM_PLUGIN_DEFINE_MAJOR_VERSION
MM_PLUGIN_DEFINE_MINOR_VERSION

/*****************************************************************************/

static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered SimTech modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    return MM_BASE_MODEM (mm_broadband_modem_simtech_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
}
예제 #22
0
static void
debug_log (MMPortSerial *port, const char *prefix, const char *buf, gsize len)
{
    static GString *debug = NULL;
    const char *s;

    if (!debug)
        debug = g_string_sized_new (256);

    g_string_append (debug, prefix);
    g_string_append (debug, " '");

    s = buf;
    while (len--) {
        if (g_ascii_isprint (*s))
            g_string_append_c (debug, *s);
        else if (*s == '\r')
            g_string_append (debug, "<CR>");
        else if (*s == '\n')
            g_string_append (debug, "<LF>");
        else
            g_string_append_printf (debug, "\\%u", (guint8) (*s & 0xFF));

        s++;
    }

    g_string_append_c (debug, '\'');
    mm_dbg ("(%s): %s", mm_port_get_device (MM_PORT (port)), debug->str);
    g_string_truncate (debug, 0);
}
static void
check_support_ready (MMIfaceModemMessaging *self,
                     GAsyncResult *res,
                     InitializationContext *ctx)
{
    GError *error = NULL;

    if (!MM_IFACE_MODEM_MESSAGING_GET_INTERFACE (self)->check_support_finish (self,
                                                                              res,
                                                                              &error)) {
        if (error) {
            /* This error shouldn't be treated as critical */
            mm_dbg ("Messaging support check failed: '%s'", error->message);
            g_error_free (error);
        }
    } else {
        /* Messaging is supported! */
        g_object_set_qdata (G_OBJECT (self),
                            supported_quark,
                            GUINT_TO_POINTER (TRUE));
    }

    /* Go on to next step */
    ctx->step++;
    interface_initialization_step (ctx);
}
예제 #24
0
static gboolean
serial_probe_at (MMPortProbe *self)
{
    PortProbeRunTask *task = self->priv->task;

    task->source_id = 0;

    /* If already cancelled, do nothing else */
    if (port_probe_run_is_cancelled (self))
        return FALSE;

    /* If AT probing cancelled, end this partial probing */
    if (g_cancellable_is_cancelled (task->at_probing_cancellable)) {
        mm_dbg ("(%s) no need to launch probing for AT support",
                self->priv->name);
        task->at_result_processor (self, NULL);
        serial_probe_schedule (self);
        return FALSE;
    }

    mm_at_serial_port_queue_command (
        MM_AT_SERIAL_PORT (task->serial),
        task->at_commands->command,
        task->at_commands->timeout,
        task->at_probing_cancellable,
        (MMAtSerialResponseFn)serial_probe_at_parse_response,
        self);
    return FALSE;
}
예제 #25
0
static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered Sierra modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    if (sierra_port_probe_list_is_icera (probes))
        return MM_BASE_MODEM (mm_broadband_modem_sierra_icera_new (sysfs_path,
                                                                   drivers,
                                                                   mm_plugin_get_name (self),
                                                                   vendor,
                                                                   product));

    return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
                                                         drivers,
                                                         mm_plugin_get_name (self),
                                                         vendor,
                                                         product));
}
gboolean
mm_iface_modem_messaging_take_part (MMIfaceModemMessaging *self,
                                    MMSmsPart *sms_part,
                                    MMSmsState state,
                                    MMSmsStorage storage)
{
    MMSmsList *list = NULL;
    GError *error = NULL;
    gboolean added;

    g_object_get (self,
                  MM_IFACE_MODEM_MESSAGING_SMS_LIST, &list,
                  NULL);
    if (!list)
        return FALSE;

    added = mm_sms_list_take_part (list, sms_part, state, storage, &error);
    if (!added) {
        mm_dbg ("Couldn't take part in SMS list: '%s'", error->message);
        g_error_free (error);

        /* If part wasn't taken, we need to free the part ourselves */
        mm_sms_part_free (sms_part);
    }
    g_object_unref (list);

    return added;
}
예제 #27
0
static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
    propagate_port_mode_results (probes);

#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered Huawei modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    return MM_BASE_MODEM (mm_broadband_modem_huawei_new (sysfs_path,
                                                         drivers,
                                                         mm_plugin_get_name (self),
                                                         vendor,
                                                         product));
}
static void
modem_load_signal_quality (MMIfaceModem *self,
                           GAsyncReadyCallback callback,
                           gpointer user_data)
{
    GSimpleAsyncResult *result;

    mm_dbg ("loading signal quality...");
    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_load_signal_quality);

    /* 3GPP modems can just run parent's signal quality loading */
    if (mm_iface_modem_is_3gpp (self)) {
        iface_modem_parent->load_signal_quality (
            self,
            (GAsyncReadyCallback)parent_load_signal_quality_ready,
            result);
        return;
    }

    /* CDMA modems need custom signal quality loading */
    mm_base_modem_at_command (
        MM_BASE_MODEM (self),
        "$NWRSSI",
        3,
        FALSE,
        (GAsyncReadyCallback)nwrssi_ready,
        result);
}
static void
reg_eri_6500_cb (MMPortSerialQcdm *port,
                 GAsyncResult *res,
                 DetailedRegistrationStateContext *ctx)
{
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        /* Just ignore the error and complete with the input info */
        mm_dbg ("Couldn't run QCDM MSM6500 ERI: '%s'", error->message);
        g_error_free (error);
    } else {
        QcdmResult *result;

        result = qcdm_cmd_nw_subsys_eri_result ((const gchar *) response->data, response->len, NULL);
        g_byte_array_unref (response);
        if (result) {
            parse_modem_eri (ctx, result);
            qcdm_result_unref (result);
        }
    }

    /* NOTE: always complete NOT in idle here */
    g_simple_async_result_set_op_res_gpointer (ctx->result, &ctx->state, NULL);
    detailed_registration_state_context_complete_and_free (ctx);
}
예제 #30
0
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)) {
        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 (usbif == fi_ctx->first_usbif) {
            g_warn_if_reached ();
        } else if (usbif > fi_ctx->first_usbif &&
                   usbif < closest) {
            closest = usbif;
        }
    }

    if (closest == G_MAXINT) {
        /* Retry with interface 0... */
        closest = 0;
    }

    mm_dbg ("(Huawei) Will try initial probing with interface '%d' instead", closest);

    fi_ctx->first_usbif = closest;
}