aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Caruso <ejcaruso@chromium.org>2020-10-16 11:22:37 -0700
committerEric Caruso <ejcaruso@chromium.org>2020-10-16 11:22:37 -0700
commit1800983b6c77b495a97eb4335541561456abfed5 (patch)
tree9882f6130f9ef91ec298eba2d1243e6a9d1ae668
parentf013e94ff89680d1acd7dba12ff4a6a0fa7b58bf (diff)
mm-modem-helpers: add low_nybble_first argument to mm_bcd_to_string
All BCD-encoded strings used by MM currently have the low nybble of each byte come before the high nybble, but some strings (such as the EID string returned by QMI Get Slot Status) are meant to be read in order with the high nybble before the low one. As such, extend mm_bcd_to_string to decode both.
-rw-r--r--src/mm-modem-helpers.c9
-rw-r--r--src/mm-modem-helpers.h4
-rw-r--r--src/mm-shared-qmi.c9
-rw-r--r--src/mm-sim-qmi.c6
-rw-r--r--src/tests/test-modem-helpers.c35
5 files changed, 41 insertions, 22 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index d080e010..3ee12aaa 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -473,7 +473,7 @@ mm_filter_supported_modes (const GArray *all,
static const gchar bcd_chars[] = "0123456789\0\0\0\0\0\0";
gchar *
-mm_bcd_to_string (const guint8 *bcd, gsize bcd_len)
+mm_bcd_to_string (const guint8 *bcd, gsize bcd_len, gboolean low_nybble_first)
{
GString *str;
gsize i;
@@ -482,8 +482,11 @@ mm_bcd_to_string (const guint8 *bcd, gsize bcd_len)
str = g_string_sized_new (bcd_len * 2 + 1);
for (i = 0 ; i < bcd_len; i++) {
- str = g_string_append_c (str, bcd_chars[bcd[i] & 0xF]);
+ if (low_nybble_first)
+ str = g_string_append_c (str, bcd_chars[bcd[i] & 0xF]);
str = g_string_append_c (str, bcd_chars[(bcd[i] >> 4) & 0xF]);
+ if (!low_nybble_first)
+ str = g_string_append_c (str, bcd_chars[bcd[i] & 0xF]);
}
return g_string_free (str, FALSE);
}
@@ -4301,7 +4304,7 @@ mm_3gpp_parse_emergency_numbers (const char *raw, GError **error)
for (i = 0; i < max_items; i++) {
gchar *number;
- number = mm_bcd_to_string (&bin[i*3], 3);
+ number = mm_bcd_to_string (&bin[i*3], 3, TRUE /* low_nybble_first */);
if (number && number[0])
g_ptr_array_add (out, number);
else
diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h
index c1a1b2c9..fb556543 100644
--- a/src/mm-modem-helpers.h
+++ b/src/mm-modem-helpers.h
@@ -84,7 +84,9 @@ GArray *mm_filter_supported_modes (const GArray *all,
const GArray *supported_combinations,
gpointer log_object);
-gchar *mm_bcd_to_string (const guint8 *bcd, gsize bcd_len);
+gchar *mm_bcd_to_string (const guint8 *bcd,
+ gsize bcd_len,
+ gboolean low_nybble_first);
/*****************************************************************************/
/* VOICE specific helpers and utilities */
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index bea47a39..4530057a 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -3423,7 +3423,8 @@ uim_get_slot_status_ready (QmiClientUim *client,
continue;
}
- raw_iccid = mm_bcd_to_string ((const guint8 *)slot_status->iccid->data, slot_status->iccid->len);
+ raw_iccid = mm_bcd_to_string ((const guint8 *)slot_status->iccid->data, slot_status->iccid->len,
+ TRUE /* low_nybble_first */);
if (!raw_iccid) {
mm_obj_warn (self, "not creating SIM object: failed to convert ICCID from BCD");
g_ptr_array_add (ctx->sim_slots, NULL);
@@ -3765,8 +3766,10 @@ uim_slot_status_indication_cb (QmiClientUim *client,
if (slot_status->physical_slot_status == QMI_UIM_SLOT_STATE_ACTIVE) {
g_autofree gchar *iccid = NULL;
- if (slot_status->iccid && slot_status->iccid->len > 0)
- iccid = mm_bcd_to_string ((const guint8 *) slot_status->iccid->data, slot_status->iccid->len);
+ if (slot_status->iccid && slot_status->iccid->len > 0) {
+ iccid = mm_bcd_to_string ((const guint8 *) slot_status->iccid->data, slot_status->iccid->len,
+ TRUE /* low_nybble_first */);
+ }
mm_iface_modem_check_for_sim_swap (MM_IFACE_MODEM (self),
i + 1, /* Slot index */
diff --git a/src/mm-sim-qmi.c b/src/mm-sim-qmi.c
index 52bf0792..bbe2352c 100644
--- a/src/mm-sim-qmi.c
+++ b/src/mm-sim-qmi.c
@@ -344,7 +344,8 @@ uim_get_iccid_ready (QmiClientUim *client,
return;
}
- iccid = mm_bcd_to_string ((const guint8 *) read_result->data, read_result->len);
+ iccid = mm_bcd_to_string ((const guint8 *) read_result->data, read_result->len,
+ TRUE /* low_nybble_first */);
g_assert (iccid);
g_task_return_pointer (task, iccid, g_free);
g_object_unref (task);
@@ -458,7 +459,8 @@ uim_get_imsi_ready (QmiClientUim *client,
return;
}
- imsi = mm_bcd_to_string ((const guint8 *) read_result->data, read_result->len);
+ imsi = mm_bcd_to_string ((const guint8 *) read_result->data, read_result->len,
+ TRUE /* low_nybble_first */);
g_assert (imsi);
if (strlen (imsi) < 3)
g_task_return_new_error (task,
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index 78b3cd11..a6bc72d2 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -4429,20 +4429,22 @@ test_parse_uint_list (void)
typedef struct {
const guint8 bcd[10];
gsize bcd_len;
- const gchar *str;
+ const gchar *low_nybble_first_str;
+ const gchar *high_nybble_first_str;
} BcdToStringTest;
static const BcdToStringTest bcd_to_string_tests[] = {
- { { }, 0, "" },
- { { 0x01 }, 1, "10" },
- { { 0x1F }, 1, "" },
- { { 0xE2 }, 1, "2" },
- { { 0xD3 }, 1, "3" },
- { { 0xC4 }, 1, "4" },
- { { 0xB1, 0x23 }, 2, "1" },
- { { 0x01, 0x23, 0x45, 0x67 }, 4, "10325476" },
- { { 0x01, 0x23, 0x45, 0xA7 }, 4, "1032547" },
- { { 0x01, 0x23, 0x45, 0x67 }, 2, "1032" },
+ { { }, 0, "", "" },
+ { { 0x01 }, 1, "10", "01" },
+ { { 0x1F }, 1, "", "1" },
+ { { 0xE2 }, 1, "2", "" },
+ { { 0xD3 }, 1, "3", "" },
+ { { 0xC4 }, 1, "4", "" },
+ { { 0xB1, 0x23 }, 2, "1", "" },
+ { { 0x01, 0x2A }, 2, "10", "012" },
+ { { 0x01, 0x23, 0x45, 0x67 }, 4, "10325476", "01234567" },
+ { { 0x01, 0x23, 0x45, 0xA7 }, 4, "1032547", "012345" },
+ { { 0x01, 0x23, 0x45, 0x67 }, 2, "1032", "0123" },
};
static void
@@ -4454,8 +4456,15 @@ test_bcd_to_string (void *f, gpointer d)
gchar *str;
str = mm_bcd_to_string (bcd_to_string_tests[i].bcd,
- bcd_to_string_tests[i].bcd_len);
- g_assert_cmpstr (str, ==, bcd_to_string_tests[i].str);
+ bcd_to_string_tests[i].bcd_len,
+ TRUE /* low_nybble_first */);
+ g_assert_cmpstr (str, ==, bcd_to_string_tests[i].low_nybble_first_str);
+ g_free (str);
+
+ str = mm_bcd_to_string (bcd_to_string_tests[i].bcd,
+ bcd_to_string_tests[i].bcd_len,
+ FALSE /* low_nybble_first */);
+ g_assert_cmpstr (str, ==, bcd_to_string_tests[i].high_nybble_first_str);
g_free (str);
}
}