diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-11-04 23:04:37 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2018-11-07 10:20:15 +0100 |
commit | aa5e4ee5666c9f22b71a0bbbed7475b665eab85b (patch) | |
tree | 1ef089de6d4e6a32b516e15d334ab908a351f08b | |
parent | 3eeaa4248b98e1c3265caa5efca0db00a00e8a56 (diff) | |
download | libmbim-aa5e4ee5666c9f22b71a0bbbed7475b665eab85b.tar.gz |
libmbim-glib,proxy: also track standard servicesaleksander/proxy-notifications
The assumption that we could totally ignore enabling/disabling
standard services seems to be wrong, as not all devices follow that
logic. Looks like some do expect the FULL list of service/cids to
subscribe to on every request, and we are not specifying the standard
services, we would totally be losing the notifications they emit.
So, track the full default list of CIDs of all standard services that
emit notifications, and assume that all new clients have that list
enabled by default. At device level we will NEVER disable the standard
services, but clients may do so. This means that the list of
service/cids that we pass down to the device must ALWAYS include all
cids from all standard services.
Fixes: 0073cbed59a270e1a8f18f591d31cbaf64a995ae
-rw-r--r-- | src/libmbim-glib/mbim-proxy-helpers.c | 130 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-proxy-helpers.h | 4 | ||||
-rw-r--r-- | src/libmbim-glib/mbim-proxy.c | 45 |
3 files changed, 148 insertions, 31 deletions
diff --git a/src/libmbim-glib/mbim-proxy-helpers.c b/src/libmbim-glib/mbim-proxy-helpers.c index c53f6a5..59aa455 100644 --- a/src/libmbim-glib/mbim-proxy-helpers.c +++ b/src/libmbim-glib/mbim-proxy-helpers.c @@ -111,11 +111,11 @@ _mbim_proxy_helper_service_subscribe_list_debug (const MbimEventEntry * const *l g_free (str); if (entry->cids_count == 0) - g_debug ("[service %u] all CIDs enabled", (guint)i); + g_debug ("[service %u] No CIDs explicitly enabled", (guint)i); else { guint j; - g_debug ("[service %u] %u CIDs enabled", (guint)i, entry->cids_count);; + g_debug ("[service %u] %u CIDs enabled", (guint)i, entry->cids_count); for (j = 0; j < entry->cids_count; j++) { const gchar *cid_str; @@ -263,3 +263,129 @@ _mbim_proxy_helper_service_subscribe_list_merge (MbimEventEntry **in, return in; } + +/*****************************************************************************/ + +MbimEventEntry ** +_mbim_proxy_helper_service_subscribe_list_dup (MbimEventEntry **in, + gsize in_size, + gsize *out_size) +{ + MbimEventEntry **out; + guint i; + + g_assert (out_size != NULL); + + out = g_new0 (MbimEventEntry *, in_size + 1); + for (i = 0; i < in_size; i++) { + MbimEventEntry *entry_in; + MbimEventEntry *entry_out; + + entry_in = in[i]; + entry_out = g_new (MbimEventEntry, 1); + memcpy (&entry_out->device_service_id, &entry_in->device_service_id, sizeof (MbimUuid)); + entry_out->cids_count = entry_in->cids_count; + entry_out->cids = g_new (guint32, entry_out->cids_count); + memcpy (entry_out->cids, entry_in->cids, sizeof (guint32) * entry_out->cids_count); + out[i] = entry_out; + } + + *out_size = in_size; + return out; +} + +/*****************************************************************************/ + +MbimEventEntry ** +_mbim_proxy_helper_service_subscribe_list_new_standard (gsize *out_size) +{ + MbimEventEntry **out; + guint i = 0; + MbimEventEntry *entry; + + g_assert (out_size != NULL); + +#define STANDARD_SERVICES_LIST_SIZE 5 + out = g_new0 (MbimEventEntry *, STANDARD_SERVICES_LIST_SIZE + 1); + + /* Basic connect service */ + { + static const guint32 notify_cids[] = { + MBIM_CID_BASIC_CONNECT_SUBSCRIBER_READY_STATUS, + MBIM_CID_BASIC_CONNECT_RADIO_STATE, + MBIM_CID_BASIC_CONNECT_PREFERRED_PROVIDERS, + MBIM_CID_BASIC_CONNECT_REGISTER_STATE, + MBIM_CID_BASIC_CONNECT_PACKET_SERVICE, + MBIM_CID_BASIC_CONNECT_SIGNAL_STATE, + MBIM_CID_BASIC_CONNECT_CONNECT, + MBIM_CID_BASIC_CONNECT_PROVISIONED_CONTEXTS, + MBIM_CID_BASIC_CONNECT_IP_CONFIGURATION, + MBIM_CID_BASIC_CONNECT_EMERGENCY_MODE, + MBIM_CID_BASIC_CONNECT_MULTICARRIER_PROVIDERS, + }; + + entry = g_new (MbimEventEntry, 1); + memcpy (&entry->device_service_id, mbim_uuid_from_service (MBIM_SERVICE_BASIC_CONNECT), sizeof (MbimUuid)); + entry->cids_count = G_N_ELEMENTS (notify_cids); + entry->cids = g_memdup (notify_cids, sizeof (guint32) * entry->cids_count); + out[i++] = entry; + } + + /* SMS service */ + { + static const guint32 notify_cids[] = { + MBIM_CID_SMS_CONFIGURATION, + MBIM_CID_SMS_READ, + MBIM_CID_SMS_MESSAGE_STORE_STATUS, + }; + + entry = g_new (MbimEventEntry, 1); + memcpy (&entry->device_service_id, mbim_uuid_from_service (MBIM_SERVICE_SMS), sizeof (MbimUuid)); + entry->cids_count = G_N_ELEMENTS (notify_cids); + entry->cids = g_memdup (notify_cids, sizeof (guint32) * entry->cids_count); + out[i++] = entry; + } + + /* USSD service */ + { + static const guint32 notify_cids[] = { + MBIM_CID_USSD, + }; + + entry = g_new (MbimEventEntry, 1); + memcpy (&entry->device_service_id, mbim_uuid_from_service (MBIM_SERVICE_USSD), sizeof (MbimUuid)); + entry->cids_count = G_N_ELEMENTS (notify_cids); + entry->cids = g_memdup (notify_cids, sizeof (guint32) * entry->cids_count); + out[i++] = entry; + } + + /* Phonebook service */ + { + static const guint32 notify_cids[] = { + MBIM_CID_PHONEBOOK_CONFIGURATION, + }; + + entry = g_new (MbimEventEntry, 1); + memcpy (&entry->device_service_id, mbim_uuid_from_service (MBIM_SERVICE_PHONEBOOK), sizeof (MbimUuid)); + entry->cids_count = G_N_ELEMENTS (notify_cids); + entry->cids = g_memdup (notify_cids, sizeof (guint32) * entry->cids_count); + out[i++] = entry; + } + + /* STK service */ + { + static const guint32 notify_cids[] = { + MBIM_CID_STK_PAC, + }; + + entry = g_new (MbimEventEntry, 1); + memcpy (&entry->device_service_id, mbim_uuid_from_service (MBIM_SERVICE_STK), sizeof (MbimUuid)); + entry->cids_count = G_N_ELEMENTS (notify_cids); + entry->cids = g_memdup (notify_cids, sizeof (guint32) * entry->cids_count); + out[i++] = entry; + } + + g_assert_cmpuint (i, ==, STANDARD_SERVICES_LIST_SIZE); + *out_size = i; + return out; +} diff --git a/src/libmbim-glib/mbim-proxy-helpers.h b/src/libmbim-glib/mbim-proxy-helpers.h index 3c5f6a6..3abbe84 100644 --- a/src/libmbim-glib/mbim-proxy-helpers.h +++ b/src/libmbim-glib/mbim-proxy-helpers.h @@ -50,6 +50,10 @@ MbimEventEntry **_mbim_proxy_helper_service_subscribe_list_merge (MbimEve MbimEventEntry **merge, gsize merge_size, gsize *out_size); +MbimEventEntry **_mbim_proxy_helper_service_subscribe_list_dup (MbimEventEntry **original, + gsize original_size, + gsize *out_size); +MbimEventEntry **_mbim_proxy_helper_service_subscribe_list_new_standard (gsize *out_size); G_END_DECLS diff --git a/src/libmbim-glib/mbim-proxy.c b/src/libmbim-glib/mbim-proxy.c index 11b0529..06e65f2 100644 --- a/src/libmbim-glib/mbim-proxy.c +++ b/src/libmbim-glib/mbim-proxy.c @@ -274,18 +274,10 @@ client_indication_cb (MbimDevice *device, MbimMessage *message, Client *client) { - MbimService service; MbimEventEntry *entry; guint i; - /* standard service indications are always forwarded to clients */ - service = mbim_message_indicate_status_get_service (message); - if (service >= MBIM_SERVICE_BASIC_CONNECT && service <= MBIM_SERVICE_DSS) { - forward_indication (client, message); - return; - } - - /* if client didn't provide a custom subscribe list for non-standard services, we're done. */ + /* if client doesn't have a subscribe list, we're done. */ if (!client->mbim_event_entry_array) return; @@ -827,8 +819,8 @@ track_service_subscribe_list (Client *client, MbimMessage *message) { /* On each new request from the client, it should provide the FULL list of - * non-standard events it's subscribed to, so we can safely recreate the - * whole array each time. */ + * events it's subscribed to, so we can safely recreate the whole array each + * time. */ g_clear_pointer (&client->mbim_event_entry_array, mbim_event_entry_array_free); client->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_request_parse (message, &client->mbim_event_entry_array_size); @@ -1136,12 +1128,15 @@ incoming_cb (GSocketService *service, return; } - /* Create client */ client = g_slice_new0 (Client); client->self = self; client->ref_count = 1; client->connection = g_object_ref (connection); + + /* By default, a new client has all the standard services enabled for indications */ + client->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_list_new_standard (&client->mbim_event_entry_array_size); + client->connection_readable_source = g_socket_create_source (g_socket_connection_get_socket (client->connection), G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP, NULL); @@ -1239,12 +1234,11 @@ device_context_get (MbimDevice *device) ctx = g_object_get_qdata (G_OBJECT (device), device_context_quark); if (!ctx) { ctx = g_slice_new0 (DeviceContext); - /* By default, we assume we have all default services enabled - * (the default in the MBIM protocol). We also assume we cannot - * disable the default services in any way, as the protocol does - * not support that. We don't track the default services in the - * merged list, because those are implicit. */ - ctx->mbim_event_entry_array = NULL; + ctx->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_list_new_standard (&ctx->mbim_event_entry_array_size); + + g_debug ("Initial device subscribe list..."); + _mbim_proxy_helper_service_subscribe_list_debug ((const MbimEventEntry * const *)ctx->mbim_event_entry_array, ctx->mbim_event_entry_array_size); + g_object_set_qdata_full (G_OBJECT (device), device_context_quark, ctx, (GDestroyNotify)device_context_free); } @@ -1266,15 +1260,8 @@ merge_client_service_subscribe_lists (MbimProxy *self, g_assert (out_size != NULL); - /* NOTE! the list_merge() command will IGNORE all basic services when building - * the merged list. If any client tries to subscribe to any of those, we'll track - * them in the client-specific lists, but NOT in the device-merged list, as - * there is no point in doing so. */ - /* Add previous global list */ - updated = _mbim_proxy_helper_service_subscribe_list_merge (NULL, 0, - ctx->mbim_event_entry_array, ctx->mbim_event_entry_array_size, - &updated_size); + updated = _mbim_proxy_helper_service_subscribe_list_dup (ctx->mbim_event_entry_array, ctx->mbim_event_entry_array_size, &updated_size); /* Lookup all clients with this device */ for (l = self->priv->clients; l; l = g_list_next (l)) { @@ -1300,7 +1287,7 @@ merge_client_service_subscribe_lists (MbimProxy *self, return NULL; } - /* Lists are different, updated stored one */ + /* Lists are different, update stored one */ g_clear_pointer (&ctx->mbim_event_entry_array, mbim_event_entry_array_free); ctx->mbim_event_entry_array = updated; ctx->mbim_event_entry_array_size = updated_size; @@ -1334,13 +1321,13 @@ reset_client_service_subscribe_lists (MbimProxy *self, if (client->device == device) { g_clear_pointer (&client->mbim_event_entry_array, mbim_event_entry_array_free); - client->mbim_event_entry_array_size = 0; + client->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_list_new_standard (&client->mbim_event_entry_array_size); } } /* And reset the device-specific merged list */ g_clear_pointer (&ctx->mbim_event_entry_array, mbim_event_entry_array_free); - ctx->mbim_event_entry_array_size = 0; + ctx->mbim_event_entry_array = _mbim_proxy_helper_service_subscribe_list_new_standard (&ctx->mbim_event_entry_array_size); } static void |