aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-04-14 12:39:45 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-04-17 15:19:41 +0200
commit032911ec20f984b306ba8fb6d45f243c81437fd2 (patch)
treeb54d020df9cc8a4b2cd9ed08f98e053e0daa4fda
parent4609f708b8321dbd73af52a7958d46b13844e343 (diff)
bearer-mbim: gather a unique session id in the [0,255] range
-rw-r--r--src/mm-bearer-mbim.c86
-rw-r--r--src/mm-bearer-mbim.h7
-rw-r--r--src/mm-broadband-modem-mbim.c69
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);