diff options
author | David Timber <dxdt@dev.snart.me> | 2025-05-29 13:05:13 +0900 |
---|---|---|
committer | David Timber <dxdt@dev.snart.me> | 2025-05-29 13:05:13 +0900 |
commit | 5cf13f64b02ace83c84f7fbd8dc6b422b7732913 (patch) | |
tree | a34189b5277ebb50d763645886bafcc4d3efee01 | |
parent | 224c04065d459356e98ce0e3bb32425ce344ad14 (diff) |
SIM7600 CPCMREG, CPCFRM supportmmfwd
-rw-r--r-- | src/plugins/simtech/mm-shared-simtech.c | 111 |
1 files changed, 84 insertions, 27 deletions
diff --git a/src/plugins/simtech/mm-shared-simtech.c b/src/plugins/simtech/mm-shared-simtech.c index 99c2346e..121ab33e 100644 --- a/src/plugins/simtech/mm-shared-simtech.c +++ b/src/plugins/simtech/mm-shared-simtech.c @@ -51,12 +51,14 @@ typedef struct { /* voice */ MMIfaceModemVoice *iface_modem_voice_parent; FeatureSupport cpcmreg_support; + FeatureSupport cpcmfrm_support; FeatureSupport clcc_urc_support; GRegex *clcc_urc_regex; GRegex *voice_call_regex; GRegex *missed_call_regex; GRegex *cring_regex; GRegex *rxdtmf_regex; + guint cpcmreg_timer; } Private; static void @@ -67,6 +69,7 @@ private_free (Private *ctx) g_regex_unref (ctx->missed_call_regex); g_regex_unref (ctx->voice_call_regex); g_regex_unref (ctx->clcc_urc_regex); + if (ctx->cpcmreg_timer) g_source_remove(ctx->cpcmreg_timer); g_slice_free (Private, ctx); } @@ -85,12 +88,14 @@ get_private (MMSharedSimtech *self) priv->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE; priv->cgps_support = FEATURE_SUPPORT_UNKNOWN; priv->cpcmreg_support = FEATURE_SUPPORT_UNKNOWN; + priv->cpcmfrm_support = FEATURE_SUPPORT_UNKNOWN; priv->clcc_urc_support = FEATURE_SUPPORT_UNKNOWN; priv->clcc_urc_regex = mm_simtech_get_clcc_urc_regex (); priv->voice_call_regex = mm_simtech_get_voice_call_urc_regex (); priv->missed_call_regex = mm_simtech_get_missed_call_urc_regex (); priv->cring_regex = mm_simtech_get_cring_urc_regex (); priv->rxdtmf_regex = mm_simtech_get_rxdtmf_urc_regex (); + priv->cpcmreg_timer = 0; /* Setup parent class' MMIfaceModemLocation and MMIfaceModemVoice */ @@ -771,6 +776,45 @@ mm_shared_simtech_voice_enable_unsolicited_events (MMIfaceModemVoice *self, /* Common setup/cleanup voice unsolicited events */ static void +cpcmreg_set_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + + if (!mm_base_modem_at_command_finish (self, res, &error)) + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static gboolean +call_audio_channel_set (gpointer user_data) +{ + GTask *task; + MMBaseModem *modem; + gboolean setup; + + task = G_TASK (user_data); + setup = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (task), "setup")); + + if (g_task_return_error_if_cancelled (task)) { + g_object_unref (task); + return G_SOURCE_REMOVE; + } + + modem = g_task_get_source_object (task); + mm_base_modem_at_command (modem, + setup ? "+CPCMREG=1" : "+CPCMREG=0", + 3, + FALSE, + (GAsyncReadyCallback) cpcmreg_set_ready, + task); + return G_SOURCE_REMOVE; +} + +static void clcc_urc_received (MMPortSerialAt *port, GMatchInfo *match_info, MMSharedSimtech *self) @@ -1047,8 +1091,15 @@ mm_shared_simtech_voice_setup_in_call_audio_channel_finish (MMIfaceModemVoice * if (!g_task_propagate_boolean (G_TASK (res), error)) return FALSE; - if (audio_format) - *audio_format = NULL; + if (audio_format) { + MMCallAudioFormat *new_afmt = mm_call_audio_format_new(); + + mm_call_audio_format_set_encoding(new_afmt, "pcm"); + mm_call_audio_format_set_resolution(new_afmt, "s16le"); + mm_call_audio_format_set_rate(new_afmt, priv->cpcmfrm_support ? 16000 : 8000); + + *audio_format = new_afmt; + } if (audio_port) { if (priv->cpcmreg_support == FEATURE_SUPPORTED) @@ -1069,31 +1120,20 @@ mm_shared_simtech_voice_cleanup_in_call_audio_channel_finish (MMIfaceModemVoice } static void -cpcmreg_set_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - if (!mm_base_modem_at_command_finish (self, res, &error)) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void common_setup_cleanup_in_call_audio_channel (MMSharedSimtech *self, gboolean setup, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; - Private *priv; + GTask *task; + Private *priv; + GCancellable *cancellable; priv = get_private (MM_SHARED_SIMTECH (self)); - task = g_task_new (self, NULL, callback, user_data); + cancellable = mm_base_modem_peek_cancellable (MM_BASE_MODEM (self)); + task = g_task_new (self, cancellable, callback, user_data); + g_object_set_data (G_OBJECT (task), "setup", GINT_TO_POINTER (setup)); /* Do nothing if CPCMREG isn't supported */ if (priv->cpcmreg_support != FEATURE_SUPPORTED) { @@ -1102,12 +1142,8 @@ common_setup_cleanup_in_call_audio_channel (MMSharedSimtech *self, return; } - mm_base_modem_at_command (MM_BASE_MODEM (self), - setup ? "+CPCMREG=1" : "+CPCMREG=0", - 3, - FALSE, - (GAsyncReadyCallback) cpcmreg_set_ready, - task); + /* Some models (like SIM7600) need to wait a bit before they can accept +CPCMREG */ + g_timeout_add (500, (GSourceFunc)call_audio_channel_set, task); } void @@ -1138,6 +1174,23 @@ mm_shared_simtech_voice_check_support_finish (MMIfaceModemVoice *self, } static void +cpcmfrm_format_check_ready (MMBroadbandModem *self, + GAsyncResult *res, + GTask *task) +{ + Private *priv; + + priv = get_private (MM_SHARED_SIMTECH (self)); + + priv->cpcmfrm_support = (mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, NULL) ? + FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED); + mm_obj_dbg (self, "modem %s USB audio 16k sample rate", (priv->cpcmfrm_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support"); + + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void cpcmreg_format_check_ready (MMBroadbandModem *self, GAsyncResult *res, GTask *task) @@ -1150,8 +1203,12 @@ cpcmreg_format_check_ready (MMBroadbandModem *self, FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED); mm_obj_dbg (self, "modem %s USB audio control", (priv->cpcmreg_support == FEATURE_SUPPORTED) ? "supports" : "doesn't support"); - g_task_return_boolean (task, TRUE); - g_object_unref (task); + mm_base_modem_at_command (MM_BASE_MODEM (self), + "+CPCMFRM=1", + 6, + FALSE, + (GAsyncReadyCallback) cpcmfrm_format_check_ready, + task); } static void |