aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <dxdt@dev.snart.me>2025-05-29 13:05:13 +0900
committerDavid Timber <dxdt@dev.snart.me>2025-05-29 13:05:13 +0900
commit5cf13f64b02ace83c84f7fbd8dc6b422b7732913 (patch)
treea34189b5277ebb50d763645886bafcc4d3efee01
parent224c04065d459356e98ce0e3bb32425ce344ad14 (diff)
SIM7600 CPCMREG, CPCFRM supportmmfwd
-rw-r--r--src/plugins/simtech/mm-shared-simtech.c111
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