diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-06-19 12:23:47 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-08-21 13:26:08 +0000 |
commit | 8a364c4dfd910d5679b070b1f574539008028872 (patch) | |
tree | 61d09138b525799fcef488c1de31e1f55cd4ad6d /src/mm-port-mbim.c | |
parent | c0cc694c67d9e71f200fb23e20473cc9b31d9ec0 (diff) |
port-mbim: implement QMI client allocation logic
Diffstat (limited to 'src/mm-port-mbim.c')
-rw-r--r-- | src/mm-port-mbim.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/mm-port-mbim.c b/src/mm-port-mbim.c index 20a72dfc..c94a5163 100644 --- a/src/mm-port-mbim.c +++ b/src/mm-port-mbim.c @@ -35,11 +35,125 @@ struct _MMPortMbimPrivate { MbimDevice *mbim_device; #if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED QmiDevice *qmi_device; + GList *qmi_clients; #endif }; /*****************************************************************************/ +#if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED + +gboolean +mm_port_mbim_supports_qmi (MMPortMbim *self) +{ + return !!self->priv->qmi_device; +} + +QmiClient * +mm_port_mbim_peek_qmi_client (MMPortMbim *self, + QmiService service) +{ + GList *l; + + for (l = self->priv->qmi_clients; l; l = g_list_next (l)) { + QmiClient *qmi_client = QMI_CLIENT (l->data); + + if (qmi_client_get_service (qmi_client) == service) + return qmi_client; + } + + return NULL; +} + +QmiClient * +mm_port_mbim_get_qmi_client (MMPortMbim *self, + QmiService service) +{ + QmiClient *client; + + client = mm_port_mbim_peek_qmi_client (self, service); + return (client ? g_object_ref (client) : NULL); +} + +gboolean +mm_port_mbim_allocate_qmi_client_finish (MMPortMbim *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +allocate_client_ready (QmiDevice *qmi_device, + GAsyncResult *res, + GTask *task) +{ + MMPortMbim *self; + QmiClient *qmi_client; + GError *error = NULL; + + self = g_task_get_source_object (task); + qmi_client = qmi_device_allocate_client_finish (qmi_device, res, &error); + if (!qmi_client) { + g_prefix_error (&error, + "Couldn't create QMI client for service '%s': ", + qmi_service_get_string ((QmiService) GPOINTER_TO_INT (g_task_get_task_data (task)))); + g_task_return_error (task, error); + } else { + /* Store the client in our internal list */ + self->priv->qmi_clients = g_list_prepend (self->priv->qmi_clients, qmi_client); + g_task_return_boolean (task, TRUE); + } + g_object_unref (task); +} + +void +mm_port_mbim_allocate_qmi_client (MMPortMbim *self, + QmiService service, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (self, cancellable, callback, user_data); + + if (!mm_port_mbim_is_open (self)) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE, + "Port is closed"); + g_object_unref (task); + return; + } + + if (!mm_port_mbim_supports_qmi (self)) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, + "Port doesn't support QMI over MBIM"); + g_object_unref (task); + return; + } + + if (!!mm_port_mbim_peek_qmi_client (self, service)) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_EXISTS, + "Client for service '%s' already allocated", + qmi_service_get_string (service)); + g_object_unref (task); + return; + } + + g_task_set_task_data (task, GINT_TO_POINTER (service), NULL); + qmi_device_allocate_client (self->priv->qmi_device, + service, + QMI_CID_NONE, + 10, + cancellable, + (GAsyncReadyCallback)allocate_client_ready, + task); +} + +#endif + +/*****************************************************************************/ + gboolean mm_port_mbim_open_finish (MMPortMbim *self, GAsyncResult *res, @@ -356,6 +470,8 @@ dispose (GObject *object) MMPortMbim *self = MM_PORT_MBIM (object); #if defined WITH_QMI && QMI_MBIM_QMUX_SUPPORTED + g_list_free_full (self->priv->qmi_clients, g_object_unref); + self->priv->qmi_clients = NULL; g_clear_object (&self->priv->qmi_device); #endif |