aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-08-14 16:14:37 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-09-09 10:19:20 +0200
commite6a7c85661d33493a8de7f19c6c7ff8773b83e8c (patch)
treef59cdd1631b12c4b9c83f3c16571bc23506ab556 /src
parentdf47f1ac8f696c2712efc8c76bd9551d88c3d837 (diff)
broadband-modem-qmi: handle OMA indications
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-qmi.c271
-rw-r--r--src/mm-modem-helpers-qmi.c80
-rw-r--r--src/mm-modem-helpers-qmi.h9
3 files changed, 359 insertions, 1 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index 760dfea0..08ab45ef 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -111,6 +111,11 @@ struct _MMBroadbandModemQmiPrivate {
MMModemLocationSource enabled_sources;
guint location_event_report_indication_id;
+ /* Oma helpers */
+ gboolean oma_unsolicited_events_enabled;
+ gboolean oma_unsolicited_events_setup;
+ guint oma_event_report_indication_id;
+
/* Firmware helpers */
GList *firmware_list;
MMFirmwareProperties *current_firmware;
@@ -8032,6 +8037,261 @@ oma_check_support (MMIfaceModemOma *self,
}
/*****************************************************************************/
+/* Setup/Cleanup unsolicited event handlers (OMA interface) */
+
+static void
+oma_event_report_indication_cb (QmiClientNas *client,
+ QmiIndicationOmaEventReportOutput *output,
+ MMBroadbandModemQmi *self)
+{
+ QmiOmaSessionState qmi_session_state;
+ QmiOmaSessionType network_initiated_alert_session_type;
+ guint16 network_initiated_alert_session_id;
+
+ /* Update session state? */
+ if (qmi_indication_oma_event_report_output_get_session_state (
+ output,
+ &qmi_session_state,
+ NULL)) {
+ QmiOmaSessionFailedReason qmi_oma_session_failed_reason = QMI_OMA_SESSION_FAILED_REASON_UNKNOWN;
+
+ if (qmi_session_state == QMI_OMA_SESSION_STATE_FAILED)
+ qmi_indication_oma_event_report_output_get_session_fail_reason (
+ output,
+ &qmi_oma_session_failed_reason,
+ NULL);
+
+ mm_iface_modem_oma_update_session_state (
+ MM_IFACE_MODEM_OMA (self),
+ mm_oma_session_state_from_qmi_oma_session_state (qmi_session_state),
+ mm_oma_session_state_failed_reason_from_qmi_oma_session_failed_reason (qmi_oma_session_failed_reason));
+ }
+
+ /* New network initiated session? */
+ if (qmi_indication_oma_event_report_output_get_network_initiated_alert (
+ output,
+ &network_initiated_alert_session_type,
+ &network_initiated_alert_session_id,
+ NULL)) {
+ mm_iface_modem_oma_add_pending_network_initiated_session (
+ MM_IFACE_MODEM_OMA (self),
+ mm_oma_session_type_from_qmi_oma_session_type (network_initiated_alert_session_type),
+ (guint)network_initiated_alert_session_id);
+ }
+}
+
+static gboolean
+common_oma_setup_cleanup_unsolicited_events_finish (MMIfaceModemOma *_self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
+static void
+common_setup_cleanup_oma_unsolicited_events (MMBroadbandModemQmi *self,
+ gboolean enable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+ QmiClient *client = NULL;
+
+ if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self),
+ QMI_SERVICE_OMA, &client,
+ callback, user_data))
+ return;
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ common_setup_cleanup_oma_unsolicited_events);
+
+ if (enable == self->priv->oma_unsolicited_events_setup) {
+ mm_dbg ("OMA unsolicited events already %s; skipping",
+ enable ? "setup" : "cleanup");
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+ return;
+ }
+
+ /* Store new state */
+ self->priv->oma_unsolicited_events_setup = enable;
+
+ /* Connect/Disconnect "Event Report" indications */
+ if (enable) {
+ g_assert (self->priv->oma_event_report_indication_id == 0);
+ self->priv->oma_event_report_indication_id =
+ g_signal_connect (client,
+ "event-report",
+ G_CALLBACK (oma_event_report_indication_cb),
+ self);
+ } else {
+ g_assert (self->priv->oma_event_report_indication_id != 0);
+ g_signal_handler_disconnect (client, self->priv->oma_event_report_indication_id);
+ self->priv->oma_event_report_indication_id = 0;
+ }
+
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+oma_cleanup_unsolicited_events (MMIfaceModemOma *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_setup_cleanup_oma_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
+ FALSE,
+ callback,
+ user_data);
+}
+
+static void
+oma_setup_unsolicited_events (MMIfaceModemOma *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_setup_cleanup_oma_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
+ TRUE,
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
+/* Enable/Disable unsolicited events (OMA interface) */
+
+typedef struct {
+ MMBroadbandModemQmi *self;
+ GSimpleAsyncResult *result;
+ QmiClientOma *client;
+ gboolean enable;
+} EnableOmaUnsolicitedEventsContext;
+
+static void
+enable_oma_unsolicited_events_context_complete_and_free (EnableOmaUnsolicitedEventsContext *ctx)
+{
+ g_simple_async_result_complete (ctx->result);
+ g_object_unref (ctx->result);
+ g_object_unref (ctx->client);
+ g_object_unref (ctx->self);
+ g_slice_free (EnableOmaUnsolicitedEventsContext, ctx);
+}
+
+static gboolean
+common_oma_enable_disable_unsolicited_events_finish (MMIfaceModemOma *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
+}
+
+static void
+ser_oma_indicator_ready (QmiClientOma *client,
+ GAsyncResult *res,
+ EnableOmaUnsolicitedEventsContext *ctx)
+{
+ QmiMessageOmaSetEventReportOutput *output = NULL;
+ GError *error = NULL;
+
+ output = qmi_client_oma_set_event_report_finish (client, res, &error);
+ if (!output) {
+ mm_dbg ("QMI operation failed: '%s'", error->message);
+ g_error_free (error);
+ } else if (!qmi_message_oma_set_event_report_output_get_result (output, &error)) {
+ mm_dbg ("Couldn't set event report: '%s'", error->message);
+ g_error_free (error);
+ }
+
+ if (output)
+ qmi_message_oma_set_event_report_output_unref (output);
+
+ /* Just ignore errors for now */
+ ctx->self->priv->oma_unsolicited_events_enabled = ctx->enable;
+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ enable_oma_unsolicited_events_context_complete_and_free (ctx);
+}
+
+static void
+common_enable_disable_oma_unsolicited_events (MMBroadbandModemQmi *self,
+ gboolean enable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ EnableOmaUnsolicitedEventsContext *ctx;
+ GSimpleAsyncResult *result;
+ QmiClient *client = NULL;
+ QmiMessageOmaSetEventReportInput *input;
+
+ if (!ensure_qmi_client (MM_BROADBAND_MODEM_QMI (self),
+ QMI_SERVICE_OMA, &client,
+ callback, user_data))
+ return;
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ common_enable_disable_oma_unsolicited_events);
+
+ if (enable == self->priv->oma_unsolicited_events_enabled) {
+ mm_dbg ("OMA unsolicited events already %s; skipping",
+ enable ? "enabled" : "disabled");
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+ return;
+ }
+
+ ctx = g_slice_new0 (EnableOmaUnsolicitedEventsContext);
+ ctx->self = g_object_ref (self);
+ ctx->client = g_object_ref (client);
+ ctx->enable = enable;
+ ctx->result = result;
+
+ input = qmi_message_oma_set_event_report_input_new ();
+ qmi_message_oma_set_event_report_input_set_session_state_reporting (
+ input,
+ ctx->enable,
+ NULL);
+ qmi_message_oma_set_event_report_input_set_network_initiated_alert_reporting (
+ input,
+ ctx->enable,
+ NULL);
+ qmi_client_oma_set_event_report (
+ ctx->client,
+ input,
+ 5,
+ NULL,
+ (GAsyncReadyCallback)ser_oma_indicator_ready,
+ ctx);
+ qmi_message_oma_set_event_report_input_unref (input);
+}
+
+static void
+oma_disable_unsolicited_events (MMIfaceModemOma *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_enable_disable_oma_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
+ FALSE,
+ callback,
+ user_data);
+}
+
+static void
+oma_enable_unsolicited_events (MMIfaceModemOma *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_enable_disable_oma_unsolicited_events (MM_BROADBAND_MODEM_QMI (self),
+ TRUE,
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
/* Check firmware support (Firmware interface) */
typedef struct {
@@ -9366,7 +9626,8 @@ initialization_started (MMBroadbandModem *self,
ctx->services[1] = QMI_SERVICE_NAS;
ctx->services[2] = QMI_SERVICE_WMS;
ctx->services[3] = QMI_SERVICE_PDS;
- ctx->services[4] = QMI_SERVICE_UNKNOWN;
+ ctx->services[4] = QMI_SERVICE_OMA;
+ ctx->services[5] = QMI_SERVICE_UNKNOWN;
/* Now open our QMI port */
mm_qmi_port_open (ctx->qmi,
@@ -9650,6 +9911,14 @@ iface_modem_oma_init (MMIfaceModemOma *iface)
{
iface->check_support = oma_check_support;
iface->check_support_finish = oma_check_support_finish;
+ iface->setup_unsolicited_events = oma_setup_unsolicited_events;
+ iface->setup_unsolicited_events_finish = common_oma_setup_cleanup_unsolicited_events_finish;
+ iface->cleanup_unsolicited_events = oma_cleanup_unsolicited_events;
+ iface->cleanup_unsolicited_events_finish = common_oma_setup_cleanup_unsolicited_events_finish;
+ iface->enable_unsolicited_events = oma_enable_unsolicited_events;
+ iface->enable_unsolicited_events_finish = common_oma_enable_disable_unsolicited_events_finish;
+ iface->disable_unsolicited_events = oma_disable_unsolicited_events;
+ iface->disable_unsolicited_events_finish = common_oma_enable_disable_unsolicited_events_finish;
}
static void
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index 61d8b271..ece937ef 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -1271,3 +1271,83 @@ mm_modem_capability_from_qmi_capabilities_context (MMQmiCapabilitiesContext *ctx
return tmp;
}
+
+/*****************************************************************************/
+
+MMOmaSessionType
+mm_oma_session_type_from_qmi_oma_session_type (QmiOmaSessionType qmi_session_type)
+{
+ switch (qmi_session_type) {
+ case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE:
+ return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_DEVICE_CONFIGURE;
+ case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE:
+ return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_PRL_UPDATE;
+ case QMI_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION:
+ return MM_OMA_SESSION_TYPE_CLIENT_INITIATED_HANDS_FREE_ACTIVATION;
+ case QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION:
+ return MM_OMA_SESSION_TYPE_DEVICE_INITIATED_HANDS_FREE_ACTIVATION;
+ case QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE:
+ return MM_OMA_SESSION_TYPE_NETWORK_INITIATED_PRL_UPDATE;
+ case QMI_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE:
+ return MM_OMA_SESSION_TYPE_NETWORK_INITIATED_DEVICE_CONFIGURE;
+ case QMI_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE:
+ return MM_OMA_SESSION_TYPE_DEVICE_INITIATED_PRL_UPDATE;
+ default:
+ return MM_OMA_SESSION_TYPE_UNKNOWN;
+ }
+}
+
+MMOmaSessionState
+mm_oma_session_state_from_qmi_oma_session_state (QmiOmaSessionState qmi_session_state)
+{
+ /* Note: MM_OMA_SESSION_STATE_STARTED is not a state received from the modem */
+
+ switch (qmi_session_state) {
+ case QMI_OMA_SESSION_STATE_COMPLETE_INFORMATION_UPDATED:
+ case QMI_OMA_SESSION_STATE_COMPLETE_UPDATED_INFORMATION_UNAVAILABLE:
+ return MM_OMA_SESSION_STATE_COMPLETED;
+ case QMI_OMA_SESSION_STATE_FAILED:
+ return MM_OMA_SESSION_STATE_FAILED;
+ case QMI_OMA_SESSION_STATE_RETRYING:
+ return MM_OMA_SESSION_STATE_RETRYING;
+ case QMI_OMA_SESSION_STATE_CONNECTING:
+ return MM_OMA_SESSION_STATE_CONNECTING;
+ case QMI_OMA_SESSION_STATE_CONNECTED:
+ return MM_OMA_SESSION_STATE_CONNECTED;
+ case QMI_OMA_SESSION_STATE_AUTHENTICATED:
+ return MM_OMA_SESSION_STATE_AUTHENTICATED;
+ case QMI_OMA_SESSION_STATE_MDN_DOWNLOADED:
+ return MM_OMA_SESSION_STATE_MDN_DOWNLOADED;
+ case QMI_OMA_SESSION_STATE_MSID_DOWNLOADED:
+ return MM_OMA_SESSION_STATE_MSID_DOWNLOADED;
+ case QMI_OMA_SESSION_STATE_PRL_DOWNLOADED:
+ return MM_OMA_SESSION_STATE_PRL_DOWNLOADED;
+ case QMI_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED:
+ return MM_OMA_SESSION_STATE_MIP_PROFILE_DOWNLOADED;
+ default:
+ return MM_OMA_SESSION_STATE_UNKNOWN;
+ }
+}
+
+/*****************************************************************************/
+
+MMOmaSessionStateFailedReason
+mm_oma_session_state_failed_reason_from_qmi_oma_session_failed_reason (QmiOmaSessionFailedReason qmi_session_failed_reason)
+{
+ switch (qmi_session_failed_reason) {
+ case QMI_OMA_SESSION_FAILED_REASON_UNKNOWN:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_UNKNOWN;
+ case QMI_OMA_SESSION_FAILED_REASON_NETWORK_UNAVAILABLE:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_NETWORK_UNAVAILABLE;
+ case QMI_OMA_SESSION_FAILED_REASON_SERVER_UNAVAILABLE:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_SERVER_UNAVAILABLE;
+ case QMI_OMA_SESSION_FAILED_REASON_AUTHENTICATION_FAILED:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_AUTHENTICATION_FAILED;
+ case QMI_OMA_SESSION_FAILED_REASON_MAX_RETRY_EXCEEDED:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_MAX_RETRY_EXCEEDED;
+ case QMI_OMA_SESSION_FAILED_REASON_SESSION_CANCELLED:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_SESSION_CANCELLED;
+ default:
+ return MM_OMA_SESSION_STATE_FAILED_REASON_UNKNOWN;
+ }
+}
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index 63b05311..ff2196cd 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -95,6 +95,15 @@ MMSmsState mm_sms_state_from_qmi_message_tag (QmiWmsMessageTagType tag);
QmiWdsAuthentication mm_bearer_allowed_auth_to_qmi_authentication (MMBearerAllowedAuth auth);
/*****************************************************************************/
+/* QMI/OMA to MM translations */
+
+MMOmaSessionType mm_oma_session_type_from_qmi_oma_session_type (QmiOmaSessionType qmi_session_type);
+
+MMOmaSessionState mm_oma_session_state_from_qmi_oma_session_state (QmiOmaSessionState qmi_session_state);
+
+MMOmaSessionStateFailedReason mm_oma_session_state_failed_reason_from_qmi_oma_session_failed_reason (QmiOmaSessionFailedReason qmi_session_failed_reason);
+
+/*****************************************************************************/
/* Utility to gather current capabilities from various sources */
typedef struct {