[PATCH] broadband-modem-mbim: handle network initiated disconnect

Aleksander Morgado aleksander at aleksander.es
Thu Feb 20 01:27:43 PST 2014


On 20/02/14 06:44, Ben Chan wrote:
> Observing registration updates via the MBIM_CID_REGISTER_STATE
> notification alone is not always sufficient to detect if the modem is
> disconnected from the network. In case of a network-initiated
> disconnect, it is possible that the modem is disconnected from the
> network but remains registered.
> 
> This patch modifies MMBroadbandModemMbim to subscribe to the
> MBIM_CID_CONNECT notification. Upon receiving a notification of a
> deactivated session ID, the corresponding bearer is reported as
> disconnected.
> ---

Nice one!

Pushed, thanks.

> Here is an example debug trace:
> 
> 2014-02-19T17:52:58.319918-08:00 localhost ModemManager[4524]: <debug> Connected bearer '/org/freedesktop/ModemManager1/Bearer/1'
> 2014-02-19T17:52:58.319925-08:00 localhost ModemManager[4524]: <info>  Modem /org/freedesktop/ModemManager1/Modem/1: state changed (connecting -> connected)
> 2014-02-19T17:52:58.319934-08:00 localhost ModemManager[4524]: <info>  Simple connect state (8/8): All done
> 2014-02-19T17:53:33.310774-08:00 localhost ModemManager[4524]: <debug> Signal quality value not updated in 60s, marking as not being recent
> 
> ...
> 
> 2014-02-19T17:54:30.156200-08:00 localhost ModemManager[4524]: [/dev/cdc-wdm0] Received message...
>>>>>>> RAW:
>>>>>>>   length = 80
>>>>>>>   data   = 07:00:00:80:50:00:00:00:00:00:00:00:01:00:00:00:00:00:00:00:A2:89:CC:33:BC:BB:8B:4F:B6:B0:13:3E:C2:AA:E6:DF:0C:00:00:00:24:00:00:00:00:00:00:00:03:00:00:00:00:00:00:00:00:00:00:00:7E:5E:2A:7E:4E:6F:72:72:73:6B:65:6E:7E:5E:2A:7E:00:00:00:00
> 2014-02-19T17:54:30.156268-08:00 localhost ModemManager[4524]: [/dev/cdc-wdm0] Received message (translated)...
>>>>>>> Header:
>>>>>>>   length      = 80
>>>>>>>   type        = indicate-status (0x80000007)
>>>>>>>   transaction = 0
>>>>>>> Fragment header:
>>>>>>>   total   = 1
>>>>>>>   current = 0
>>>>>>> Contents:
>>>>>>>   service = 'basic-connect' (a289cc33-bcbb-8b4f-b6b0-133ec2aae6df)
>>>>>>>   cid     = 'connect' (0x0000000c)
> 2014-02-19T17:54:30.156376-08:00 localhost ModemManager[4524]: <debug> Received notification (service 'basic-connect', command 'connect')
> 2014-02-19T17:54:30.156472-08:00 localhost ModemManager[4524]: <debug> Session ID '0' was deactivated.
> 2014-02-19T17:54:30.156495-08:00 localhost ModemManager[4524]: <debug> Bearer '/org/freedesktop/ModemManager1/Bearer/1' was disconnected.
> 2014-02-19T17:54:30.156653-08:00 localhost ModemManager[4524]: <info>  Modem /org/freedesktop/ModemManager1/Modem/1: state changed (connected -> registered)
> 
> 
>  src/mm-broadband-modem-mbim.c | 85 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 79 insertions(+), 6 deletions(-)
> 
> diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c
> index 714cb70..64f1d7c 100644
> --- a/src/mm-broadband-modem-mbim.c
> +++ b/src/mm-broadband-modem-mbim.c
> @@ -52,6 +52,7 @@ typedef enum {
>      PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY       = 1 << 0,
>      PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES = 1 << 1,
>      PROCESS_NOTIFICATION_FLAG_SMS_READ             = 1 << 2,
> +    PROCESS_NOTIFICATION_FLAG_CONNECT              = 1 << 3,
>  } ProcessNotificationFlag;
>  
>  struct _MMBroadbandModemMbimPrivate {
> @@ -1607,6 +1608,65 @@ basic_connect_notification_register_state (MMBroadbandModemMbim *self,
>      }
>  }
>  
> +typedef struct {
> +    guint32 session_id;
> +} ReportDisconnectedStatusContext;
> +
> +static void
> +bearer_list_report_disconnected_status (MMBearer *bearer,
> +                                        gpointer user_data)
> +{
> +    ReportDisconnectedStatusContext *ctx = user_data;
> +
> +    if (MM_IS_BEARER_MBIM (bearer) &&
> +        mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (bearer)) == ctx->session_id) {
> +        mm_dbg ("Bearer '%s' was disconnected.", mm_bearer_get_path (bearer));
> +        mm_bearer_report_connection_status (bearer, MM_BEARER_CONNECTION_STATUS_DISCONNECTED);
> +    }
> +}
> +
> +static void
> +basic_connect_notification_connect (MMBroadbandModemMbim *self,
> +                                    MbimMessage *notification)
> +{
> +    guint32 session_id;
> +    MbimActivationState activation_state;
> +    const MbimUuid *context_type;
> +    MMBearerList *bearer_list;
> +
> +    if (!mbim_message_connect_notification_parse (
> +            notification,
> +            &session_id,
> +            &activation_state,
> +            NULL, /* voice_call_state */
> +            NULL, /* ip_type */
> +            &context_type,
> +            NULL, /* nw_error */
> +            NULL)) {
> +        return;
> +    }
> +
> +    g_object_get (self,
> +                  MM_IFACE_MODEM_BEARER_LIST, &bearer_list,
> +                  NULL);
> +
> +    if (!bearer_list)
> +        return;
> +
> +    if (mbim_uuid_to_context_type (context_type) == MBIM_CONTEXT_TYPE_INTERNET &&
> +        activation_state == MBIM_ACTIVATION_STATE_DEACTIVATED) {
> +      ReportDisconnectedStatusContext ctx;
> +
> +      mm_dbg ("Session ID '%u' was deactivated.", session_id);
> +      ctx.session_id = session_id;
> +      mm_bearer_list_foreach (bearer_list,
> +                              (MMBearerListForeachFunc)bearer_list_report_disconnected_status,
> +                              &ctx);
> +    }
> +
> +    g_object_unref (bearer_list);
> +}
> +
>  static void add_sms_part (MMBroadbandModemMbim *self,
>                            const MbimSmsPduReadRecord *pdu);
>  
> @@ -1650,6 +1710,10 @@ basic_connect_notification (MMBroadbandModemMbim *self,
>          if (self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES)
>              basic_connect_notification_register_state (self, notification);
>          break;
> +    case MBIM_CID_BASIC_CONNECT_CONNECT:
> +        if (self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_CONNECT)
> +            basic_connect_notification_connect (self, notification);
> +        break;
>      default:
>          /* Ignore */
>          break;
> @@ -1808,10 +1872,11 @@ common_setup_cleanup_unsolicited_events (MMBroadbandModemMbim *self,
>                                          user_data,
>                                          common_setup_cleanup_unsolicited_events);
>  
> -    mm_dbg ("Supported notifications: signal (%s), registration (%s), sms (%s)",
> +    mm_dbg ("Supported notifications: signal (%s), registration (%s), sms (%s), connect (%s)",
>              self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
>              self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
> -            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no");
> +            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
> +            self->priv->setup_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no");
>  
>      if (setup) {
>          /* Don't re-enable it if already there */
> @@ -1852,6 +1917,7 @@ cleanup_unsolicited_events_3gpp (MMIfaceModem3gpp *self,
>                                   gpointer user_data)
>  {
>      MM_BROADBAND_MODEM_MBIM (self)->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY;
> +    MM_BROADBAND_MODEM_MBIM (self)->priv->setup_flags &= ~PROCESS_NOTIFICATION_FLAG_CONNECT;
>      common_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM_MBIM (self), FALSE, callback, user_data);
>  }
>  
> @@ -1861,6 +1927,7 @@ setup_unsolicited_events_3gpp (MMIfaceModem3gpp *self,
>                                 gpointer user_data)
>  {
>      MM_BROADBAND_MODEM_MBIM (self)->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY;
> +    MM_BROADBAND_MODEM_MBIM (self)->priv->setup_flags |= PROCESS_NOTIFICATION_FLAG_CONNECT;
>      common_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM_MBIM (self), TRUE, callback, user_data);
>  }
>  
> @@ -1938,24 +2005,28 @@ common_enable_disable_unsolicited_events (MMBroadbandModemMbim *self,
>                                          user_data,
>                                          common_enable_disable_unsolicited_events);
>  
> -    mm_dbg ("Enabled notifications: signal (%s), registration (%s), sms (%s)",
> +    mm_dbg ("Enabled notifications: signal (%s), registration (%s), sms (%s), connect (%s)",
>              self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ? "yes" : "no",
>              self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ? "yes" : "no",
> -            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no");
> +            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SMS_READ ? "yes" : "no",
> +            self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT ? "yes" : "no");
>  
>      entries = g_new0 (MbimEventEntry *, 3);
>  
>      /* Basic connect service */
>      if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY ||
> -        self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES) {
> +        self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES ||
> +        self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT) {
>          entries[n_entries] = g_new (MbimEventEntry, 1);
>          memcpy (&(entries[n_entries]->device_service_id), MBIM_UUID_BASIC_CONNECT, sizeof (MbimUuid));
>          entries[n_entries]->cids_count = 0;
> -        entries[n_entries]->cids = g_new0 (guint32, 2);
> +        entries[n_entries]->cids = g_new0 (guint32, 3);
>          if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY)
>              entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_SIGNAL_STATE;
>          if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_REGISTRATION_UPDATES)
>              entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_REGISTER_STATE;
> +        if (self->priv->enable_flags & PROCESS_NOTIFICATION_FLAG_CONNECT)
> +            entries[n_entries]->cids[entries[n_entries]->cids_count++] = MBIM_CID_BASIC_CONNECT_CONNECT;
>          n_entries++;
>      }
>  
> @@ -2037,6 +2108,7 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
>                                         gpointer user_data)
>  {
>      MM_BROADBAND_MODEM_MBIM (self)->priv->enable_flags &= ~PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY;
> +    MM_BROADBAND_MODEM_MBIM (self)->priv->enable_flags &= ~PROCESS_NOTIFICATION_FLAG_CONNECT;
>      common_enable_disable_unsolicited_events (MM_BROADBAND_MODEM_MBIM (self), callback, user_data);
>  }
>  
> @@ -2046,6 +2118,7 @@ modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self,
>                                        gpointer user_data)
>  {
>      MM_BROADBAND_MODEM_MBIM (self)->priv->enable_flags |= PROCESS_NOTIFICATION_FLAG_SIGNAL_QUALITY;
> +    MM_BROADBAND_MODEM_MBIM (self)->priv->enable_flags |= PROCESS_NOTIFICATION_FLAG_CONNECT;
>      common_enable_disable_unsolicited_events (MM_BROADBAND_MODEM_MBIM (self), callback, user_data);
>  }
>  
> 


-- 
Aleksander
https://aleksander.es


More information about the ModemManager-devel mailing list