aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-iface-modem-simple.c400
1 files changed, 41 insertions, 359 deletions
diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c
index ef66c88b..de74b529 100644
--- a/src/mm-iface-modem-simple.c
+++ b/src/mm-iface-modem-simple.c
@@ -25,8 +25,6 @@
#include "mm-iface-modem-3gpp.h"
#include "mm-iface-modem-cdma.h"
#include "mm-iface-modem-simple.h"
-#include "mm-bearer-3gpp.h"
-#include "mm-bearer-cdma.h"
#include "mm-log.h"
/*****************************************************************************/
@@ -169,314 +167,6 @@ register_in_3gpp_or_cdma_network (MMIfaceModemSimple *self,
/*****************************************************************************/
-typedef struct {
- GSimpleAsyncResult *result;
- MMIfaceModemSimple *self;
- MMCommonBearerProperties *bearer_properties;
- gboolean create_cdma_bearer;
- gboolean create_3gpp_bearer;
- GList *list;
-} CreateBearersContext;
-
-static void
-create_bearers_context_complete_and_free (CreateBearersContext *ctx)
-{
- g_simple_async_result_complete_in_idle (ctx->result);
- g_list_free_full (ctx->list, (GDestroyNotify)g_object_unref);
- g_object_unref (ctx->bearer_properties);
- g_object_unref (ctx->result);
- g_object_unref (ctx->self);
- g_free (ctx);
-}
-
-static GList *
-create_3gpp_and_cdma_bearers_finish (MMIfaceModemSimple *self,
- GAsyncResult *res,
- GError **error)
-{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- /* We return the list itself. Note that there was no GDestroyNotify given when
- * the result was set, as we know that this finish() is always executed */
- return (GList *) g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
-}
-
-static void create_next_bearer (CreateBearersContext *ctx);
-
-static void
-create_bearer_ready (MMIfaceModem *self,
- GAsyncResult *res,
- CreateBearersContext *ctx)
-{
- GError *error = NULL;
- MMBearer *bearer;
-
- bearer = mm_iface_modem_create_bearer_finish (self, res, &error);
- if (!bearer) {
- g_simple_async_result_take_error (ctx->result, error);
- create_bearers_context_complete_and_free (ctx);
- return;
- }
-
- /* Keep the new bearer */
- ctx->list = g_list_prepend (ctx->list, bearer);
-
- /* And see if we need to create a new one */
- create_next_bearer (ctx);
-}
-
-static void
-create_next_bearer (CreateBearersContext *ctx)
-{
- /* Create 3GPP bearer if needed */
- if (ctx->create_3gpp_bearer) {
- ctx->create_3gpp_bearer = FALSE;
- mm_iface_modem_create_bearer (MM_IFACE_MODEM (ctx->self),
- ctx->bearer_properties,
- (GAsyncReadyCallback)create_bearer_ready,
- ctx);
- return;
- }
-
- /* Create CDMA bearer if needed */
- if (ctx->create_cdma_bearer) {
- MMCommonBearerProperties *cdma_properties = NULL;
-
- ctx->create_cdma_bearer = FALSE;
-
- /* If the bearer properties has 'apn', we need to remove that before
- * trying to create the bearer. */
- if (mm_common_bearer_properties_get_apn (ctx->bearer_properties)) {
- cdma_properties = mm_common_bearer_properties_dup (ctx->bearer_properties);
- mm_common_bearer_properties_set_apn (cdma_properties, NULL);
- }
-
- mm_iface_modem_create_bearer (
- MM_IFACE_MODEM (ctx->self),
- (cdma_properties ? cdma_properties : ctx->bearer_properties),
- (GAsyncReadyCallback)create_bearer_ready,
- ctx);
-
- if (cdma_properties)
- g_object_unref (cdma_properties);
- return;
- }
-
- /* If no more bearers to create, we're done.
- * NOTE: we won't provide a GDestroyNotify to clear the gpointer passed as
- * result, as we know that finish() will ALWAYS be executed. */
- g_assert (ctx->list != NULL);
- g_simple_async_result_set_op_res_gpointer (ctx->result, ctx->list, NULL);
- ctx->list = NULL;
- create_bearers_context_complete_and_free (ctx);
-}
-
-static void
-create_3gpp_and_cdma_bearers (MMIfaceModemSimple *self,
- MMCommonBearerProperties *bearer_properties,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- guint n_bearers_needed;
- MMBearerList *list = NULL;
- CreateBearersContext *ctx;
-
- /* The implementation of this async method requires a valid callback, so
- * that we ensure that finish() will always be called. */
- g_assert (callback != NULL);
-
- ctx = g_new0 (CreateBearersContext, 1);
- ctx->self = g_object_ref (self);
- ctx->bearer_properties = g_object_ref (bearer_properties);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- create_3gpp_and_cdma_bearers);
-
- /* 3GPP-only modems... */
- if (mm_iface_modem_is_3gpp_only (MM_IFACE_MODEM (ctx->self)))
- ctx->create_3gpp_bearer = TRUE;
- /* CDMA-only modems... */
- else if (mm_iface_modem_is_cdma_only (MM_IFACE_MODEM (ctx->self)))
- ctx->create_cdma_bearer = TRUE;
- /* Mixed CDMA+3GPP modems */
- else {
- /* If we have APN, we'll create both 3GPP and CDMA bearers.
- * Otherwise we'll only create a CDMA bearer. */
- if (mm_common_bearer_properties_get_apn (ctx->bearer_properties)) {
- ctx->create_3gpp_bearer = TRUE;
- }
- ctx->create_cdma_bearer = TRUE;
- }
-
- n_bearers_needed = ctx->create_3gpp_bearer + ctx->create_cdma_bearer;
- if (n_bearers_needed == 0)
- g_assert_not_reached ();
-
- g_object_get (self,
- MM_IFACE_MODEM_BEARER_LIST, &list,
- NULL);
-
- /* TODO: check if the bearers we want to create are already in the list */
-
- /* If we don't have enough space to create all needed bearers, try to remove
- * all existing ones first BUT only if that will give us enough space. */
- if (mm_bearer_list_get_max (list) < (mm_bearer_list_get_count (list) +
- n_bearers_needed)) {
- if (mm_bearer_list_get_max (list) < n_bearers_needed) {
- g_simple_async_result_set_error (
- ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_TOO_MANY,
- "Cannot create bearers: need %u but only %u allowed",
- n_bearers_needed,
- mm_bearer_list_get_max (list));
- create_bearers_context_complete_and_free (ctx);
- g_object_unref (list);
- return;
- }
-
- /* We are told to force the creation of the new bearer.
- * We'll remove all existing bearers, and then go on creating the new one */
- mm_bearer_list_delete_all_bearers (list);
- }
-
- create_next_bearer (ctx);
- g_object_unref (list);
-}
-
-/*****************************************************************************/
-
-typedef struct {
- MMIfaceModemSimple *self;
- GSimpleAsyncResult *result;
- GList *bearers;
- MMBearer *current;
-} ConnectBearerContext;
-
-static void
-connect_bearer_context_complete_and_free (ConnectBearerContext *ctx)
-{
- g_simple_async_result_complete_in_idle (ctx->result);
- if (ctx->current)
- g_object_unref (ctx->current);
- g_list_free_full (ctx->bearers, (GDestroyNotify)g_object_unref);
- g_object_unref (ctx->result);
- g_object_unref (ctx->self);
- g_free (ctx);
-}
-
-static MMBearer *
-connect_3gpp_or_cdma_bearer_finish (MMIfaceModemSimple *self,
- GAsyncResult *res,
- GError **error)
-{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return NULL;
-
- return MM_BEARER (g_object_ref (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (res))));
-}
-
-static void connect_next_bearer (ConnectBearerContext *ctx);
-
-static void
-connect_bearer_ready (MMBearer *bearer,
- GAsyncResult *res,
- ConnectBearerContext *ctx)
-{
- GError *error = NULL;
-
- if (!mm_bearer_connect_finish (bearer, res, &error)) {
- mm_dbg ("Couldn't connect bearer: '%s'", error->message);
- g_error_free (error);
- /* We'll try with the next one */
- connect_next_bearer (ctx);
- return;
- }
-
- /* We got connected! */
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- g_object_ref (ctx->current),
- (GDestroyNotify)g_object_unref);
- connect_bearer_context_complete_and_free (ctx);
-}
-
-static void
-connect_next_bearer (ConnectBearerContext *ctx)
-{
- GList *l;
-
- g_clear_object (&ctx->current);
-
- /* First, look for 3GPP bearers */
- for (l = ctx->bearers; l; l = g_list_next (l)) {
- if (MM_IS_BEARER_3GPP (l->data)) {
- /* Try to connect the current bearer. If the modem is not yet
- * registered in the 3GPP network, connection won't succeed.
- * Steal the reference from the list. */
- ctx->current = MM_BEARER (l->data);
- ctx->bearers = g_list_delete_link (ctx->bearers, l);
- mm_bearer_connect (MM_BEARER (ctx->current),
- NULL, /* no number given */
- (GAsyncReadyCallback)connect_bearer_ready,
- ctx);
- return;
- }
- }
-
- /* Then, we look for CDMA bearers */
- for (l = ctx->bearers; l; l = g_list_next (l)) {
- if (MM_IS_BEARER_CDMA (l->data)) {
- /* Try to connect the current bearer. If the modem is not yet
- * registered in the 3GPP network, connection won't succeed.
- * Steal the reference from the list. */
- ctx->current = MM_BEARER (l->data);
- ctx->bearers = g_list_delete_link (ctx->bearers, l);
- mm_bearer_connect (MM_BEARER (ctx->current),
- NULL, /* no number given */
- (GAsyncReadyCallback)connect_bearer_ready,
- ctx);
- return;
- }
- }
-
- /* Here we shouldn't have any remaining bearer.
- * POTS modem not yet supported */
-
- /* If we got here, we didn't get connected :-/ */
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_UNAUTHORIZED,
- "Cannot connect any bearer");
- connect_bearer_context_complete_and_free (ctx);
-}
-
-static void
-connect_3gpp_or_cdma_bearer (MMIfaceModemSimple *self,
- GList *bearers,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- ConnectBearerContext *ctx;
-
- g_assert (bearers != NULL);
-
- ctx = g_new0 (ConnectBearerContext, 1);
- ctx->self = g_object_ref (self);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- connect_3gpp_or_cdma_bearer);
- ctx->bearers = g_list_copy (bearers);
- g_list_foreach (ctx->bearers, (GFunc)g_object_ref, NULL);
-
- connect_next_bearer (ctx);
-}
-
-/*****************************************************************************/
-
typedef enum {
CONNECTION_STEP_FIRST,
CONNECTION_STEP_UNLOCK_CHECK,
@@ -499,16 +189,13 @@ typedef struct {
MMCommonConnectProperties *properties;
/* Results to set */
- GList *bearers;
- MMBearer *connected_bearer;
+ MMBearer *bearer;
} ConnectionContext;
static void
connection_context_free (ConnectionContext *ctx)
{
- g_list_free_full (ctx->bearers, (GDestroyNotify)g_object_unref);
- if (ctx->connected_bearer)
- g_object_unref (ctx->connected_bearer);
+ g_object_unref (ctx->bearer);
g_object_unref (ctx->properties);
g_object_unref (ctx->skeleton);
g_object_unref (ctx->invocation);
@@ -519,14 +206,14 @@ connection_context_free (ConnectionContext *ctx)
static void connection_step (ConnectionContext *ctx);
static void
-connect_3gpp_or_cdma_bearer_ready (MMIfaceModemSimple *self,
- GAsyncResult *res,
- ConnectionContext *ctx)
+connect_bearer_ready (MMBearer *bearer,
+ GAsyncResult *res,
+ ConnectionContext *ctx)
{
GError *error = NULL;
- ctx->connected_bearer = connect_3gpp_or_cdma_bearer_finish (self, res, &error);
- if (!ctx->connected_bearer) {
+ if (!mm_bearer_connect_finish (bearer, res, &error)) {
+ mm_dbg ("Couldn't connect bearer: '%s'", error->message);
g_dbus_method_invocation_take_error (ctx->invocation, error);
connection_context_free (ctx);
return;
@@ -538,21 +225,21 @@ connect_3gpp_or_cdma_bearer_ready (MMIfaceModemSimple *self,
}
static void
-create_3gpp_and_cdma_bearers_ready (MMIfaceModemSimple *self,
- GAsyncResult *res,
- ConnectionContext *ctx)
+create_bearer_ready (MMIfaceModem *self,
+ GAsyncResult *res,
+ ConnectionContext *ctx)
{
GError *error = NULL;
- /* List ownership for the caller */
- ctx->bearers = create_3gpp_and_cdma_bearers_finish (self, res, &error);
- if (!ctx->bearers) {
+ /* ownership for the caller */
+ ctx->bearer = mm_iface_modem_create_bearer_finish (self, res, &error);
+ if (!ctx->bearer) {
g_dbus_method_invocation_take_error (ctx->invocation, error);
connection_context_free (ctx);
return;
}
- /* Bearers available! */
+ /* Bearer available! */
ctx->step++;
connection_step (ctx);
}
@@ -804,50 +491,45 @@ connection_step (ConnectionContext *ctx)
* So, fall down to next step */
ctx->step++;
- case CONNECTION_STEP_BEARER:
+ case CONNECTION_STEP_BEARER: {
+ MMBearerList *list = NULL;
+ MMCommonBearerProperties *bearer_properties;
+
mm_info ("Simple connect state (%d/%d): Bearer",
ctx->step, CONNECTION_STEP_LAST);
- if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (ctx->self)) ||
- mm_iface_modem_is_cdma (MM_IFACE_MODEM (ctx->self))) {
- MMCommonBearerProperties *bearer_properties;
+ g_object_get (ctx->self,
+ MM_IFACE_MODEM_BEARER_LIST, &list,
+ NULL);
- bearer_properties = (mm_common_connect_properties_get_bearer_properties (
- ctx->properties));
- /* 3GPP and/or CDMA bearer creation */
- create_3gpp_and_cdma_bearers (
- ctx->self,
- bearer_properties,
- (GAsyncReadyCallback)create_3gpp_and_cdma_bearers_ready,
- ctx);
+ /* TODO: check if the bearer we want to create is already in the list */
- g_object_unref (bearer_properties);
- return;
+ /* If we don't have enough space to create the, try to remove
+ * all existing ones first BUT only if that will give us enough space. */
+ if (mm_bearer_list_get_max (list) == mm_bearer_list_get_count (list)) {
+ /* We'll remove all existing bearers, and then go on creating the new one */
+ mm_bearer_list_delete_all_bearers (list);
}
- /* If not 3GPP and not CDMA, this will possibly be a POTS modem,
- * currently unsupported. So, just abort. */
- g_assert_not_reached ();
+ bearer_properties = (mm_common_connect_properties_get_bearer_properties (
+ ctx->properties));
+ mm_iface_modem_create_bearer (MM_IFACE_MODEM (ctx->self),
+ bearer_properties,
+ (GAsyncReadyCallback)create_bearer_ready,
+ ctx);
+
+ g_object_unref (list);
+ g_object_unref (bearer_properties);
return;
+ }
case CONNECTION_STEP_CONNECT:
mm_info ("Simple connect state (%d/%d): Connect",
ctx->step, CONNECTION_STEP_LAST);
- if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (ctx->self)) ||
- mm_iface_modem_is_cdma (MM_IFACE_MODEM (ctx->self))) {
- /* 3GPP or CDMA bearer connection */
- connect_3gpp_or_cdma_bearer (
- ctx->self,
- ctx->bearers,
- (GAsyncReadyCallback)connect_3gpp_or_cdma_bearer_ready,
- ctx);
- return;
- }
-
- /* If not 3GPP and not CDMA, this will possibly be a POTS modem,
- * currently unsupported. So, just abort. */
- g_assert_not_reached ();
+ mm_bearer_connect (ctx->bearer,
+ (GAsyncReadyCallback)connect_bearer_ready,
+ ctx);
return;
case CONNECTION_STEP_LAST:
@@ -857,7 +539,7 @@ connection_step (ConnectionContext *ctx)
mm_gdbus_modem_simple_complete_connect (
ctx->skeleton,
ctx->invocation,
- mm_bearer_get_path (ctx->connected_bearer));
+ mm_bearer_get_path (ctx->bearer));
connection_context_free (ctx);
return;
}