modem-helpers: add utility function to split DTMF runs

Split into groups of non-pause characters and single pause characters
by themselves and return as an array of strings.

Signed-off-by: Dan Williams <dan@ioncontrol.co>
This commit is contained in:
Dan Williams
2025-05-30 08:02:47 -05:00
parent 957a141e57
commit 56fe8e7d31
4 changed files with 83 additions and 2 deletions
-2
View File
@@ -41,8 +41,6 @@ typedef struct _MMBaseCallPrivate MMBaseCallPrivate;
#define MM_CALL_NUMBER "number"
#define MM_CALL_DTMF_TONE_DURATION "dtmf-tone-duration"
#define MM_CALL_DTMF_PAUSE_CHAR ','
#define MM_BASE_CALL_PATH "call-path"
#define MM_BASE_CALL_CONNECTION "call-connection"
#define MM_BASE_CALL_IFACE_MODEM_VOICE "call-iface-modem-voice"
+34
View File
@@ -5887,3 +5887,37 @@ mm_dtmf_duration_normalize (guint duration_ms)
return CLAMP (duration_ms, 100, 1000);
}
GPtrArray *
mm_dtmf_split (const gchar *dtmf)
{
GPtrArray *array;
const gchar *p = dtmf;
GString *cur = NULL;
array = g_ptr_array_new ();
while (*p) {
if (*p == MM_CALL_DTMF_PAUSE_CHAR) {
if (cur) {
g_ptr_array_add (array, g_string_free (cur, FALSE));
cur = NULL;
}
g_ptr_array_add (array, g_strdup (","));
} else {
if (!cur)
cur = g_string_new (NULL);
g_string_append_c (cur, *p);
}
p++;
}
if (cur)
g_ptr_array_add (array, g_string_free (cur, FALSE));
if (array->len == 0) {
g_ptr_array_free (array, TRUE);
return NULL;
}
return array;
}
+4
View File
@@ -648,4 +648,8 @@ MMModemLock mm_parse_cpin_response (const gchar *response,
/* Helper to clamp duration and round to next 100ms */
guint mm_dtmf_duration_normalize (guint duration_ms);
#define MM_CALL_DTMF_PAUSE_CHAR ','
GPtrArray *mm_dtmf_split (const gchar *dtmf);
#endif /* MM_MODEM_HELPERS_H */
+45
View File
@@ -5120,6 +5120,44 @@ test_cpin_response (void)
/*****************************************************************************/
typedef struct {
const char *desc;
const char *dtmf;
const char *expected[5];
} DtmfTestData;
static const DtmfTestData test_dtmf_data[] = {
{ "/MM/ModemHelpers/DTMF/empty", "", { NULL } },
{ "/MM/ModemHelpers/DTMF/one", "1", { "1", NULL } },
{ "/MM/ModemHelpers/DTMF/no-pause", "1234", { "1234", NULL } },
{ "/MM/ModemHelpers/DTMF/mid-pause", "123,,456", { "123", ",", ",", "456", NULL } },
{ "/MM/ModemHelpers/DTMF/end-pause", "123,,", { "123", ",", ",", NULL } },
};
static void
test_dtmf_split (gpointer user_data)
{
DtmfTestData *td = user_data;
GPtrArray *split;
guint expected_len;
guint i;
split = mm_dtmf_split (td->dtmf);
expected_len = g_strv_length ((gchar **) td->expected);
if (expected_len == 0)
g_assert_true (split == NULL);
else {
g_assert_true (split != NULL);
g_assert_cmpint (split->len, ==, expected_len);
}
for (i = 0; i < expected_len; i++)
g_assert_cmpstr (td->expected[i], ==, g_ptr_array_index (split, i));
}
/*****************************************************************************/
#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (GTestFixtureFunc) t, NULL)
int main (int argc, char **argv)
@@ -5128,6 +5166,7 @@ int main (int argc, char **argv)
RegTestData *reg_data;
gint result;
DevidItem *item = &devids[0];
guint i;
g_test_init (&argc, &argv, NULL);
@@ -5384,6 +5423,12 @@ int main (int argc, char **argv)
g_test_suite_add (suite, TESTCASE (test_cpin_response, NULL));
for (i = 0; i < G_N_ELEMENTS (test_dtmf_data); i++) {
g_test_add_data_func (test_dtmf_data[i].desc,
&test_dtmf_data[i],
(GTestDataFunc) test_dtmf_split);
}
result = g_test_run ();
reg_test_data_free (reg_data);