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.
This commit is contained in:
Eric Caruso
2020-10-16 11:22:37 -07:00
parent f013e94ff8
commit 1800983b6c
5 changed files with 41 additions and 22 deletions
+6 -3
View File
@@ -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
+3 -1
View File
@@ -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 */
+6 -3
View File
@@ -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 */
+4 -2
View File
@@ -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,
+22 -13
View File
@@ -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);
}
}