summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2014-08-02 13:53:28 +0200
committerAleksander Morgado <aleksander@aleksander.es>2014-08-02 14:04:31 +0200
commit9ad75d9a0c1e8fd1afedaaa9279b96154b3d59ad (patch)
treeebc1359cf2fed8cf304e82eeb85726dada5f6bb1
parent1f828309808150f8ebc0d069263564888fc6826f (diff)
libmbim-glib,proxy: don't re-configure global indications if merged unchanged
Currently we're defaulting to enable the standard services list; so whenever clients want to re-configure their standard services list (e.g. just enabling some of the indications), we just end up having the full standard list again. So, avoid multiple re-configures in the device, just compare and only send the new setup to the device if the global list changes.
-rw-r--r--src/libmbim-glib/mbim-proxy.c110
1 files changed, 76 insertions, 34 deletions
diff --git a/src/libmbim-glib/mbim-proxy.c b/src/libmbim-glib/mbim-proxy.c
index 4bf4eaa..7677cc6 100644
--- a/src/libmbim-glib/mbim-proxy.c
+++ b/src/libmbim-glib/mbim-proxy.c
@@ -64,6 +64,10 @@ struct _MbimProxyPrivate {
/* Devices */
GList *devices;
GList *opening_devices;
+
+ /* Global events array */
+ MbimEventEntry **mbim_event_entry_array;
+ gsize mbim_event_entry_array_size;
};
static void track_device (MbimProxy *self, MbimDevice *device);
@@ -735,12 +739,15 @@ merge_client_service_subscribe_lists (MbimProxy *self,
gsize *out_size)
{
GList *l;
- MbimEventEntry **out = NULL;
+ MbimEventEntry **updated;
+ gsize updated_size = 0;
g_assert (out_size != NULL);
- *out_size = 0;
- out = _mbim_proxy_helper_service_subscribe_standard_list_new (out_size);
+ /* Add previous global list */
+ updated = _mbim_proxy_helper_service_subscribe_list_merge (NULL, 0,
+ self->priv->mbim_event_entry_array, self->priv->mbim_event_entry_array_size,
+ &updated_size);
for (l = self->priv->clients; l; l = g_list_next (l)) {
Client *client;
@@ -749,43 +756,29 @@ merge_client_service_subscribe_lists (MbimProxy *self,
if (!client->mbim_event_entry_array)
continue;
- out = _mbim_proxy_helper_service_subscribe_list_merge (out, *out_size,
- client->mbim_event_entry_array, client->mbim_event_entry_array_size,
- out_size);
+ /* Add per-client list */
+ updated = _mbim_proxy_helper_service_subscribe_list_merge (updated, updated_size,
+ client->mbim_event_entry_array, client->mbim_event_entry_array_size,
+ &updated_size);
}
if (mbim_utils_get_traces_enabled ()) {
g_debug ("Merged service subscribe list built");
- _mbim_proxy_helper_service_subscribe_list_debug ((const MbimEventEntry * const *)out, *out_size);
+ _mbim_proxy_helper_service_subscribe_list_debug ((const MbimEventEntry * const *)updated, updated_size);
}
- return out;
+ *out_size = updated_size;
+ return updated;
}
static void
-device_service_subscribe_list_set_ready (MbimDevice *device,
- GAsyncResult *res,
- Request *request)
+device_service_subscribe_list_set_complete (Request *request,
+ MbimStatusError status)
{
- MbimMessage *tmp_response;
- MbimStatusError error_status_code;
struct command_done_message *command_done;
- GError *error = NULL;
guint32 raw_len;
const guint8 *raw_data;
- tmp_response = mbim_device_command_finish (device, res, &error);
- if (!tmp_response) {
- g_debug ("sending request to device failed: %s", error->message);
- g_error_free (error);
- /* Don't disconnect client, just let the request timeout in its side */
- request_complete_and_free (request);
- return;
- }
-
- error_status_code = GUINT32_FROM_LE (((struct full_message *)(tmp_response->data))->message.command_done.status_code);
- mbim_message_unref (tmp_response);
-
/* The raw message data to send back as response to client */
raw_data = mbim_message_command_get_raw_information_buffer (request->message, &raw_len);
@@ -798,32 +791,73 @@ device_service_subscribe_list_set_ready (MbimDevice *device,
command_done->fragment_header.current = 0;
memcpy (command_done->service_id, MBIM_UUID_BASIC_CONNECT, sizeof (MbimUuid));
command_done->command_id = GUINT32_TO_LE (MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBE_LIST);
- command_done->status_code = GUINT32_TO_LE (error_status_code);
+ command_done->status_code = GUINT32_TO_LE (status);
command_done->buffer_length = GUINT32_TO_LE (raw_len);
memcpy (&command_done->buffer[0], raw_data, raw_len);
request_complete_and_free (request);
}
+static void
+device_service_subscribe_list_set_ready (MbimDevice *device,
+ GAsyncResult *res,
+ Request *request)
+{
+ MbimMessage *tmp_response;
+ MbimStatusError error_status_code;
+ GError *error = NULL;
+
+ tmp_response = mbim_device_command_finish (device, res, &error);
+ if (!tmp_response) {
+ g_debug ("sending request to device failed: %s", error->message);
+ g_error_free (error);
+ /* Don't disconnect client, just let the request timeout in its side */
+ request_complete_and_free (request);
+ return;
+ }
+
+ error_status_code = GUINT32_FROM_LE (((struct full_message *)(tmp_response->data))->message.command_done.status_code);
+ mbim_message_unref (tmp_response);
+
+ device_service_subscribe_list_set_complete (request, error_status_code);
+}
+
static gboolean
process_device_service_subscribe_list (MbimProxy *self,
Client *client,
MbimMessage *message)
{
- MbimEventEntry **events;
- gsize events_size = 0;
+ MbimEventEntry **updated;
+ gsize updated_size = 0;
Request *request;
+ /* create request holder */
+ request = request_new (self, client, message);
+
/* trace the service subscribe list for the client */
track_service_subscribe_list (client, message);
/* merge all service subscribe list for all clients to set on device */
- events = merge_client_service_subscribe_lists (self, &events_size);
+ updated = merge_client_service_subscribe_lists (self, &updated_size);
+
+ /* If lists are equal, ignore re-setting them up */
+ if (_mbim_proxy_helper_service_subscribe_list_cmp (
+ (const MbimEventEntry *const *)updated, updated_size,
+ (const MbimEventEntry *const *)self->priv->mbim_event_entry_array, self->priv->mbim_event_entry_array_size)) {
+ /* Complete directly without error */
+ mbim_event_entry_array_free (updated);
+ device_service_subscribe_list_set_complete (request, MBIM_STATUS_ERROR_NONE);
+ return TRUE;
+ }
- /* create request holder */
- request = request_new (self, client, message);
+ /* Lists are different, updated stored one */
+ mbim_event_entry_array_free (self->priv->mbim_event_entry_array);
+ self->priv->mbim_event_entry_array = updated;
+ self->priv->mbim_event_entry_array_size = updated_size;
- message = mbim_message_device_service_subscribe_list_set_new (events_size, (const MbimEventEntry *const *)events, NULL);
+ message = mbim_message_device_service_subscribe_list_set_new (self->priv->mbim_event_entry_array_size,
+ (const MbimEventEntry *const *)self->priv->mbim_event_entry_array,
+ NULL);
mbim_message_set_transaction_id (message, mbim_device_get_next_transaction_id (client->device));
mbim_device_command (client->device,
@@ -833,7 +867,6 @@ process_device_service_subscribe_list (MbimProxy *self,
(GAsyncReadyCallback)device_service_subscribe_list_set_ready,
request);
- mbim_event_entry_array_free (events);
mbim_message_unref (message);
return TRUE;
}
@@ -1203,6 +1236,9 @@ mbim_proxy_init (MbimProxy *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
MBIM_TYPE_PROXY,
MbimProxyPrivate);
+
+ /* By default, we assume we have all default services enabled */
+ self->priv->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_standard_list_new (&self->priv->mbim_event_entry_array_size);
}
static void
@@ -1252,6 +1288,12 @@ dispose (GObject *object)
g_debug ("UNIX socket service at '%s' stopped", MBIM_PROXY_SOCKET_PATH);
}
+ if (priv->mbim_event_entry_array) {
+ mbim_event_entry_array_free (priv->mbim_event_entry_array);
+ priv->mbim_event_entry_array = NULL;
+ priv->mbim_event_entry_array_size = 0;
+ }
+
G_OBJECT_CLASS (mbim_proxy_parent_class)->dispose (object);
}