예제 #1
0
static void
connection_enabled (MMAtSerialPort *port,
                    GMatchInfo *match_info,
                    gpointer user_data)
{
    MMModemIcera *self = MM_MODEM_ICERA (user_data);
    MMAtSerialPort *primary;
    char *str;
    int status, cid, tmp;

    cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (self));
    if (cid < 0)
        return;

    str = g_match_info_fetch (match_info, 1);
    g_return_if_fail (str != NULL);
    tmp = atoi (str);
    g_free (str);

    /* Make sure the unsolicited message's CID matches the current CID */
    if (tmp != cid)
        return;

    str = g_match_info_fetch (match_info, 2);
    g_return_if_fail (str != NULL);
    status = atoi (str);
    g_free (str);

    switch (status) {
    case 0:
        /* Disconnected */
        if (mm_modem_get_state (MM_MODEM (self)) >= MM_MODEM_STATE_CONNECTED)
            mm_modem_disconnect (MM_MODEM (self), icera_disconnect_done, NULL);
        break;
    case 1:
        /* Connected */
        connect_pending_done (self);
        break;
    case 2:
        /* Connecting */
        break;
    case 3:
        /* Call setup failure? */
        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,
                                         query_network_error_code_done, self);
        break;
    default:
        mm_warn ("Unknown Icera connect status %d", status);
        break;
    }
}
예제 #2
0
static void
unsolicited_disable_done (MMModem *modem,
                          GError *error,
                          gpointer user_data)
{
    MMCallbackInfo *info = user_data;

    /* Handle modem removal, but ignore other errors */
    if (g_error_matches (error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED))
        info->error = g_error_copy (error);
    else if (!modem) {
        info->error =  g_error_new_literal (MM_MODEM_ERROR,
                                            MM_MODEM_ERROR_REMOVED,
                                            "The modem was removed.");
    }

    if (info->error) {
        mm_callback_info_schedule (info);
        return;
    }

    /* Otherwise, kill any existing connection */
    if (mm_generic_gsm_get_cid (MM_GENERIC_GSM (modem)) >= 0)
        hso_call_control (MM_MODEM_HSO (modem), FALSE, TRUE, disable_done, info);
    else
        disable_done (modem, NULL, info);
}
예제 #3
0
static void
nwstate_changed (MMAtSerialPort *port,
                 GMatchInfo *info,
                 gpointer user_data)
{
    MMModemIcera *self = MM_MODEM_ICERA (user_data);
    MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
    char *str;
    int rssi = -1;

    str = g_match_info_fetch (info, 1);
    if (str) {
        rssi = atoi (str);
        rssi = CLAMP (rssi, -1, 5);
        g_free (str);
    }

    /* Check the <connection state> field first for the connected access
     * technology, otherwise if not connected (ie, "-") use the available
     * access technology from the <tech> field.
     */
    str = g_match_info_fetch (info, 4);
    if (!str || (strcmp (str, "-") == 0)) {
        g_free (str);
        str = g_match_info_fetch (info, 3);
    }
    if (str) {
        act = nwstate_to_act (str);
        g_free (str);
    }

    MM_MODEM_ICERA_GET_PRIVATE (self)->last_act = act;
    mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (self), act);
}
예제 #4
0
static void
icera_connected (MMAtSerialPort *port,
                 GString *response,
                 GError *error,
                 gpointer user_data)
{
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;

    /* If the modem has already been removed, return without
     * scheduling callback */
    if (mm_callback_info_check_modem_removed (info))
        return;

    if (error) {
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info);
    } else {
        MMModemIcera *self = MM_MODEM_ICERA (info->modem);
        MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self);

        g_warn_if_fail (priv->connect_pending_id == 0);
        if (priv->connect_pending_id)
            g_source_remove (priv->connect_pending_id);

        priv->connect_pending_data = info;
        priv->connect_pending_id = g_timeout_add_seconds (30, icera_connect_timed_out, self);
    }
}
예제 #5
0
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)) {
        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;
}
예제 #6
0
static void
_internal_hso_modem_authenticate (MMModemHso *self, MMCallbackInfo *info)
{
    MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (self);
    MMAtSerialPort *primary;
    gint cid;
    char *command;

    primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_PORT_TYPE_PRIMARY);
    g_assert (primary);

    cid = hso_get_cid (self);
    g_warn_if_fail (cid >= 0);

    /* Both user and password are required; otherwise firmware returns an error */
    if (!priv->username || !priv->password)
		command = g_strdup_printf ("%s=%d,0", auth_commands[priv->auth_idx], cid);
    else {
        command = g_strdup_printf ("%s=%d,1,\"%s\",\"%s\"",
                                   auth_commands[priv->auth_idx],
                                   cid,
                                   priv->password ? priv->password : "",
                                   priv->username ? priv->username : "");

    }

    mm_at_serial_port_queue_command (primary, command, 3, auth_done, info);
    g_free (command);
}
예제 #7
0
void
mm_modem_icera_change_unsolicited_messages (MMModemIcera *self, gboolean enabled)
{
    MMAtSerialPort *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);
}
예제 #8
0
static void
disable (MMModem *modem,
         MMModemFn callback,
         gpointer user_data)
{
    MMModemHso *self = MM_MODEM_HSO (modem);
    MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (self);
    MMCallbackInfo *info;

    mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));

    g_free (priv->username);
    priv->username = NULL;
    g_free (priv->password);
    priv->password = NULL;

    info = mm_callback_info_new (modem, callback, user_data);

    /* Turn off unsolicited messages so they don't pile up in the modem */
    option_change_unsolicited_messages (MM_GENERIC_GSM (modem), FALSE, unsolicited_disable_done, info);
}
예제 #9
0
static gint
_get_cid (MMModemIcera *self)
{
    gint cid;

    cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (self));
    if (cid < 0) {
        g_warn_if_fail (cid >= 0);
        cid = 0;
    }
    return cid;
}
예제 #10
0
void
mm_modem_icera_get_local_timestamp (MMModemIcera *self,
                                    MMModemIceraTimestampFn callback,
                                    gpointer user_data)
{
    MMCallbackInfo *info;
    MMAtSerialPort *primary;

    info = mm_callback_info_icera_timestamp_new (self, callback, user_data);

    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);
}
예제 #11
0
static void
icera_call_control (MMModemIcera *self,
                    gboolean activate,
                    MMAtSerialResponseFn callback,
                    gpointer user_data)
{
    char *command;
    MMAtSerialPort *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);
    mm_at_serial_port_queue_command (primary, command, 3, callback, user_data);
    g_free (command);
}
예제 #12
0
static void
get_ip4_config (MMModem *modem,
                MMModemIp4Fn callback,
                gpointer user_data)
{
    MMCallbackInfo *info;
    char *command;
    MMAtSerialPort *primary;

    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);
    g_assert (primary);
    mm_at_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info);
    g_free (command);
}
예제 #13
0
static void
old_context_clear_done (MMModem *modem,
                        GError *error,
                        gpointer user_data)
{
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
    GError *tmp_error;

    tmp_error = mm_modem_check_removed (modem, error);
    if (tmp_error) {
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info);
        g_clear_error (&tmp_error);
    } else {
        /* Success, activate the PDP context and start the data session */
        hso_call_control (MM_MODEM_HSO (modem), TRUE, FALSE, hso_enabled, info);
    }
}
예제 #14
0
static void
connect_auth_done (MMModem *modem,
                   GError *error,
                   gpointer user_data)
{
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
    GError *tmp_error;

    tmp_error = mm_modem_check_removed (modem, error);
    if (tmp_error) {
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info);
        g_clear_error (&tmp_error);
    } else {
        /* Now connect; kill any existing connections first */
        hso_call_control (MM_MODEM_HSO (modem), FALSE, TRUE, old_context_clear_done, info);
    }
}
예제 #15
0
void
mm_modem_icera_get_allowed_mode (MMModemIcera *self,
                                 MMModemUIntFn callback,
                                 gpointer user_data)
{
    MMCallbackInfo *info;
    MMAtSerialPort *port;

    info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data);

    port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (self), &info->error);
    if (!port) {
        mm_callback_info_schedule (info);
        return;
    }
    mm_at_serial_port_queue_command (port, "%IPSYS?", 3, get_allowed_mode_done, info);
}
예제 #16
0
static void
hso_enabled (MMModem *modem,
             GError *error,
             gpointer user_data)
{
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
    GError *tmp_error;

    tmp_error = mm_modem_check_removed (modem, error);
    if (tmp_error) {
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (modem), tmp_error, info);
        g_clear_error (&tmp_error);
    } else {
        MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (modem);

        priv->connect_pending_data = info;
        priv->connect_pending_id = g_timeout_add_seconds (30, hso_connect_timed_out, modem);
    }
}
예제 #17
0
void
mm_modem_icera_set_allowed_mode (MMModemIcera *self,
                                 MMModemGsmAllowedMode mode,
                                 MMModemFn callback,
                                 gpointer user_data)
{
    MMCallbackInfo *info;
    MMAtSerialPort *port;
    char *command;
    int i;

    info = mm_callback_info_new (MM_MODEM (self), callback, user_data);

    port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (self), &info->error);
    if (!port) {
        mm_callback_info_schedule (info);
        return;
    }

    switch (mode) {
    case MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY:
        i = 0;
        break;
    case MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY:
        i = 1;
        break;
    case MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED:
        i = 2;
        break;
    case MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED:
        i = 3;
        break;
    case MM_MODEM_GSM_ALLOWED_MODE_ANY:
    default:
        i = 5;
        break;
    }

    command = g_strdup_printf ("%%IPSYS=%d", i);
    mm_at_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info);
    g_free (command);
}
예제 #18
0
static void
auth_done (MMAtSerialPort *port,
           GString *response,
           GError *error,
           gpointer user_data)
{
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;

    /* If the modem has already been removed, return without
     * scheduling callback */
    if (mm_callback_info_check_modem_removed (info))
        return;

    if (error)
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), error, info);
    else {
        /* Ensure the PDP context is deactivated */
        icera_call_control (MM_MODEM_ICERA (info->modem), FALSE, old_context_clear_done, info);
    }
}
예제 #19
0
static void
hso_call_control (MMModemHso *self,
                  gboolean activate,
                  gboolean ignore_errors,
                  MMModemFn callback,
                  gpointer user_data)
{
    MMCallbackInfo *info;
    char *command;
    MMAtSerialPort *primary;

    info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
    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);
    g_assert (primary);
    mm_at_serial_port_queue_command (primary, command, 3, hso_call_control_done, info);
    g_free (command);
}
예제 #20
0
void
mm_modem_icera_get_ip4_config (MMModemIcera *self,
                               MMModemIp4Fn callback,
                               gpointer user_data)
{
    MMCallbackInfo *info;
    char *command;
    MMAtSerialPort *primary;

    info = mm_callback_info_new_full (MM_MODEM (self),
                                      ip4_config_invoke,
                                      G_CALLBACK (callback),
                                      user_data);

    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));
    mm_at_serial_port_queue_command (primary, command, 3, get_ip4_config_done, info);
    g_free (command);
}
예제 #21
0
static void
connect_pending_done (MMModemIcera *self)
{
    MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self);
    GError *error = NULL;

    if (priv->connect_pending_data) {
        if (priv->connect_pending_data->error) {
            error = priv->connect_pending_data->error;
            priv->connect_pending_data->error = NULL;
        }

        /* Complete the connect */
        mm_generic_gsm_connect_complete (MM_GENERIC_GSM (self), error, priv->connect_pending_data);
        priv->connect_pending_data = NULL;
    }

    if (priv->connect_pending_id) {
        g_source_remove (priv->connect_pending_id);
        priv->connect_pending_id = 0;
    }
}
예제 #22
0
void
mm_modem_icera_do_connect (MMModemIcera *self,
                           const char *number,
                           MMModemFn callback,
                           gpointer user_data)
{
    MMModem *modem = MM_MODEM (self);
    MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self);
    MMCallbackInfo *info;
    MMAtSerialPort *primary;
    gint cid;
    char *command;

    mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE);

    info = mm_callback_info_new (modem, callback, user_data);

    primary = mm_generic_gsm_get_at_port (MM_GENERIC_GSM (self), MM_AT_PORT_FLAG_PRIMARY);
    g_assert (primary);

    cid = _get_cid (self);


    /* Both user and password are required; otherwise firmware returns an error */
    if (!priv->username || !priv->password)
		command = g_strdup_printf ("%%IPDPCFG=%d,0,0,\"\",\"\"", cid);
    else {
        command = g_strdup_printf ("%%IPDPCFG=%d,0,1,\"%s\",\"%s\"",
                                   cid,
                                   priv->username ? priv->username : "",
                                   priv->password ? priv->password : "");

    }

    mm_at_serial_port_queue_command (primary, command, 3, auth_done, info);
    g_free (command);
}
예제 #23
0
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;

    if (MM_IS_AT_SERIAL_PORT (port)) {
        g_object_set (G_OBJECT (port), MM_SERIAL_PORT_SEND_DELAY, (guint64) 10000, 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);
        }
        option_register_unsolicted_handlers (gsm, MM_AT_SERIAL_PORT (port));
    }

out:
    if (device)
        g_object_unref (device);
    g_object_unref (client);
    return !!port;
}