1062
1075
MMCallbackInfo *info = user_data;
1064
info->error = mm_modem_check_removed (info->modem, error);
1067
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1069
g_clear_error (&info->error);
1071
/* The modem doesn't like unsolicited CGREG, so we'll need to poll */
1072
priv->cgreg_poll = TRUE;
1074
mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
1076
/* Success; get initial state */
1077
mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
1077
/* If the modem has already been removed, return without
1078
* scheduling callback */
1079
if (mm_callback_info_check_modem_removed (info))
1083
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1085
/* The modem doesn't like unsolicited CGREG, so we'll need to poll */
1086
priv->cgreg_poll = TRUE;
1088
mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
1090
/* Success; get initial state */
1091
mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
1080
1093
initial_unsolicited_reg_check_done (info);
1089
1102
MMCallbackInfo *info = user_data;
1091
/* Ignore errors except modem removal errors */
1092
info->error = mm_modem_check_removed (info->modem, error);
1095
g_clear_error (&info->error);
1096
/* Try CGREG=1 instead */
1097
mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info);
1099
add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
1101
mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
1103
/* Success; get initial state */
1104
mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
1107
initial_unsolicited_reg_check_done (info);
1104
/* If the modem has already been removed, return without
1105
* scheduling callback */
1106
if (mm_callback_info_check_modem_removed (info))
1111
/* Try CGREG=1 instead */
1112
mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info);
1110
/* Modem got removed */
1111
mm_callback_info_schedule (info);
1114
add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
1116
mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
1118
/* Success; get initial state */
1119
mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
1122
initial_unsolicited_reg_check_done (info);
1119
1130
gpointer user_data)
1121
1132
MMCallbackInfo *info = user_data;
1123
info->error = mm_modem_check_removed (info->modem, error);
1125
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1128
g_clear_error (&info->error);
1130
/* The modem doesn't like unsolicited CREG, so we'll need to poll */
1131
priv->creg_poll = TRUE;
1133
mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
1133
MMGenericGsmPrivate *priv;
1135
/* If the modem has already been removed, return without
1136
* scheduling callback */
1137
if (mm_callback_info_check_modem_removed (info))
1140
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1143
/* The modem doesn't like unsolicited CREG, so we'll need to poll */
1144
priv->creg_poll = TRUE;
1146
mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
1148
/* Success; get initial state */
1149
mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
1151
/* Now try to set up CGREG messages */
1152
mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
1156
creg2_done (MMAtSerialPort *port,
1161
MMCallbackInfo *info = user_data;
1163
/* If the modem has already been removed, return without
1164
* scheduling callback */
1165
if (mm_callback_info_check_modem_removed (info))
1170
mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info);
1172
add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
1174
mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
1135
1176
/* Success; get initial state */
1136
1177
mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
1138
1179
/* Now try to set up CGREG messages */
1139
1180
mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
1141
/* Modem got removed */
1142
mm_callback_info_schedule (info);
1147
creg2_done (MMAtSerialPort *port,
1152
MMCallbackInfo *info = user_data;
1154
/* Ignore errors except modem removal errors */
1155
info->error = mm_modem_check_removed (info->modem, error);
1158
g_clear_error (&info->error);
1159
mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info);
1161
add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
1163
mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
1165
/* Success; get initial state */
1166
mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
1168
/* Now try to set up CGREG messages */
1169
mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
1172
/* Modem got removed */
1173
mm_callback_info_schedule (info);
1180
1187
MMGenericGsmPrivate *priv;
1182
info->error = mm_modem_check_removed (modem, error);
1185
mm_modem_set_state (modem,
1186
MM_MODEM_STATE_DISABLED,
1187
MM_MODEM_STATE_REASON_NONE);
1189
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
1191
if (priv->primary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary)))
1192
mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary));
1193
if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary)))
1194
mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary));
1189
/* If modem already removed, do nothing */
1190
if (!modem || mm_callback_info_check_modem_removed (info))
1194
info->error = g_error_copy (error);
1196
mm_modem_set_state (modem,
1197
MM_MODEM_STATE_DISABLED,
1198
MM_MODEM_STATE_REASON_NONE);
1200
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
1202
if (priv->primary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary)))
1203
mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary));
1204
if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary)))
1205
mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary));
1197
1207
mm_callback_info_schedule (info);
1615
1648
MMModemState prev_state;
1616
1649
char *cmd = NULL;
1618
info->error = mm_modem_check_removed (info->modem, error);
1621
/* Reset old state since the operation failed */
1622
prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
1623
mm_modem_set_state (MM_MODEM (info->modem),
1625
MM_MODEM_STATE_REASON_NONE);
1651
/* If the modem has already been removed, return without
1652
* scheduling callback */
1653
if (mm_callback_info_check_modem_removed (info))
1657
info->error = g_error_copy (error);
1659
/* Reset old state since the operation failed */
1660
prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
1661
mm_modem_set_state (MM_MODEM (info->modem),
1663
MM_MODEM_STATE_REASON_NONE);
1628
1665
mm_callback_info_schedule (info);
1896
get_spn_done (MMAtSerialPort *port,
1901
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
1903
gboolean success = FALSE;
1908
info->error = g_error_copy (error);
1912
memset (hex, 0, sizeof (hex));
1913
if (sscanf (response->str, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3)
1916
/* May not include quotes... */
1917
if (sscanf (response->str, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3)
1922
info->error = g_error_new_literal (MM_MODEM_ERROR,
1923
MM_MODEM_ERROR_GENERAL,
1924
"Could not parse the CRSM response");
1928
if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) {
1931
/* Make sure the buffer is only hex characters */
1932
while (buflen < sizeof (hex) && hex[buflen]) {
1933
if (!isxdigit (hex[buflen])) {
1940
/* Convert hex string to binary */
1941
bin = utils_hexstr2bin (hex, &buflen);
1943
info->error = g_error_new (MM_MODEM_ERROR,
1944
MM_MODEM_ERROR_GENERAL,
1945
"SIM returned malformed response '%s'",
1950
/* Remove the FF filler at the end */
1951
while (bin[buflen - 1] == (char)0xff)
1954
/* First byte is metadata; remainder is GSM-7 unpacked into octets; convert to UTF8 */
1955
utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 ((guint8 *)bin + 1, buflen - 1);
1957
mm_callback_info_set_result(info, utf8, g_free);
1959
info->error = g_error_new (MM_MODEM_ERROR,
1960
MM_MODEM_ERROR_GENERAL,
1961
"SIM failed to handle CRSM request (sw1 %d sw2 %d)",
1966
mm_callback_info_schedule (info);
1847
1971
get_imei (MMModemGsmCard *modem,
1848
1972
MMModemStringFn callback,
1849
1973
gpointer user_data)
2008
get_spn (MMModemGsmCard *modem,
2009
MMModemStringFn callback,
2012
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
2013
MMCallbackInfo *info;
2015
info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
2017
/* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */
2018
mm_at_serial_port_queue_command_cached (priv->primary,
2019
"+CRSM=176,28486,0,0,17",
1884
2026
get_card_info (MMModem *modem,
1885
2027
MMModemInfoFn callback,
1886
2028
gpointer user_data)
1913
2055
pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data)
1915
2057
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
2058
MMGenericGsmPrivate *priv;
1916
2059
MMSerialPort *port;
1917
2060
GError *saved_error;
2062
/* Do nothing if modem removed */
2063
if (!modem || mm_callback_info_check_modem_removed (info))
2066
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1919
2068
/* Clear the pin check timeout to ensure that it won't ever get a
1920
2069
* stale MMCallbackInfo if the modem got removed. We'll reschedule it here
1921
2070
* anyway if needed.
1924
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
1926
if (priv->pin_check_timeout)
1927
g_source_remove (priv->pin_check_timeout);
1928
priv->pin_check_timeout = 0;
1931
/* modem could have been removed before we get here, in which case
1932
* 'modem' will be NULL.
1934
info->error = mm_modem_check_removed (modem, error);
2072
if (priv->pin_check_timeout)
2073
g_source_remove (priv->pin_check_timeout);
2074
priv->pin_check_timeout = 0;
2076
/* Propagate the error to the info */
2078
info->error = g_error_copy (error);
1936
2080
/* If the modem wasn't removed, and the modem isn't ready yet, ask it for
1937
2081
* the current PIN status a few times since some devices take a bit to fully
1938
2082
* enable themselves after a SIM PIN/PUK unlock.
1942
&& !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) {
1943
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
2084
if (info->error && !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) {
1945
2085
if (priv->pin_check_tries < 4) {
1946
2086
g_clear_error (&info->error);
1947
2087
priv->pin_check_tries++;
1953
2093
/* Otherwise, clean up and return the PIN check result */
1954
2094
port = mm_callback_info_get_data (info, PIN_PORT_TAG);
1956
2096
mm_serial_port_close (port);
1958
2098
/* If we have a saved error from sending PIN/PUK, return that to callers */
1959
2099
saved_error = mm_callback_info_get_data (info, SAVED_ERROR_TAG);
1960
2100
if (saved_error) {
1961
if (info->modem && !mm_modem_base_get_unlock_required (MM_MODEM_BASE (info->modem))) {
2101
if (!mm_modem_base_get_unlock_required (MM_MODEM_BASE (info->modem))) {
1962
2102
/* Original unlock failed but the modem is actually unlocked, so
1963
2103
* return success. Sometimes happens if the modem doesn't allow
1964
2104
* CPIN="xxxx" when it's already unlocked and returns an error.
2631
2791
gpointer user_data)
2633
2793
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
2634
MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
2635
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
2795
MMGenericGsmPrivate *priv;
2637
2797
MMModemGsmNetworkRegStatus status;
2799
/* If the modem has already been removed, return without
2800
* scheduling callback */
2801
if (mm_callback_info_check_modem_removed (info))
2804
self = MM_GENERIC_GSM (info->modem);
2805
priv = MM_GENERIC_GSM_GET_PRIVATE (self);
2639
2807
/* This function should only get called during the connect sequence when
2640
2808
* polling for registration state, since explicit registration requests
2641
2809
* from D-Bus clients are filled from the cached registration state.
2703
2871
gpointer user_data)
2705
2873
MMCallbackInfo *info = user_data;
2706
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
2874
MMGenericGsmPrivate *priv;
2708
2876
mm_callback_info_unref (info);
2878
/* If the modem has already been removed, return without
2879
* scheduling callback */
2880
if (mm_callback_info_check_modem_removed (info))
2883
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
2710
2885
/* If the registration timed out (and thus pending_reg_info will be NULL)
2711
2886
* and the modem eventually got around to sending the response for the
2712
2887
* registration request then just ignore the response since the callback is
2964
3151
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
2965
3152
MMModemState prev_state;
2967
info->error = mm_modem_check_removed (modem, error);
2969
if (info->modem && modem) {
2970
/* Reset old state since the operation failed */
2971
prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
2972
mm_modem_set_state (MM_MODEM (info->modem),
2974
MM_MODEM_STATE_REASON_NONE);
3154
/* Do nothing if modem removed */
3155
if (!modem || mm_callback_info_check_modem_removed (info))
3159
info->error = g_error_copy (error);
3160
/* Reset old state since the operation failed */
3161
prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
3162
mm_modem_set_state (MM_MODEM (info->modem),
3164
MM_MODEM_STATE_REASON_NONE);
2977
3166
MMGenericGsm *self = MM_GENERIC_GSM (modem);
2978
3167
MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
3023
3219
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
3024
3220
MMGenericGsmPrivate *priv;
3026
info->error = mm_modem_check_removed (info->modem, error);
3222
/* If the modem has already been removed, return without
3223
* scheduling callback */
3224
if (mm_callback_info_check_modem_removed (info))
3028
3228
/* Ignore "NO CARRIER" response when modem disconnects and any flash
3029
3229
* failures we might encounter. Other errors are hard errors.
3031
if ( !g_error_matches (info->error, MM_MODEM_CONNECT_ERROR, MM_MODEM_CONNECT_ERROR_NO_CARRIER)
3032
&& !g_error_matches (info->error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) {
3231
if ( !g_error_matches (error, MM_MODEM_CONNECT_ERROR, MM_MODEM_CONNECT_ERROR_NO_CARRIER)
3232
&& !g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) {
3233
info->error = g_error_copy (error);
3033
3234
mm_callback_info_schedule (info);
3036
g_clear_error (&info->error);
3039
3239
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
3771
4016
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
3773
info->error = mm_modem_check_removed (info->modem, error);
4018
/* If the modem has already been removed, return without
4019
* scheduling callback */
4020
if (mm_callback_info_check_modem_removed (info))
3775
4024
gboolean tried_no_quotes = !!mm_callback_info_get_data (info, TRIED_NO_QUOTES_TAG);
3776
4025
MMModemCharset charset = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "charset"));
3779
if (!info->modem || tried_no_quotes) {
4028
if (tried_no_quotes) {
4029
info->error = g_error_copy (error);
3780
4030
mm_callback_info_schedule (info);
3931
4194
*dest++ = '\0';
3934
/* len is in septets for gsm7 and in digits (semi-octets) for others */
4197
/* len is in semi-octets */
3936
4199
sms_decode_address (const guint8 *address, int len)
4201
guint8 addrtype, addrplan;
3941
addrtype = address[0];
4204
addrtype = address[0] & SMS_NUMBER_TYPE_MASK;
4205
addrplan = address[0] & SMS_NUMBER_PLAN_MASK;
3944
if (addrtype == 0xd0) {
4208
if (addrtype == SMS_NUMBER_TYPE_ALPHA) {
3945
4209
guint8 *unpacked;
3946
4210
guint32 unpacked_len;
3947
unpacked = gsm_unpack (address + 1, len, 0, &unpacked_len);
4211
unpacked = gsm_unpack (address, (len * 4) / 7, 0, &unpacked_len);
3948
4212
utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 (unpacked,
3950
4214
g_free(unpacked);
4215
} else if (addrtype == SMS_NUMBER_TYPE_INTL &&
4216
addrplan == SMS_NUMBER_PLAN_TELEPHONE) {
4217
/* International telphone number, format as "+1234567890" */
4218
utf8 = g_malloc (len + 3); /* '+' + digits + possible trailing 0xf + NUL */
4220
sms_semi_octets_to_bcd_string (utf8 + 1, address, (len + 1) / 2);
3952
utf8 = g_malloc (len + 2); /* may need one extra for trailing 0xf */
4223
* All non-alphanumeric types and plans are just digits, but
4224
* don't apply any special formatting if we don't know the
4227
utf8 = g_malloc (len + 2); /* digits + possible trailing 0xf + NUL */
3953
4228
sms_semi_octets_to_bcd_string (utf8, address, (len + 1) / 2);
4483
4773
/* encode to cur_charset */
4484
g_warn_if_fail (mm_modem_charset_byte_array_append (ussd_command, command, FALSE, priv->cur_charset));
4774
success = mm_modem_charset_byte_array_append (ussd_command, command, FALSE, priv->cur_charset);
4775
g_warn_if_fail (success == TRUE);
4485
4777
/* convert to hex representation */
4486
4778
hex = utils_bin2hexstr (ussd_command->data, ussd_command->len);
4487
4779
g_byte_array_free (ussd_command, TRUE);