diff mbox series

[v2,1/2] ofono: Correct conditional in 'cm_get_contexts_reply'.

Message ID 7a05bc1060f2aaba362f8198cdd4f1c7d2ff04e9.1739203086.git.gerickson@nuovations.com (mailing list archive)
State Accepted
Commit 28a7ce1595a188705b6fc8e613932a187ab266db
Headers show
Series ofono: Correct conditional in 'cm_get_contexts_reply'. | expand

Commit Message

Grant Erickson Feb. 10, 2025, 3:59 p.m. UTC
At the appropriate moment in the oFono plugin lifecycle, it gets and
evaluates contexts from a given Cellular modem. Depending on the
HNI/MCC+MNC and the network operator, there may be one or more such
contexts, each with a different type.

Within 'cm_get_contexts_reply', each received context is iterated on,
evaluating each for the type 'internet' by calling
'add_cm_context'. If the context is not of type 'internet',
'cm_get_contexts_reply' should continue to iterate until all contexts
are exhausted or a matching context is found.

The return semantics of 'add_cm_context' are '-ENOMEM' if memory could
not be allocated, '-EINVAL' if a context is *not* of the type
'internet'; otherwise zero ('0') if a context of type 'internet' was
found.

However, the conditional logic of 'cm_get_contexts_reply' prior to
this change was:

   while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) {
       const char *context_path;

       dbus_message_iter_recurse(&dict, &entry);
       dbus_message_iter_get_basic(&entry, &context_path);

       dbus_message_iter_next(&entry);
       dbus_message_iter_recurse(&entry, &value);

       if (add_cm_context(modem, context_path, &value))
           break;

       dbus_message_iter_next(&dict);
   }

So, assuming a set of contexts from, for example Verizon, such as '[ {
vzwims, ims }, { vzwinternet, internet }, { vzwapp, wap } ]', then the
above logic will encounter '{ vzwims, ims }' on the first iteration,
evaluate that it is not of type 'internet', return '-EINVAL' from
'add_cm_context', that will satisfy the conditional and trigger the
'break' from the 'while' loop and context iteration will
terminate. This then misses the second, desired '{ vzwinternet,
internet }' context and the Cellular interface will never come up.

By changing the conditional logic to match the return semantics of
'add_cm_context' the code now works correctly, regardless of the number
of contexts iterated on or their order.

Fixes: 4b238d8590942 ("ofono: Implementation of simultaneous APNS")
---
 plugins/ofono.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/plugins/ofono.c b/plugins/ofono.c
index 062905c8a3a6..6b89df3af0ae 100644
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -1415,7 +1415,11 @@  static void cm_get_contexts_reply(DBusPendingCall *call, void *user_data)
 		dbus_message_iter_next(&entry);
 		dbus_message_iter_recurse(&entry, &value);
 
-		if (add_cm_context(modem, context_path, &value))
+		/*
+		 * If a context of type 'internet' is found, stop iterating;
+		 * we have the desired context.
+		 */
+		if (add_cm_context(modem, context_path, &value) == 0)
 			break;
 
 		dbus_message_iter_next(&dict);