gsm: add SimIdentifier property
An obfuscated SimIdentifier that may be available before the PIN has been entered, for use in auto-unlocking a device. If this value is present, it should be used in preference to DeviceIdentifier as it is SIM-specific like the PIN code.
This commit is contained in:
@@ -109,6 +109,14 @@
|
|||||||
</arg>
|
</arg>
|
||||||
</method>
|
</method>
|
||||||
|
|
||||||
|
<property name="SimIdentifier" type="s" access="read">
|
||||||
|
<tp:docstring>
|
||||||
|
An obfuscated SIM identifier based on the IMSI or the ICCID. This may
|
||||||
|
be available before the PIN has been entered depending on the device
|
||||||
|
itself.
|
||||||
|
</tp:docstring>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property name="SupportedBands" type="u" access="read" tp:type="MM_MODEM_GSM_BAND">
|
<property name="SupportedBands" type="u" access="read" tp:type="MM_MODEM_GSM_BAND">
|
||||||
<tp:docstring>
|
<tp:docstring>
|
||||||
Bands supported by the card. (Note for plugin writers:
|
Bands supported by the card. (Note for plugin writers:
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -242,6 +243,78 @@ get_access_technology (MMGenericGsm *modem,
|
|||||||
mm_at_serial_port_queue_command (port, "*CNTI=0", 3, get_act_request_done, info);
|
mm_at_serial_port_queue_command (port, "*CNTI=0", 3, get_act_request_done, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_sim_iccid_done (MMAtSerialPort *port,
|
||||||
|
GString *response,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMCallbackInfo *info = user_data;
|
||||||
|
const char *p;
|
||||||
|
char buf[21];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
info->error = g_error_copy (error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = mm_strip_tag (response->str, "!ICCID:");
|
||||||
|
if (!p) {
|
||||||
|
info->error = g_error_new_literal (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Failed to parse !ICCID response");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (buf, 0, sizeof (buf));
|
||||||
|
for (i = 0; i < 20; i++) {
|
||||||
|
if (!isdigit (p[i]) && (p[i] != 'F') && (p[i] == 'f')) {
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"CRSM ICCID response contained invalid character '%c'",
|
||||||
|
p[i]);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (p[i] == 'F' || p[i] == 'f') {
|
||||||
|
buf[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[i] = p[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 19 || i == 20)
|
||||||
|
mm_callback_info_set_result (info, g_strdup (buf), g_free);
|
||||||
|
else {
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Invalid +CRSM ICCID response size (was %d, expected 19 or 20)",
|
||||||
|
i);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_sim_iccid (MMGenericGsm *modem,
|
||||||
|
MMModemStringFn callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMAtSerialPort *port;
|
||||||
|
MMCallbackInfo *info;
|
||||||
|
|
||||||
|
info = mm_callback_info_string_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, "!ICCID?", 3, get_sim_iccid_done, info);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Modem class override functions */
|
/* Modem class override functions */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -355,5 +428,6 @@ mm_modem_sierra_gsm_class_init (MMModemSierraGsmClass *klass)
|
|||||||
gsm_class->set_allowed_mode = set_allowed_mode;
|
gsm_class->set_allowed_mode = set_allowed_mode;
|
||||||
gsm_class->get_allowed_mode = get_allowed_mode;
|
gsm_class->get_allowed_mode = get_allowed_mode;
|
||||||
gsm_class->get_access_technology = get_access_technology;
|
gsm_class->get_access_technology = get_access_technology;
|
||||||
|
gsm_class->get_sim_iccid = get_sim_iccid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -69,6 +69,7 @@ typedef struct {
|
|||||||
gboolean pin_checked;
|
gboolean pin_checked;
|
||||||
guint32 pin_check_tries;
|
guint32 pin_check_tries;
|
||||||
guint pin_check_timeout;
|
guint pin_check_timeout;
|
||||||
|
char *simid;
|
||||||
|
|
||||||
MMModemGsmAllowedMode allowed_mode;
|
MMModemGsmAllowedMode allowed_mode;
|
||||||
|
|
||||||
@@ -555,6 +556,188 @@ initial_info_check (MMGenericGsm *self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_iccid_done (MMModem *modem,
|
||||||
|
const char *response,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMGenericGsmPrivate *priv;
|
||||||
|
const char *p = response;
|
||||||
|
GChecksum *sum;
|
||||||
|
|
||||||
|
if (error || !response || !strlen (response))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sum = g_checksum_new (G_CHECKSUM_SHA1);
|
||||||
|
|
||||||
|
/* Make sure it looks like an ICCID */
|
||||||
|
while (*p) {
|
||||||
|
if (!isdigit (*p)) {
|
||||||
|
g_warning ("%s: invalid ICCID format (not a digit)", __func__);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
g_checksum_update (sum, (const guchar *) p++, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
|
||||||
|
g_free (priv->simid);
|
||||||
|
priv->simid = g_strdup (g_checksum_get_string (sum));
|
||||||
|
|
||||||
|
if (mm_options_debug ()) {
|
||||||
|
g_debug ("SIM ID source '%s'", response);
|
||||||
|
g_debug ("SIM ID '%s'", priv->simid);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_notify (G_OBJECT (modem), MM_MODEM_GSM_CARD_SIM_IDENTIFIER);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_checksum_free (sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
real_get_iccid_done (MMAtSerialPort *port,
|
||||||
|
GString *response,
|
||||||
|
GError *error,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MMCallbackInfo *info = (MMCallbackInfo *) user_data;
|
||||||
|
const char *str;
|
||||||
|
int sw1, sw2;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
char buf[21], swapped[21];
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
info->error = g_error_copy (error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (buf, 0, sizeof (buf));
|
||||||
|
str = mm_strip_tag (response->str, "+CRSM:");
|
||||||
|
if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3)
|
||||||
|
success = TRUE;
|
||||||
|
else {
|
||||||
|
/* May not include quotes... */
|
||||||
|
if (sscanf (str, "%d,%d,%20c", &sw1, &sw2, (char *) &buf) == 3)
|
||||||
|
success = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
info->error = g_error_new_literal (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Could not parse the CRSM response");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) {
|
||||||
|
gsize len = 0;
|
||||||
|
int f_pos = -1, i;
|
||||||
|
|
||||||
|
/* Make sure the buffer is only digits or 'F' */
|
||||||
|
for (len = 0; len < sizeof (buf) && buf[len]; len++) {
|
||||||
|
if (isdigit (buf[len]))
|
||||||
|
continue;
|
||||||
|
if (buf[len] == 'F' || buf[len] == 'f') {
|
||||||
|
buf[len] = 'F'; /* canonicalize the F */
|
||||||
|
f_pos = len;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buf[len] == '\"') {
|
||||||
|
buf[len] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invalid character */
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"CRSM ICCID response contained invalid character '%c'",
|
||||||
|
buf[len]);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BCD encoded ICCIDs are 20 digits long */
|
||||||
|
if (len != 20) {
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Invalid +CRSM ICCID response size (was %zd, expected 20)",
|
||||||
|
len);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure if there's an 'F' that it's second-to-last */
|
||||||
|
if ((f_pos >= 0) && (f_pos != len - 2)) {
|
||||||
|
info->error = g_error_new_literal (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"Invalid +CRSM ICCID length (unexpected F)");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Swap digits in the EFiccid response to get the actual ICCID, each
|
||||||
|
* group of 2 digits is reversed in the +CRSM response. i.e.:
|
||||||
|
*
|
||||||
|
* 21436587 -> 12345678
|
||||||
|
*/
|
||||||
|
memset (swapped, 0, sizeof (swapped));
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
swapped[i * 2] = buf[(i * 2) + 1];
|
||||||
|
swapped[(i * 2) + 1] = buf[i * 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zero out the F for 19 digit ICCIDs */
|
||||||
|
if (swapped[len - 1] == 'F')
|
||||||
|
swapped[len - 1] = 0;
|
||||||
|
|
||||||
|
mm_callback_info_set_result (info, g_strdup (swapped), g_free);
|
||||||
|
} else {
|
||||||
|
info->error = g_error_new (MM_MODEM_ERROR,
|
||||||
|
MM_MODEM_ERROR_GENERAL,
|
||||||
|
"SIM failed to handle CRSM request (sw1 %d sw2 %d)",
|
||||||
|
sw1, sw2);
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
mm_callback_info_schedule (info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
real_get_sim_iccid (MMGenericGsm *self,
|
||||||
|
MMModemStringFn callback,
|
||||||
|
gpointer callback_data)
|
||||||
|
{
|
||||||
|
MMCallbackInfo *info;
|
||||||
|
MMAtSerialPort *port;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
port = mm_generic_gsm_get_best_at_port (self, &error);
|
||||||
|
if (!port) {
|
||||||
|
callback (MM_MODEM (self), NULL, error, callback_data);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mm_serial_port_open (MM_SERIAL_PORT (port), &error)) {
|
||||||
|
callback (MM_MODEM (self), NULL, error, callback_data);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = mm_callback_info_string_new (MM_MODEM (self), callback, callback_data);
|
||||||
|
|
||||||
|
/* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */
|
||||||
|
mm_at_serial_port_queue_command (port,
|
||||||
|
"+CRSM=176,12258,0,0,10",
|
||||||
|
3,
|
||||||
|
real_get_iccid_done,
|
||||||
|
info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initial_iccid_check (MMGenericGsm *self)
|
||||||
|
{
|
||||||
|
g_assert (MM_GENERIC_GSM_GET_CLASS (self)->get_sim_iccid);
|
||||||
|
MM_GENERIC_GSM_GET_CLASS (self)->get_sim_iccid (self, get_iccid_done, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
owns_port (MMModem *modem, const char *subsys, const char *name)
|
owns_port (MMModem *modem, const char *subsys, const char *name)
|
||||||
{
|
{
|
||||||
@@ -608,9 +791,12 @@ mm_generic_gsm_grab_port (MMGenericGsm *self,
|
|||||||
/* Get the modem's general info */
|
/* Get the modem's general info */
|
||||||
initial_info_check (self);
|
initial_info_check (self);
|
||||||
|
|
||||||
/* Get modem's IMEI number */
|
/* Get modem's IMEI */
|
||||||
initial_imei_check (self);
|
initial_imei_check (self);
|
||||||
|
|
||||||
|
/* Try to get the SIM's ICCID */
|
||||||
|
initial_iccid_check (self);
|
||||||
|
|
||||||
/* Get modem's initial lock/unlock state */
|
/* Get modem's initial lock/unlock state */
|
||||||
initial_pin_check (self);
|
initial_pin_check (self);
|
||||||
|
|
||||||
@@ -4184,6 +4370,7 @@ set_property (GObject *object, guint prop_id,
|
|||||||
case MM_GENERIC_GSM_PROP_SUPPORTED_MODES:
|
case MM_GENERIC_GSM_PROP_SUPPORTED_MODES:
|
||||||
case MM_GENERIC_GSM_PROP_ALLOWED_MODE:
|
case MM_GENERIC_GSM_PROP_ALLOWED_MODE:
|
||||||
case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY:
|
case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY:
|
||||||
|
case MM_GENERIC_GSM_PROP_SIM_IDENTIFIER:
|
||||||
#if LOCATION_API
|
#if LOCATION_API
|
||||||
case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
|
case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
|
||||||
case MM_GENERIC_GSM_PROP_LOC_ENABLED:
|
case MM_GENERIC_GSM_PROP_LOC_ENABLED:
|
||||||
@@ -4250,6 +4437,9 @@ get_property (GObject *object, guint prop_id,
|
|||||||
else
|
else
|
||||||
g_value_set_uint (value, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN);
|
g_value_set_uint (value, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN);
|
||||||
break;
|
break;
|
||||||
|
case MM_GENERIC_GSM_PROP_SIM_IDENTIFIER:
|
||||||
|
g_value_set_string (value, priv->simid);
|
||||||
|
break;
|
||||||
#if LOCATION_API
|
#if LOCATION_API
|
||||||
case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
|
case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
|
||||||
g_value_set_uint (value, priv->loc_caps);
|
g_value_set_uint (value, priv->loc_caps);
|
||||||
@@ -4303,6 +4493,7 @@ finalize (GObject *object)
|
|||||||
|
|
||||||
g_free (priv->oper_code);
|
g_free (priv->oper_code);
|
||||||
g_free (priv->oper_name);
|
g_free (priv->oper_name);
|
||||||
|
g_free (priv->simid);
|
||||||
|
|
||||||
G_OBJECT_CLASS (mm_generic_gsm_parent_class)->finalize (object);
|
G_OBJECT_CLASS (mm_generic_gsm_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -4323,6 +4514,7 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass)
|
|||||||
klass->do_enable = real_do_enable;
|
klass->do_enable = real_do_enable;
|
||||||
klass->do_enable_power_up_done = real_do_enable_power_up_done;
|
klass->do_enable_power_up_done = real_do_enable_power_up_done;
|
||||||
klass->do_disconnect = real_do_disconnect;
|
klass->do_disconnect = real_do_disconnect;
|
||||||
|
klass->get_sim_iccid = real_get_sim_iccid;
|
||||||
|
|
||||||
/* Properties */
|
/* Properties */
|
||||||
g_object_class_override_property (object_class,
|
g_object_class_override_property (object_class,
|
||||||
@@ -4349,6 +4541,10 @@ mm_generic_gsm_class_init (MMGenericGsmClass *klass)
|
|||||||
MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY,
|
MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY,
|
||||||
MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY);
|
MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY);
|
||||||
|
|
||||||
|
g_object_class_override_property (object_class,
|
||||||
|
MM_GENERIC_GSM_PROP_SIM_IDENTIFIER,
|
||||||
|
MM_MODEM_GSM_CARD_SIM_IDENTIFIER);
|
||||||
|
|
||||||
#if LOCATION_API
|
#if LOCATION_API
|
||||||
g_object_class_override_property (object_class,
|
g_object_class_override_property (object_class,
|
||||||
MM_GENERIC_GSM_PROP_LOC_CAPABILITIES,
|
MM_GENERIC_GSM_PROP_LOC_CAPABILITIES,
|
||||||
|
@@ -55,6 +55,7 @@ typedef enum {
|
|||||||
MM_GENERIC_GSM_PROP_LOC_SIGNAL,
|
MM_GENERIC_GSM_PROP_LOC_SIGNAL,
|
||||||
MM_GENERIC_GSM_PROP_LOC_LOCATION,
|
MM_GENERIC_GSM_PROP_LOC_LOCATION,
|
||||||
#endif
|
#endif
|
||||||
|
MM_GENERIC_GSM_PROP_SIM_IDENTIFIER,
|
||||||
} MMGenericGsmProp;
|
} MMGenericGsmProp;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -128,6 +129,11 @@ typedef struct {
|
|||||||
void (*loc_get_capabilities) (MMGenericGsm *self,
|
void (*loc_get_capabilities) (MMGenericGsm *self,
|
||||||
MMModemUIntFn callback,
|
MMModemUIntFn callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
|
/* Called by the generic class to retrieve the SIM's ICCID */
|
||||||
|
void (*get_sim_iccid) (MMGenericGsm *self,
|
||||||
|
MMModemStringFn callback,
|
||||||
|
gpointer user_data);
|
||||||
} MMGenericGsmClass;
|
} MMGenericGsmClass;
|
||||||
|
|
||||||
GType mm_generic_gsm_get_type (void);
|
GType mm_generic_gsm_get_type (void);
|
||||||
|
@@ -579,6 +579,14 @@ mm_modem_gsm_card_init (gpointer g_iface)
|
|||||||
|
|
||||||
initialized = TRUE;
|
initialized = TRUE;
|
||||||
|
|
||||||
|
g_object_interface_install_property
|
||||||
|
(g_iface,
|
||||||
|
g_param_spec_string (MM_MODEM_GSM_CARD_SIM_IDENTIFIER,
|
||||||
|
"SimIdentifier",
|
||||||
|
"An obfuscated identifier of the SIM",
|
||||||
|
NULL,
|
||||||
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
g_object_interface_install_property
|
g_object_interface_install_property
|
||||||
(g_iface,
|
(g_iface,
|
||||||
g_param_spec_uint (MM_MODEM_GSM_CARD_SUPPORTED_BANDS,
|
g_param_spec_uint (MM_MODEM_GSM_CARD_SUPPORTED_BANDS,
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
|
#define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
|
||||||
#define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
|
#define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
|
||||||
|
#define MM_MODEM_GSM_CARD_SIM_IDENTIFIER "sim-identifier"
|
||||||
|
|
||||||
#define MM_MODEM_GSM_CARD_SIM_PIN "sim-pin"
|
#define MM_MODEM_GSM_CARD_SIM_PIN "sim-pin"
|
||||||
#define MM_MODEM_GSM_CARD_SIM_PIN2 "sim-pin2"
|
#define MM_MODEM_GSM_CARD_SIM_PIN2 "sim-pin2"
|
||||||
|
@@ -33,6 +33,13 @@ response_clean (GString *response)
|
|||||||
s -= 2;
|
s -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Contains duplicate '<CR><CR>' */
|
||||||
|
s = response->str;
|
||||||
|
while ((response->len >= 2) && (*s == '\r') && (*(s + 1) == '\r')) {
|
||||||
|
g_string_erase (response, 0, 1);
|
||||||
|
s = response->str;
|
||||||
|
}
|
||||||
|
|
||||||
/* Starts with one or more '<CR><LF>' */
|
/* Starts with one or more '<CR><LF>' */
|
||||||
s = response->str;
|
s = response->str;
|
||||||
while ((response->len >= 2) && (*s == '\r') && (*(s + 1) == '\n')) {
|
while ((response->len >= 2) && (*s == '\r') && (*(s + 1) == '\n')) {
|
||||||
|
15
test/info.py
15
test/info.py
@@ -167,6 +167,13 @@ def gsm_inspect(proxy, props):
|
|||||||
# Gsm.Card interface
|
# Gsm.Card interface
|
||||||
card = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_CARD)
|
card = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM_GSM_CARD)
|
||||||
|
|
||||||
|
simid = "<unavailable>"
|
||||||
|
try:
|
||||||
|
simid = props.Get(MM_DBUS_INTERFACE_MODEM_GSM_CARD, "SimIdentifier")
|
||||||
|
except dbus.exceptions.DBusException:
|
||||||
|
pass
|
||||||
|
print "SIM ID: %s" % simid
|
||||||
|
|
||||||
imei = "<unavailable>"
|
imei = "<unavailable>"
|
||||||
try:
|
try:
|
||||||
imei = card.GetImei()
|
imei = card.GetImei()
|
||||||
@@ -229,10 +236,10 @@ if mtype == 1:
|
|||||||
elif mtype == 2:
|
elif mtype == 2:
|
||||||
print "Type: CDMA"
|
print "Type: CDMA"
|
||||||
|
|
||||||
print "Driver: '%s'" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
|
print "Driver: %s" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'Driver'))
|
||||||
print "Modem device: '%s'" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
|
print "Modem device: %s" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'MasterDevice'))
|
||||||
print "Data device: '%s'" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'Device'))
|
print "Data device: %s" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'Device'))
|
||||||
print "Device ID: '%s'" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'DeviceIdentifier'))
|
print "Device ID: %s" % (props.Get(MM_DBUS_INTERFACE_MODEM, 'DeviceIdentifier'))
|
||||||
print ""
|
print ""
|
||||||
|
|
||||||
modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
|
modem = dbus.Interface(proxy, dbus_interface=MM_DBUS_INTERFACE_MODEM)
|
||||||
|
Reference in New Issue
Block a user