aboutsummaryrefslogtreecommitdiff
path: root/src/mm-broadband-modem.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-07-31 12:59:23 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-06 20:15:41 +0200
commit4aaafc54c78f96160675109a27c4fde75ebb6f2e (patch)
tree487109407907aabcf496bd05acd8dd67dd88bea8 /src/mm-broadband-modem.c
parent4d5892204d9f28b65a9f1a8495c036c7448791bc (diff)
iface-modem-3gpp: removed the 'setup indicators' step
The previous logic would first request to check if indicators were supported, and only then allow to setup/enable/cleanup/disable unsolicited events. This behaviour is very specific to the generic 3GPP case, and therefore it shouldn't be handled in the even more generic 3GPP interface. The logic is still kept, but handled within the MMBroadbandModem object.
Diffstat (limited to 'src/mm-broadband-modem.c')
-rw-r--r--src/mm-broadband-modem.c288
1 files changed, 158 insertions, 130 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 515e3c1f..3c9cfcb2 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -113,6 +113,7 @@ struct _MMBroadbandModemPrivate {
MMModemState modem_state;
/* Implementation helpers */
MMModemCharset modem_current_charset;
+ gboolean modem_cind_support_checked;
gboolean modem_cind_supported;
guint modem_cind_indicator_signal_quality;
guint modem_cind_min_signal_quality;
@@ -1490,17 +1491,87 @@ modem_load_signal_quality (MMIfaceModem *self,
}
/*****************************************************************************/
-/* Setting up indicators (3GPP interface) */
+/* Setup/Cleanup unsolicited events (3GPP interface) */
static gboolean
-modem_3gpp_setup_indicators_finish (MMIfaceModem3gpp *self,
- GAsyncResult *res,
- GError **error)
+modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp *self,
+ GAsyncResult *res,
+ GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
+ciev_received (MMAtSerialPort *port,
+ GMatchInfo *info,
+ MMBroadbandModem *self)
+{
+ gint ind = 0;
+ gchar *item;
+
+ item = g_match_info_fetch (info, 1);
+ if (item)
+ ind = atoi (item);
+
+ /* Handle signal quality change indication */
+ if (ind == self->priv->modem_cind_indicator_signal_quality ||
+ g_str_equal (item, "signal")) {
+ gchar *value;
+
+ value = g_match_info_fetch (info, 2);
+ if (value) {
+ gint quality = 0;
+
+ quality = atoi (value);
+
+ mm_iface_modem_update_signal_quality (
+ MM_IFACE_MODEM (self),
+ normalize_ciev_cind_signal_quality (quality,
+ self->priv->modem_cind_min_signal_quality,
+ self->priv->modem_cind_max_signal_quality));
+ g_free (value);
+ }
+ }
+
+ g_free (item);
+
+ /* FIXME: handle roaming and service indicators.
+ * ... wait, arent these already handle by unsolicited CREG responses? */
+}
+
+static void
+set_unsolicited_events_handlers (MMBroadbandModem *self,
+ gboolean enable)
+{
+ MMAtSerialPort *ports[2];
+ GRegex *ciev_regex;
+ guint i;
+
+ ciev_regex = mm_3gpp_ciev_regex_get ();
+ ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
+ ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
+
+ /* Enable unsolicited events in given port */
+ for (i = 0; i < 2; i++) {
+ if (!ports[i])
+ continue;
+
+ /* Set/unset unsolicited CIEV event handler */
+ mm_dbg ("(%s) %s 3GPP unsolicited events handlers",
+ mm_port_get_device (MM_PORT (ports[i])),
+ enable ? "Setting" : "Removing");
+ mm_at_serial_port_add_unsolicited_msg_handler (
+ ports[i],
+ ciev_regex,
+ enable ? (MMAtSerialUnsolicitedMsgFn) ciev_received : NULL,
+ enable ? self : NULL,
+ NULL);
+ }
+
+ g_regex_unref (ciev_regex);
+}
+
+static void
cind_format_check_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
@@ -1513,8 +1584,10 @@ cind_format_check_ready (MMBroadbandModem *self,
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error ||
!(indicators = mm_3gpp_parse_cind_test_response (result, &error))) {
- /* quit with error */
- g_simple_async_result_take_error (simple, error);
+ /* unsupported indications */
+ mm_dbg ("Marking indications as unsupported: '%s'", error->message);
+ g_free (error);
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
@@ -1559,140 +1632,71 @@ cind_format_check_ready (MMBroadbandModem *self,
g_hash_table_destroy (indicators);
+ /* Now, keep on setting up the ports */
+ set_unsolicited_events_handlers (self, TRUE);
+
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
-modem_3gpp_setup_indicators (MMIfaceModem3gpp *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
+modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *_self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
- modem_3gpp_setup_indicators);
+ modem_3gpp_setup_unsolicited_events);
/* Load supported indicators */
- mm_base_modem_at_command (MM_BASE_MODEM (self),
- "+CIND=?",
- 3,
- TRUE,
- (GAsyncReadyCallback)cind_format_check_ready,
- result);
-}
-
-/*****************************************************************************/
-/* Setup/Cleanup unsolicited events (3GPP interface) */
-
-static gboolean
-modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp *self,
- GAsyncResult *res,
- GError **error)
-{
- return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
-}
-
-static void
-ciev_received (MMAtSerialPort *port,
- GMatchInfo *info,
- MMBroadbandModem *self)
-{
- gint ind = 0;
- gchar *item;
-
- item = g_match_info_fetch (info, 1);
- if (item)
- ind = atoi (item);
-
- /* Handle signal quality change indication */
- if (ind == self->priv->modem_cind_indicator_signal_quality ||
- g_str_equal (item, "signal")) {
- gchar *value;
-
- value = g_match_info_fetch (info, 2);
- if (value) {
- gint quality = 0;
-
- quality = atoi (value);
-
- mm_iface_modem_update_signal_quality (
- MM_IFACE_MODEM (self),
- normalize_ciev_cind_signal_quality (quality,
- self->priv->modem_cind_min_signal_quality,
- self->priv->modem_cind_max_signal_quality));
- g_free (value);
- }
+ if (!self->priv->modem_cind_support_checked) {
+ mm_dbg ("Checking indicator support...");
+ self->priv->modem_cind_support_checked = TRUE;
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CIND=?",
+ 3,
+ TRUE,
+ (GAsyncReadyCallback)cind_format_check_ready,
+ result);
+ return;
}
- g_free (item);
+ /* If supported, go on */
+ if (self->priv->modem_cind_supported)
+ set_unsolicited_events_handlers (self, TRUE);
- /* FIXME: handle roaming and service indicators.
- * ... wait, arent these already handle by unsolicited CREG responses? */
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
static void
-set_unsolicited_events_handlers (MMIfaceModem3gpp *self,
- gboolean enable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *_self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
- MMAtSerialPort *ports[2];
- GRegex *ciev_regex;
- guint i;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
- set_unsolicited_events_handlers);
-
- ciev_regex = mm_3gpp_ciev_regex_get ();
- ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
- ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
-
- /* Enable unsolicited events in given port */
- for (i = 0; i < 2; i++) {
- if (!ports[i])
- continue;
+ modem_3gpp_cleanup_unsolicited_events);
- /* Set/unset unsolicited CIEV event handler */
- mm_dbg ("(%s) %s 3GPP unsolicited events handlers",
- mm_port_get_device (MM_PORT (ports[i])),
- enable ? "Setting" : "Removing");
- mm_at_serial_port_add_unsolicited_msg_handler (
- ports[i],
- ciev_regex,
- enable ? (MMAtSerialUnsolicitedMsgFn) ciev_received : NULL,
- enable ? self : NULL,
- NULL);
- }
+ /* If supported, go on */
+ if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported)
+ set_unsolicited_events_handlers (self, FALSE);
- g_regex_unref (ciev_regex);
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
-static void
-modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- set_unsolicited_events_handlers (self, TRUE, callback, user_data);
-}
-
-static void
-modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- set_unsolicited_events_handlers (self, FALSE, callback, user_data);
-}
-
/*****************************************************************************/
/* Enabling/disabling unsolicited events (3GPP interface) */
@@ -1780,38 +1784,64 @@ run_unsolicited_events_setup (UnsolicitedEventsContext *ctx)
}
static void
-modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self,
+modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- UnsolicitedEventsContext *ctx;
+ MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
+ GSimpleAsyncResult *result;
- ctx = g_new0 (UnsolicitedEventsContext, 1);
- ctx->self = g_object_ref (self);
- ctx->enable = TRUE;
- ctx->command = g_strdup ("+CMER=3,0,0,1");
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_enable_unsolicited_events);
- run_unsolicited_events_setup (ctx);
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ modem_3gpp_enable_unsolicited_events);
+
+ /* If supported, go on */
+ if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
+ UnsolicitedEventsContext *ctx;
+
+ ctx = g_new0 (UnsolicitedEventsContext, 1);
+ ctx->self = g_object_ref (self);
+ ctx->enable = TRUE;
+ ctx->command = g_strdup ("+CMER=3,0,0,1");
+ ctx->result = result;
+ run_unsolicited_events_setup (ctx);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
static void
-modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
+modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- UnsolicitedEventsContext *ctx;
+ MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
+ GSimpleAsyncResult *result;
- ctx = g_new0 (UnsolicitedEventsContext, 1);
- ctx->self = g_object_ref (self);
- ctx->command = g_strdup ("+CMER=0");
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- modem_3gpp_disable_unsolicited_events);
- run_unsolicited_events_setup (ctx);
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ modem_3gpp_disable_unsolicited_events);
+
+ /* If supported, go on */
+ if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
+ UnsolicitedEventsContext *ctx;
+
+ ctx = g_new0 (UnsolicitedEventsContext, 1);
+ ctx->self = g_object_ref (self);
+ ctx->command = g_strdup ("+CMER=0");
+ ctx->result = result;
+ run_unsolicited_events_setup (ctx);
+ return;
+ }
+
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
/*****************************************************************************/
@@ -7878,8 +7908,6 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
iface->load_enabled_facility_locks_finish = modem_3gpp_load_enabled_facility_locks_finish;
/* Enabling steps */
- iface->setup_indicators = modem_3gpp_setup_indicators;
- iface->setup_indicators_finish = modem_3gpp_setup_indicators_finish;
iface->setup_unsolicited_events = modem_3gpp_setup_unsolicited_events;
iface->setup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events;