static void query_registration_state (MMGenericCdma *cdma, MMModemCdmaRegistrationState cur_cdma_state, MMModemCdmaRegistrationState cur_evdo_state, MMModemCdmaRegistrationStateFn callback, gpointer user_data) { MMCallbackInfo *info; MMQcdmSerialPort *port; GByteArray *nwsnap; info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, cur_cdma_state, cur_evdo_state, callback, user_data); port = mm_generic_cdma_get_best_qcdm_port (cdma, &info->error); if (!port) { mm_callback_info_schedule (info); return; } /* Try MSM6800 first since newer cards use that */ nwsnap = g_byte_array_sized_new (25); nwsnap->len = qcdm_cmd_nw_subsys_modem_snapshot_cdma_new ((char *) nwsnap->data, 25, QCDM_NW_CHIPSET_6800); g_assert (nwsnap->len); mm_qcdm_serial_port_queue_command (port, nwsnap, 3, reg_nwsnap_6800_cb, info); }
static void get_nwstate_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) info->error = g_error_copy (error); else { MMModemIcera *self = MM_MODEM_ICERA (info->modem); MMModemIceraPrivate *priv = MM_MODEM_ICERA_GET_PRIVATE (self); /* The unsolicited message handler will already have run and * removed the NWSTATE response, so we have to work around that. */ mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->last_act), NULL); priv->last_act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; } mm_callback_info_schedule (info); }
static void get_act_request_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN; const char *p; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) info->error = g_error_copy (error); else { p = mm_strip_tag (response->str, "+PSRAT:"); act = mm_gsm_string_to_access_tech (p); } mm_callback_info_set_result (info, GUINT_TO_POINTER (act), NULL); mm_callback_info_schedule (info); }
static void reg_nwsnap_6800_cb (MMQcdmSerialPort *port, GByteArray *response, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; QcdmResult *result; GByteArray *nwsnap; if (error) goto done; /* Parse the response */ result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const char *) response->data, response->len, NULL); if (!result) { /* Try for MSM6500 */ nwsnap = g_byte_array_sized_new (25); nwsnap->len = qcdm_cmd_nw_subsys_modem_snapshot_cdma_new ((char *) nwsnap->data, 25, QCDM_NW_CHIPSET_6500); g_assert (nwsnap->len); mm_qcdm_serial_port_queue_command (port, nwsnap, 3, reg_nwsnap_6500_cb, info); return; } parse_modem_snapshot (info, result); qcdm_result_unref (result); done: mm_callback_info_schedule (info); }
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); }
static void disconnect_owancall_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { mm_callback_info_schedule ((MMCallbackInfo *) user_data); }
static void parent_disable_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; if (error) info->error = g_error_copy (error); mm_callback_info_schedule (info); }
static void get_ip4_config_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; char **items, **iter; GArray *dns_array; int i; guint32 tmp; gint cid; if (error) { info->error = g_error_copy (error); goto out; } else if (!g_str_has_prefix (response->str, OWANDATA_TAG)) { info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Retrieving failed: invalid response."); goto out; } cid = hso_get_cid (MM_MODEM_HSO (info->modem)); dns_array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 2); items = g_strsplit (response->str + strlen (OWANDATA_TAG), ", ", 0); for (iter = items, i = 0; *iter; iter++, i++) { if (i == 0) { /* CID */ long int num; errno = 0; num = strtol (*iter, NULL, 10); if (errno != 0 || num < 0 || (gint) num != cid) { info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Unknown CID in OWANDATA response (" "got %d, expected %d)", (guint) num, cid); break; } } else if (i == 1) { /* IP address */ if (inet_pton (AF_INET, *iter, &tmp) > 0) mm_callback_info_set_data (info, "ip4-address", GUINT_TO_POINTER (tmp), NULL); } else if (i == 3) { /* DNS 1 */ if (inet_pton (AF_INET, *iter, &tmp) > 0) g_array_append_val (dns_array, tmp); } else if (i == 4) { /* DNS 2 */ if (inet_pton (AF_INET, *iter, &tmp) > 0) g_array_append_val (dns_array, tmp); } } g_strfreev (items); mm_callback_info_set_data (info, "ip4-dns", dns_array, free_dns_array); out: mm_callback_info_schedule (info); }
static void uint_call_not_supported (MMModemGsmCard *self, MMModemUIntFn callback, gpointer user_data) { MMCallbackInfo *info; info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data); info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED, "Operation not supported"); mm_callback_info_schedule (info); }
static void hso_call_control_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; if (error && !mm_callback_info_get_data (info, IGNORE_ERRORS_TAG)) info->error = g_error_copy (error); mm_callback_info_schedule (info); }
static void get_rssi_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemCdma *parent_iface; int qual; info->error = mm_modem_check_removed (info->modem, error); if (info->error) { if (info->modem) { /* Fallback to parent's method */ g_clear_error (&info->error); parent_iface = g_type_interface_peek_parent (MM_MODEM_CDMA_GET_INTERFACE (info->modem)); parent_iface->get_signal_quality (MM_MODEM_CDMA (info->modem), parent_csq_done, info); } else mm_callback_info_schedule (info); return; } /* Parse the signal quality */ qual = get_one_qual (response->str, "RX0="); if (qual < 0) qual = get_one_qual (response->str, "RX1="); if (qual >= 0) { mm_callback_info_set_result (info, GUINT_TO_POINTER ((guint32) qual), NULL); mm_generic_cdma_update_cdma1x_quality (MM_GENERIC_CDMA (info->modem), (guint32) qual); } else { info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "%s", "Could not parse signal quality results"); } mm_callback_info_schedule (info); }
static void get_allowed_mode_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; gboolean parsed = FALSE; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) info->error = g_error_copy (error); else if (!g_str_has_prefix (response->str, "%IPSYS: ")) { int a, b; if (sscanf (response->str + 8, "%d,%d", &a, &b)) { MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; switch (a) { case 0: mode = MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY; break; case 1: mode = MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY; break; case 2: mode = MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED; break; case 3: mode = MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED; break; default: break; } mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); parsed = TRUE; } } if (!error && !parsed) info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Could not parse allowed mode results"); mm_callback_info_schedule (info); }
static void parent_csq_done (MMModem *modem, guint32 result, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; if (error) info->error = g_error_copy (error); else mm_callback_info_set_result (info, GUINT_TO_POINTER (result), NULL); mm_callback_info_schedule (info); }
static void get_allowed_mode_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; const char *p; MMModemGsmAllowedMode mode = MM_MODEM_GSM_ALLOWED_MODE_ANY; gint mododr = -1; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) { info->error = g_error_copy (error); goto done; } p = mm_strip_tag (response->str, "+MODODR:"); if (!p) { info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Failed to parse the allowed mode response"); goto done; } mododr = atoi (p); switch (mododr) { case 1: mode = MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY; break; case 2: case 4: mode = MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED; break; case 3: mode = MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY; break; default: break; } mm_callback_info_set_result (info, GUINT_TO_POINTER (mode), NULL); done: mm_callback_info_schedule (info); }
static void disconnect_ipdpact_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; mm_callback_info_schedule (info); }
static void get_local_timestamp_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemIceraTimestamp *timestamp; char sign; int offset; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) { info->error = g_error_copy (error); goto out; } timestamp = g_malloc0 (sizeof (MMModemIceraTimestamp)); if (g_str_has_prefix (response->str, "*TLTS: ") && sscanf (response->str + 7, "\"%02d/%02d/%02d,%02d:%02d:%02d%c%02d\"", ×tamp->year, ×tamp->month, ×tamp->day, ×tamp->hour, ×tamp->minute, ×tamp->second, &sign, &offset) == 8) { if (sign == '-') timestamp->tz_offset = -offset; else timestamp->tz_offset = offset; mm_callback_info_set_result (info, timestamp, g_free); } else { mm_warn ("Unknown *TLTS response: %s", response->str); mm_callback_info_set_result (info, NULL, g_free); g_free (timestamp); } out: mm_callback_info_schedule (info); }
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); }
static void reg_nwsnap_6500_cb (MMQcdmSerialPort *port, GByteArray *response, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; QcdmResult *result; if (!error) { result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const char *) response->data, response->len, NULL); if (result) { parse_modem_snapshot (info, result); qcdm_result_unref (result); } } mm_callback_info_schedule (info); }
static void set_allowed_mode_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) info->error = g_error_copy (error); mm_callback_info_schedule (info); }
static void get_access_technology (MMGenericGsm *modem, MMModemUIntFn callback, gpointer user_data) { MMAtSerialPort *port; MMCallbackInfo *info; info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); port = mm_generic_gsm_get_best_at_port (modem, &info->error); if (!port) { mm_callback_info_schedule (info); return; } mm_at_serial_port_queue_command (port, "+PSRAT", 3, get_act_request_done, info); }
static void get_allowed_mode (MMGenericGsm *gsm, MMModemUIntFn callback, gpointer user_data) { MMCallbackInfo *info; MMAtSerialPort *port; info = mm_callback_info_uint_new (MM_MODEM (gsm), callback, user_data); port = mm_generic_gsm_get_best_at_port (gsm, &info->error); if (!port) { mm_callback_info_schedule (info); return; } mm_at_serial_port_queue_command (port, "AT+MODODR?", 3, get_allowed_mode_done, info); }
static void is_icera_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) info->error = g_error_copy (error); else mm_callback_info_set_result (info, GUINT_TO_POINTER (TRUE), NULL); mm_callback_info_schedule (info); }
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); }
static void query_registration_state (MMGenericCdma *cdma, MMModemCdmaRegistrationState cur_cdma_state, MMModemCdmaRegistrationState cur_evdo_state, MMModemCdmaRegistrationStateFn callback, gpointer user_data) { MMCallbackInfo *info; MMAtSerialPort *port; info = mm_generic_cdma_query_reg_state_callback_info_new (cdma, cur_cdma_state, cur_evdo_state, callback, user_data); port = mm_generic_cdma_get_best_at_port (cdma, &info->error); if (!port) { mm_callback_info_schedule (info); return; } mm_at_serial_port_queue_command (port, "^SYSINFO", 3, sysinfo_done, info); }
static void set_allowed_mode (MMGenericGsm *gsm, MMModemGsmAllowedMode mode, MMModemFn callback, gpointer user_data) { MMCallbackInfo *info; MMAtSerialPort *port; char *command; int mododr = 0; info = mm_callback_info_new (MM_MODEM (gsm), callback, user_data); port = mm_generic_gsm_get_best_at_port (gsm, &info->error); if (!port) { mm_callback_info_schedule (info); return; } switch (mode) { case MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY: mododr = 3; break; case MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY: mododr = 1; break; case MM_MODEM_GSM_ALLOWED_MODE_ANY: case MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED: case MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED: default: mododr = 2; break; } command = g_strdup_printf ("+MODODR=%d", mododr); mm_at_serial_port_queue_command (port, command, 3, set_allowed_mode_done, info); g_free (command); }
static void auth_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; MMModemHso *self = MM_MODEM_HSO (info->modem); MMModemHsoPrivate *priv = MM_MODEM_HSO_GET_PRIVATE (self); if (error) { priv->auth_idx++; if (auth_commands[priv->auth_idx]) { /* Try the next auth command */ _internal_hso_modem_authenticate (self, info); return; } else info->error = g_error_copy (error); } /* Reset to 0 so something gets tried the next connection */ priv->auth_idx = 0; mm_callback_info_schedule (info); }
static void sysinfo_done (MMAtSerialPort *port, GString *response, GError *error, gpointer user_data) { MMCallbackInfo *info = (MMCallbackInfo *) user_data; GRegex *r; GMatchInfo *match_info; const char *reply; /* If the modem has already been removed, return without * scheduling callback */ if (mm_callback_info_check_modem_removed (info)) return; if (error) { /* Leave superclass' reg state alone if AT^SYSINFO isn't supported */ goto done; } reply = strip_response (response->str, "^SYSINFO:"); /* Format is "<srv_status>,<srv_domain>,<roam_status>,<sys_mode>,<sim_state>" */ r = g_regex_new ("\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); if (!r) { mm_warn ("Huawei: ^SYSINFO parse regex creation failed."); goto done; } g_regex_match (r, reply, 0, &match_info); if (g_match_info_get_match_count (match_info) >= 5) { MMModemCdmaRegistrationState reg_state; guint32 val = 0; /* At this point the generic code already knows we've been registered */ reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED; if (uint_from_match_item (match_info, 1, &val)) { if (val == 2) { /* Service available, check roaming state */ val = 0; if (uint_from_match_item (match_info, 3, &val)) { if (val == 0) reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_HOME; else if (val == 1) reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING; } } } /* Check service type */ val = 0; if (uint_from_match_item (match_info, 4, &val)) { if (val == 2) mm_generic_cdma_query_reg_state_set_callback_1x_state (info, reg_state); else if (val == 4) mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, reg_state); else if (val == 8) { mm_generic_cdma_query_reg_state_set_callback_1x_state (info, reg_state); mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, reg_state); } } else { /* Say we're registered to something even though sysmode parsing failed */ mm_generic_cdma_query_reg_state_set_callback_1x_state (info, reg_state); } } else mm_warn ("Huawei: failed to parse ^SYSINFO response."); g_match_info_free (match_info); g_regex_unref (r); done: mm_callback_info_schedule (info); }