summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-11-04 23:04:37 +0100
committerAleksander Morgado <aleksander@aleksander.es>2018-11-07 10:20:15 +0100
commitaa5e4ee5666c9f22b71a0bbbed7475b665eab85b (patch)
tree1ef089de6d4e6a32b516e15d334ab908a351f08b
parent3eeaa4248b98e1c3265caa5efca0db00a00e8a56 (diff)
downloadlibmbim-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.c130
-rw-r--r--src/libmbim-glib/mbim-proxy-helpers.h4
-rw-r--r--src/libmbim-glib/mbim-proxy.c45
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