~ubuntu-branches/ubuntu/vivid/modemmanager/vivid-proposed

« back to all changes in this revision

Viewing changes to src/mm-generic-cdma.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2011-08-07 01:47:27 UTC
  • mfrom: (16.1.3 oneiric)
  • Revision ID: james.westby@ubuntu.com-20110807014727-ssze4jx65jrjltg9
Tags: 0.5-1
debian/rules: override dh_autoreconf in a nicer way so we don't have to
clean up manually afterwards.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
#define MM_GENERIC_CDMA_PREV_STATE_TAG "prev-state"
36
36
 
 
37
typedef enum {
 
38
    RM_PROTO_ASYNC = 0,
 
39
    RM_PROTO_RELAY = 1,
 
40
    RM_PROTO_NETWORK_PPP = 2,
 
41
    RM_PROTO_NETWORK_SLIP = 3,
 
42
    RM_PROTO_STU_III = 4
 
43
} RmProtocol;
 
44
 
 
45
 
37
46
static void simple_reg_callback (MMModemCdma *modem,
38
47
                                 MMModemCdmaRegistrationState cdma_1x_reg_state,
39
48
                                 MMModemCdmaRegistrationState evdo_reg_state,
67
76
    gboolean has_spservice;
68
77
    gboolean has_speri;
69
78
 
 
79
    /* Original and current Rm interface protocol */
 
80
    RmProtocol orig_crm;
 
81
    RmProtocol cur_crm;
 
82
 
70
83
    guint poll_id;
71
84
 
72
85
    char *meid;
563
576
}
564
577
 
565
578
static void
 
579
crm_done (MMAtSerialPort *port,
 
580
          GString *response,
 
581
          GError *error,
 
582
          gpointer user_data)
 
583
{
 
584
    const char *p;
 
585
    unsigned long num;
 
586
 
 
587
    if (error)
 
588
        return;
 
589
 
 
590
    p = mm_strip_tag (response->str, "+CRM:");
 
591
    if (p) {
 
592
        errno = 0;
 
593
        num = strtoul (p, NULL, 10);
 
594
        if (num >= 0 && num <= 4 && (errno == 0)) {
 
595
            MM_GENERIC_CDMA_GET_PRIVATE (user_data)->orig_crm = (guint32) num;
 
596
            MM_GENERIC_CDMA_GET_PRIVATE (user_data)->cur_crm = (guint32) num;
 
597
        }
 
598
    }
 
599
}
 
600
 
 
601
static void
566
602
enable_all_done (MMModem *modem, GError *error, gpointer user_data)
567
603
{
568
604
    MMCallbackInfo *info = user_data;
599
635
        /* Check for support of Sprint-specific phone commands */
600
636
        mm_at_serial_port_queue_command (priv->primary, "+SPSERVICE?", 3, spservice_done, self);
601
637
        mm_at_serial_port_queue_command (priv->primary, "$SPERI?", 3, speri_done, self);
 
638
 
 
639
        /* Grab default CRM */
 
640
        mm_at_serial_port_queue_command (priv->primary, "+CRM?", 3, crm_done, self);
602
641
    }
603
642
 
604
643
out:
1661
1700
        /* Try Sprint-specific commands */
1662
1701
        mm_at_serial_port_queue_command (port, "+SPSERVICE?", 3, reg_query_spservice_done, info);
1663
1702
    } else {
1664
 
        /* Assume we're registered on the 1x network if we passed +CAD, +CSS,
1665
 
         * and QCDM Call Manager checking.
1666
 
         */
1667
 
        mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED);
1668
 
        mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
 
1703
        /* Assume we're at least registered on the 1x network if we passed
 
1704
         * +CAD, +CSS, and QCDM Call Manager checking.  But don't override a
 
1705
         * more specific registration state passed from a caller.
 
1706
         */
 
1707
        if (cur_cdma_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
 
1708
            mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED);
 
1709
 
 
1710
        /* Don't touch EVDO state; it's already either UNKNOWN, or been set
 
1711
         * by generic checking earlier.
 
1712
         */
 
1713
 
1669
1714
        mm_callback_info_schedule (info);
1670
1715
    }
1671
1716
}
1960
2005
}
1961
2006
 
1962
2007
/*****************************************************************************/
 
2008
 
 
2009
static void
 
2010
set_rm_proto_done (MMAtSerialPort *port,
 
2011
                   GString *response,
 
2012
                   GError *error,
 
2013
                   gpointer user_data)
 
2014
{
 
2015
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
 
2016
 
 
2017
    if (mm_callback_info_check_modem_removed (info) == FALSE) {
 
2018
        if (error)
 
2019
            info->error = g_error_copy (error);
 
2020
 
 
2021
        mm_callback_info_schedule (info);
 
2022
    }
 
2023
}
 
2024
 
 
2025
static void
 
2026
mm_generic_cdma_set_rm_protocol (MMGenericCdma *self,
 
2027
                                 RmProtocol proto,
 
2028
                                 MMModemFn callback,
 
2029
                                 gpointer user_data)
 
2030
{
 
2031
    MMCallbackInfo *info;
 
2032
    MMAtSerialPort *port;
 
2033
    char *cmd;
 
2034
 
 
2035
    info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
 
2036
 
 
2037
    port = mm_generic_cdma_get_best_at_port (self, &info->error);
 
2038
    if (!port) {
 
2039
        mm_callback_info_schedule (info);
 
2040
        return;
 
2041
    }
 
2042
    g_clear_error (&info->error);
 
2043
 
 
2044
    if (proto < RM_PROTO_ASYNC || proto > RM_PROTO_STU_III) {
 
2045
        g_set_error (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
 
2046
                     "Invalid Rm interface protocol %d",
 
2047
                     proto);
 
2048
        mm_callback_info_schedule (info);
 
2049
        return;
 
2050
    }
 
2051
 
 
2052
    cmd = g_strdup_printf ("+CRM=%d", proto);
 
2053
    mm_at_serial_port_queue_command (port, cmd, 3, set_rm_proto_done, info);
 
2054
    g_free (cmd);
 
2055
}
 
2056
 
 
2057
/*****************************************************************************/
1963
2058
/* MMModemSimple interface */
1964
2059
 
1965
2060
typedef enum {
1966
2061
    SIMPLE_STATE_BEGIN = 0,
1967
2062
    SIMPLE_STATE_ENABLE,
1968
2063
    SIMPLE_STATE_REGISTER,
 
2064
    SIMPLE_STATE_PRE_CONNECT,
1969
2065
    SIMPLE_STATE_CONNECT,
1970
2066
    SIMPLE_STATE_DONE
1971
2067
} SimpleState;
1991
2087
}
1992
2088
 
1993
2089
static gboolean
 
2090
simple_get_uint_property (MMCallbackInfo *info,
 
2091
                          const char *name,
 
2092
                          guint32 *out_val,
 
2093
                          GError **error)
 
2094
{
 
2095
    GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties");
 
2096
    GValue *value;
 
2097
 
 
2098
    g_return_val_if_fail (out_val != NULL, FALSE);
 
2099
 
 
2100
    value = (GValue *) g_hash_table_lookup (properties, name);
 
2101
    if (value) {
 
2102
        if (G_VALUE_HOLDS_UINT (value)) {
 
2103
            *out_val = g_value_get_uint (value);
 
2104
            return TRUE;
 
2105
        }
 
2106
 
 
2107
        g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
 
2108
                     "Invalid property type for '%s': %s (uint expected)",
 
2109
                     name, G_VALUE_TYPE_NAME (value));
 
2110
    }
 
2111
 
 
2112
    return FALSE;
 
2113
}
 
2114
 
 
2115
static gboolean
1994
2116
simple_reg_retry (gpointer user_data)
1995
2117
{
1996
2118
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
2083
2205
simple_state_machine (MMModem *modem, GError *error, gpointer user_data)
2084
2206
{
2085
2207
    MMCallbackInfo *info = (MMCallbackInfo *) user_data;
2086
 
    MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
 
2208
    MMGenericCdma *self;
 
2209
    MMGenericCdmaPrivate *priv;
2087
2210
    SimpleState state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "simple-connect-state"));
2088
2211
    const char *str;
2089
 
    guint id;
 
2212
    guint id, rm_protocol = 0;
2090
2213
 
2091
2214
    /* Do nothing if modem removed */
2092
2215
    if (!modem || mm_callback_info_check_modem_removed (info))
2097
2220
        goto out;
2098
2221
    }
2099
2222
 
 
2223
    self = MM_GENERIC_CDMA (info->modem);
 
2224
    priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
 
2225
 
2100
2226
    switch (state) {
2101
2227
    case SIMPLE_STATE_BEGIN:
 
2228
        /* Enable state */
2102
2229
        state = set_simple_state (info, SIMPLE_STATE_ENABLE);
2103
2230
        mm_modem_enable (modem, simple_state_machine, info);
2104
2231
        break;
2105
2232
    case SIMPLE_STATE_ENABLE:
 
2233
        /* Register state */
2106
2234
        state = set_simple_state (info, SIMPLE_STATE_REGISTER);
2107
2235
        mm_modem_cdma_get_registration_state (MM_MODEM_CDMA (modem),
2108
2236
                                              simple_reg_callback,
2114
2242
        priv->reg_state_changed_id = id;
2115
2243
        break;
2116
2244
    case SIMPLE_STATE_REGISTER:
 
2245
        /* Pre Connect state */
2117
2246
        registration_cleanup (MM_GENERIC_CDMA (modem), 0, 0);
 
2247
        state = set_simple_state (info, SIMPLE_STATE_PRE_CONNECT);
 
2248
        mm_modem_set_state (modem, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE);
 
2249
 
 
2250
        /* Change the Rm interface protocol due to manager request if needed */
 
2251
        if (simple_get_uint_property (info, "rm-protocol", &rm_protocol, &info->error)) {
 
2252
            mm_generic_cdma_set_rm_protocol (self, rm_protocol, simple_state_machine, info);
 
2253
            break;
 
2254
        }
 
2255
 
 
2256
        /* Or if the Rm protocol isn't the default, and there was no request
 
2257
         * to change it, do that now.
 
2258
         */
 
2259
        if (priv->cur_crm != priv->orig_crm) {
 
2260
            mm_generic_cdma_set_rm_protocol (self, priv->orig_crm, simple_state_machine, info);
 
2261
            break;
 
2262
        }
 
2263
 
 
2264
        /* Fall through */
 
2265
    case SIMPLE_STATE_PRE_CONNECT:
 
2266
        /* Connect state */
2118
2267
        state = set_simple_state (info, SIMPLE_STATE_CONNECT);
2119
 
        mm_modem_set_state (modem, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE);
2120
 
 
2121
2268
        str = simple_get_string_property (info, "number", &info->error);
2122
2269
        mm_modem_connect (modem, str, simple_state_machine, info);
2123
2270
        break;
2124
2271
    case SIMPLE_STATE_CONNECT:
 
2272
        /* All done! */
2125
2273
        state = set_simple_state (info, SIMPLE_STATE_DONE);
2126
2274
        break;
2127
2275
    case SIMPLE_STATE_DONE:
2306
2454
static void
2307
2455
mm_generic_cdma_init (MMGenericCdma *self)
2308
2456
{
 
2457
    MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
 
2458
 
2309
2459
    g_signal_connect (self, "notify::" MM_MODEM_VALID,
2310
2460
                      G_CALLBACK (modem_valid_changed), NULL);
2311
2461
    g_signal_connect (self, "notify::" MM_MODEM_STATE,
2312
2462
                      G_CALLBACK (modem_state_changed), NULL);
 
2463
 
 
2464
    /* Default to Network Layer Rm interface/PPP */
 
2465
    priv->orig_crm = priv->cur_crm = RM_PROTO_NETWORK_PPP;
2313
2466
}
2314
2467
 
2315
2468
static void