diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-14 12:39:45 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-17 15:19:41 +0200 |
commit | 032911ec20f984b306ba8fb6d45f243c81437fd2 (patch) | |
tree | b54d020df9cc8a4b2cd9ed08f98e053e0daa4fda | |
parent | 4609f708b8321dbd73af52a7958d46b13844e343 (diff) |
bearer-mbim: gather a unique session id in the [0,255] range
-rw-r--r-- | src/mm-bearer-mbim.c | 86 | ||||
-rw-r--r-- | src/mm-bearer-mbim.h | 7 | ||||
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 69 |
3 files changed, 150 insertions, 12 deletions
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c index bb24db86..9d0fc76e 100644 --- a/src/mm-bearer-mbim.c +++ b/src/mm-bearer-mbim.c @@ -31,10 +31,20 @@ #include "mm-bearer-mbim.h" #include "mm-log.h" -G_DEFINE_TYPE (MMBearerMbim, mm_bearer_mbim, MM_TYPE_BEARER); +G_DEFINE_TYPE (MMBearerMbim, mm_bearer_mbim, MM_TYPE_BEARER) + +enum { + PROP_0, + PROP_SESSION_ID, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; struct _MMBearerMbimPrivate { + /* The session ID for this bearer */ guint32 session_id; + MMPort *data; }; @@ -353,8 +363,7 @@ connect_context_step (ConnectContext *ctx) mm_dbg ("Launching connection with APN '%s'...", apn); message = (mbim_message_connect_set_new ( - /* use bearer ptr value as session ID */ - (guint32)GPOINTER_TO_UINT (ctx->self), + ctx->self->priv->session_id, MBIM_ACTIVATION_COMMAND_ACTIVATE, apn ? apn : "", user ? user : "", @@ -388,10 +397,6 @@ connect_context_step (ConnectContext *ctx) g_assert (ctx->self->priv->data == NULL); ctx->self->priv->data = g_object_ref (ctx->data); - /* Keep the session id */ - g_assert (ctx->self->priv->session_id == 0); - ctx->self->priv->session_id = (guint32)GPOINTER_TO_UINT (ctx->self); - /* Set operation result */ g_simple_async_result_set_op_res_gpointer ( ctx->result, @@ -442,9 +447,20 @@ _connect (MMBearer *self, /*****************************************************************************/ +guint32 +mm_bearer_mbim_get_session_id (MMBearerMbim *self) +{ + g_return_val_if_fail (MM_IS_BEARER_MBIM (self), 0); + + return self->priv->session_id; +} + +/*****************************************************************************/ + MMBearer * mm_bearer_mbim_new (MMBroadbandModemMbim *modem, - MMBearerProperties *config) + MMBearerProperties *config, + guint32 session_id) { MMBearer *bearer; @@ -452,8 +468,9 @@ mm_bearer_mbim_new (MMBroadbandModemMbim *modem, * and that means that the object is not async-initable, so we just use * g_object_new() here */ bearer = g_object_new (MM_TYPE_BEARER_MBIM, - MM_BEARER_MODEM, modem, - MM_BEARER_CONFIG, config, + MM_BEARER_MODEM, modem, + MM_BEARER_CONFIG, config, + MM_BEARER_MBIM_SESSION_ID, (guint)session_id, NULL); /* Only export valid bearers */ @@ -463,6 +480,43 @@ mm_bearer_mbim_new (MMBroadbandModemMbim *modem, } static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MMBearerMbim *self = MM_BEARER_MBIM (object); + + switch (prop_id) { + case PROP_SESSION_ID: + self->priv->session_id = g_value_get_uint (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MMBearerMbim *self = MM_BEARER_MBIM (object); + + switch (prop_id) { + case PROP_SESSION_ID: + g_value_set_uint (value, self->priv->session_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + + +static void mm_bearer_mbim_init (MMBearerMbim *self) { /* Initialize private data */ @@ -491,7 +545,19 @@ mm_bearer_mbim_class_init (MMBearerMbimClass *klass) /* Virtual methods */ object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; bearer_class->connect = _connect; bearer_class->connect_finish = connect_finish; + + properties[PROP_SESSION_ID] = + g_param_spec_uint (MM_BEARER_MBIM_SESSION_ID, + "Session ID", + "Session ID to use with this bearer", + 0, + 255, + 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_SESSION_ID, properties[PROP_SESSION_ID]); } diff --git a/src/mm-bearer-mbim.h b/src/mm-bearer-mbim.h index 209f3bf8..c3e7f1fc 100644 --- a/src/mm-bearer-mbim.h +++ b/src/mm-bearer-mbim.h @@ -32,6 +32,8 @@ #define MM_IS_BEARER_MBIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BEARER_MBIM)) #define MM_BEARER_MBIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BEARER_MBIM, MMBearerMbimClass)) +#define MM_BEARER_MBIM_SESSION_ID "bearer-mbim-session-id" + typedef struct _MMBearerMbim MMBearerMbim; typedef struct _MMBearerMbimClass MMBearerMbimClass; typedef struct _MMBearerMbimPrivate MMBearerMbimPrivate; @@ -50,6 +52,9 @@ GType mm_bearer_mbim_get_type (void); /* MBIM bearer creation implementation. * NOTE it is *not* a broadband bearer, so not async-initable */ MMBearer *mm_bearer_mbim_new (MMBroadbandModemMbim *modem, - MMBearerProperties *config); + MMBearerProperties *config, + guint32 session_id); + +guint32 mm_bearer_mbim_get_session_id (MMBearerMbim *self); #endif /* MM_BEARER_MBIM_H */ diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 77014dfd..823528c5 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -31,6 +31,7 @@ #include "mm-errors-types.h" #include "mm-error-helpers.h" #include "mm-modem-helpers.h" +#include "mm-bearer-list.h" #include "mm-iface-modem.h" #include "mm-iface-modem-3gpp.h" @@ -990,6 +991,57 @@ modem_create_bearer_finish (MMIfaceModem *self, return g_object_ref (bearer); } +typedef struct { + guint32 session_id; + gboolean found; +} FindSessionId; + +static void +bearer_list_session_id_foreach (MMBearer *bearer, + gpointer user_data) +{ + FindSessionId *ctx = user_data; + + if (!ctx->found && + MM_IS_BEARER_MBIM (bearer) && + mm_bearer_mbim_get_session_id (MM_BEARER_MBIM (bearer)) == ctx->session_id) + ctx->found = TRUE; +} + +static gint +find_next_bearer_session_id (MMBroadbandModemMbim *self) +{ + MMBearerList *bearer_list; + guint i; + + g_object_get (self, + MM_IFACE_MODEM_BEARER_LIST, &bearer_list, + NULL); + + if (!bearer_list) + return 0; + + for (i = 0; i <= 255; i++) { + FindSessionId ctx; + + ctx.session_id = i; + ctx.found = FALSE; + + mm_bearer_list_foreach (bearer_list, + bearer_list_session_id_foreach, + &ctx); + + if (!ctx.found) { + g_object_unref (bearer_list); + return (gint)i; + } + } + + /* no valid session id found */ + g_object_unref (bearer_list); + return -1; +} + static void modem_create_bearer (MMIfaceModem *self, MMBearerProperties *properties, @@ -998,6 +1050,7 @@ modem_create_bearer (MMIfaceModem *self, { MMBearer *bearer; GSimpleAsyncResult *result; + gint session_id; /* Set a new ref to the bearer object as result */ result = g_simple_async_result_new (G_OBJECT (self), @@ -1005,10 +1058,24 @@ modem_create_bearer (MMIfaceModem *self, user_data, modem_create_bearer); + /* Find a new session ID */ + session_id = find_next_bearer_session_id (MM_BROADBAND_MODEM_MBIM (self)); + if (session_id < 0) { + g_simple_async_result_set_error ( + result, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Not enough session IDs"); + g_simple_async_result_complete_in_idle (result); + g_object_unref (result); + return; + } + /* We just create a MMBearerMbim */ mm_dbg ("Creating MBIM bearer in MBIM modem"); bearer = mm_bearer_mbim_new (MM_BROADBAND_MODEM_MBIM (self), - properties); + properties, + (guint)session_id); g_simple_async_result_set_op_res_gpointer (result, bearer, g_object_unref); g_simple_async_result_complete_in_idle (result); |