diff options
-rw-r--r-- | plugins/huawei/mm-broadband-bearer-huawei.c | 15 | ||||
-rw-r--r-- | plugins/huawei/mm-broadband-modem-huawei.c | 2 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-bearer-icera.c | 74 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-modem-icera.c | 30 | ||||
-rw-r--r-- | plugins/mbm/mm-broadband-bearer-mbm.c | 79 | ||||
-rw-r--r-- | plugins/novatel/mm-broadband-bearer-novatel-lte.c | 93 | ||||
-rw-r--r-- | plugins/option/mm-broadband-bearer-hso.c | 125 | ||||
-rw-r--r-- | plugins/sierra/mm-broadband-bearer-sierra.c | 21 | ||||
-rw-r--r-- | src/mm-base-modem.c | 13 | ||||
-rw-r--r-- | src/mm-base-modem.h | 4 | ||||
-rw-r--r-- | src/mm-bearer-qmi.c | 2 | ||||
-rw-r--r-- | src/mm-broadband-bearer.c | 166 | ||||
-rw-r--r-- | src/mm-broadband-bearer.h | 5 |
13 files changed, 312 insertions, 317 deletions
diff --git a/plugins/huawei/mm-broadband-bearer-huawei.c b/plugins/huawei/mm-broadband-bearer-huawei.c index 804d1659..364760fd 100644 --- a/plugins/huawei/mm-broadband-bearer-huawei.c +++ b/plugins/huawei/mm-broadband-bearer-huawei.c @@ -329,7 +329,6 @@ connect_3gpp (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -343,7 +342,6 @@ connect_3gpp (MMBroadbandBearer *self, ctx->self = g_object_ref (self); ctx->modem = g_object_ref (modem); ctx->primary = g_object_ref (primary); - ctx->data = g_object_ref (data); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, @@ -354,6 +352,19 @@ connect_3gpp (MMBroadbandBearer *self, g_assert (ctx->self->priv->connect_pending == NULL); g_assert (ctx->self->priv->disconnect_pending == NULL); + /* We need a net data port */ + ctx->data = mm_base_modem_get_best_data_port (MM_BASE_MODEM (modem), + MM_PORT_TYPE_NET); + if (!ctx->data) { + g_simple_async_result_set_error ( + ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_NOT_FOUND, + "No valid data port found to launch connection"); + connect_3gpp_context_complete_and_free (ctx); + return; + } + /* Run! */ connect_3gpp_context_step (ctx); } diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index b5ce8973..c1a29b3e 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c @@ -1368,7 +1368,7 @@ huawei_modem_create_bearer (MMIfaceModem *self, user_data, huawei_modem_create_bearer); - if (mm_port_get_port_type (mm_base_modem_peek_best_data_port (MM_BASE_MODEM (self))) == MM_PORT_TYPE_NET) { + if (mm_base_modem_peek_best_data_port (MM_BASE_MODEM (self), MM_PORT_TYPE_NET)) { /* If we get a 'net' port, check if driver is 'cdc_ether' or 'cdc_ncm' */ const gchar **drivers; guint i; diff --git a/plugins/icera/mm-broadband-bearer-icera.c b/plugins/icera/mm-broadband-bearer-icera.c index 589bdc4e..b7ea8df0 100644 --- a/plugins/icera/mm-broadband-bearer-icera.c +++ b/plugins/icera/mm-broadband-bearer-icera.c @@ -504,44 +504,23 @@ typedef struct { guint cid; GCancellable *cancellable; GSimpleAsyncResult *result; + MMPort *data; guint authentication_retries; GError *saved_error; } Dial3gppContext; -static Dial3gppContext * -dial_3gpp_context_new (MMBroadbandBearerIcera *self, - MMBaseModem *modem, - MMAtSerialPort *primary, - guint cid, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Dial3gppContext *ctx; - - ctx = g_new0 (Dial3gppContext, 1); - ctx->self = g_object_ref (self); - ctx->modem = g_object_ref (modem); - ctx->primary = g_object_ref (primary); - ctx->cid = cid; - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - dial_3gpp_context_new); - ctx->cancellable = g_object_ref (cancellable); - return ctx; -} - static void dial_3gpp_context_complete_and_free (Dial3gppContext *ctx) { g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->data) + g_object_unref (ctx->data); g_object_unref (ctx->cancellable); g_object_unref (ctx->result); g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); - g_free (ctx); + g_slice_free (Dial3gppContext, ctx); } static gboolean @@ -571,12 +550,15 @@ dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx) return TRUE; } -static gboolean +static MMPort * dial_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); } static void @@ -764,7 +746,9 @@ report_connect_status (MMBroadbandBearerIcera *self, return; } - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_set_op_res_gpointer (ctx->result, + g_object_ref (ctx->data), + (GDestroyNotify)g_object_unref); dial_3gpp_context_complete_and_free (ctx); return; @@ -1039,21 +1023,39 @@ static void dial_3gpp (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, /* unused by us */ guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + Dial3gppContext *ctx; + g_assert (primary != NULL); - authenticate (dial_3gpp_context_new (MM_BROADBAND_BEARER_ICERA (self), - modem, - primary, - cid, - cancellable, - callback, - user_data)); + ctx = g_slice_new0 (Dial3gppContext); + ctx->self = g_object_ref (self); + ctx->modem = g_object_ref (modem); + ctx->primary = g_object_ref (primary); + ctx->cid = cid; + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + dial_3gpp); + ctx->cancellable = g_object_ref (cancellable); + + /* We need a net data port */ + ctx->data = mm_base_modem_get_best_data_port (modem, MM_PORT_TYPE_NET); + if (!ctx->data) { + g_simple_async_result_set_error ( + ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_NOT_FOUND, + "No valid data port found to launch connection"); + dial_3gpp_context_complete_and_free (ctx); + return; + } + + authenticate (ctx); } /*****************************************************************************/ diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c index ca292fd7..5446fe68 100644 --- a/plugins/icera/mm-broadband-modem-icera.c +++ b/plugins/icera/mm-broadband-modem-icera.c @@ -733,25 +733,6 @@ broadband_bearer_icera_new_ready (GObject *source, } static void -broadband_bearer_new_ready (GObject *source, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - MMBearer *bearer = NULL; - GError *error = NULL; - - bearer = mm_broadband_bearer_new_finish (res, &error); - if (!bearer) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gpointer (simple, - bearer, - (GDestroyNotify)g_object_unref); - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -static void modem_create_bearer (MMIfaceModem *self, MMBearerProperties *properties, GAsyncReadyCallback callback, @@ -764,17 +745,6 @@ modem_create_bearer (MMIfaceModem *self, user_data, modem_create_bearer); - /* If data port is AT create a generic bearer */ - if (MM_IS_AT_SERIAL_PORT (mm_base_modem_peek_best_data_port (MM_BASE_MODEM (self)))) { - mm_broadband_bearer_new ( - MM_BROADBAND_MODEM (self), - properties, - NULL, /* cancellable */ - (GAsyncReadyCallback)broadband_bearer_new_ready, - result); - return; - } - /* Otherwise create a Icera bearer */ mm_broadband_bearer_icera_new ( MM_BROADBAND_MODEM (self), diff --git a/plugins/mbm/mm-broadband-bearer-mbm.c b/plugins/mbm/mm-broadband-bearer-mbm.c index ee9399db..264d084b 100644 --- a/plugins/mbm/mm-broadband-bearer-mbm.c +++ b/plugins/mbm/mm-broadband-bearer-mbm.c @@ -57,46 +57,23 @@ typedef struct { MMAtSerialPort *primary; guint cid; GCancellable *cancellable; + MMPort *data; GSimpleAsyncResult *result; guint poll_count; } Dial3gppContext; -static Dial3gppContext * -dial_3gpp_context_new (MMBroadbandBearerMbm *self, - MMBaseModem *modem, - MMAtSerialPort *primary, - guint cid, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Dial3gppContext *ctx; - - ctx = g_new0 (Dial3gppContext, 1); - ctx->self = g_object_ref (self); - ctx->modem = g_object_ref (modem); - ctx->primary = g_object_ref (primary); - ctx->cid = cid; - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - dial_3gpp_context_new); - ctx->cancellable = g_object_ref (cancellable); - ctx->poll_count = 0; - - return ctx; -} - static void dial_3gpp_context_complete_and_free (Dial3gppContext *ctx) { - g_simple_async_result_complete (ctx->result); + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->data) + g_object_unref (ctx->data); g_object_unref (ctx->cancellable); g_object_unref (ctx->result); g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); - g_free (ctx); + g_slice_free (Dial3gppContext, ctx); } static gboolean @@ -126,12 +103,15 @@ dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx) return TRUE; } -static gboolean +static MMPort * dial_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); } void @@ -164,7 +144,9 @@ mm_broadband_bearer_mbm_report_connection_status (MMBroadbandBearerMbm *self, if (!ctx) break; - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_set_op_res_gpointer (ctx->result, + g_object_ref (ctx->data), + (GDestroyNotify)g_object_unref); dial_3gpp_context_complete_and_free (ctx); return; @@ -433,21 +415,40 @@ static void dial_3gpp (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, /* unused by us */ guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + Dial3gppContext *ctx; + g_assert (primary != NULL); - authenticate (dial_3gpp_context_new (MM_BROADBAND_BEARER_MBM (self), - modem, - primary, - cid, - cancellable, - callback, - user_data)); + ctx = g_slice_new0 (Dial3gppContext); + ctx->self = g_object_ref (self); + ctx->modem = g_object_ref (modem); + ctx->primary = g_object_ref (primary); + ctx->cid = cid; + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + dial_3gpp); + ctx->cancellable = g_object_ref (cancellable); + ctx->poll_count = 0; + + /* We need a net data port */ + ctx->data = mm_base_modem_get_best_data_port (modem, MM_PORT_TYPE_NET); + if (!ctx->data) { + g_simple_async_result_set_error ( + ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_NOT_FOUND, + "No valid data port found to launch connection"); + dial_3gpp_context_complete_and_free (ctx); + return; + } + + authenticate (ctx); } /*****************************************************************************/ diff --git a/plugins/novatel/mm-broadband-bearer-novatel-lte.c b/plugins/novatel/mm-broadband-bearer-novatel-lte.c index 88d46cc7..a12e5984 100644 --- a/plugins/novatel/mm-broadband-bearer-novatel-lte.c +++ b/plugins/novatel/mm-broadband-bearer-novatel-lte.c @@ -55,45 +55,18 @@ typedef struct { gint retries; } DetailedConnectContext; -static DetailedConnectContext * -detailed_connect_context_new (MMBroadbandBearer *self, - MMBroadbandModem *modem, - MMAtSerialPort *primary, - MMPort *data, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - DetailedConnectContext *ctx; - - ctx = g_new0 (DetailedConnectContext, 1); - ctx->self = g_object_ref (self); - ctx->modem = MM_BASE_MODEM (g_object_ref (modem)); - ctx->primary = g_object_ref (primary); - ctx->data = g_object_ref (data); - /* NOTE: - * We don't currently support cancelling AT commands, so we'll just check - * whether the operation is to be cancelled at each step. */ - ctx->cancellable = g_object_ref (cancellable); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - detailed_connect_context_new); - ctx->retries = 4; - return ctx; -} - static void detailed_connect_context_complete_and_free (DetailedConnectContext *ctx) { g_simple_async_result_complete_in_idle (ctx->result); g_object_unref (ctx->result); g_object_unref (ctx->cancellable); - g_object_unref (ctx->data); + if (ctx->data) + g_object_unref (ctx->data); g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); - g_free (ctx); + g_slice_free (DetailedConnectContext, ctx); } static MMBearerConnectResult * @@ -264,28 +237,12 @@ connect_3gpp_qmiconnect_ready (MMBaseModem *modem, } static void -connect_3gpp (MMBroadbandBearer *bearer, - MMBroadbandModem *modem, - MMAtSerialPort *primary, - MMAtSerialPort *secondary, - MMPort *data, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) +connect_3gpp_authenticate (DetailedConnectContext *ctx) { - DetailedConnectContext *ctx; - gchar *command, *apn, *user, *password; MMBearerProperties *config; + gchar *command, *apn, *user, *password; - ctx = detailed_connect_context_new (bearer, - modem, - primary, - data, - cancellable, - callback, - user_data); - - config = mm_bearer_peek_config (MM_BEARER (bearer)); + config = mm_bearer_peek_config (MM_BEARER (ctx->self)); apn = mm_at_serial_port_quote_string (mm_bearer_properties_get_apn (config)); user = mm_at_serial_port_quote_string (mm_bearer_properties_get_user (config)); password = mm_at_serial_port_quote_string (mm_bearer_properties_get_password (config)); @@ -304,6 +261,44 @@ connect_3gpp (MMBroadbandBearer *bearer, g_free (command); } +static void +connect_3gpp (MMBroadbandBearer *self, + MMBroadbandModem *modem, + MMAtSerialPort *primary, + MMAtSerialPort *secondary, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + DetailedConnectContext *ctx; + + ctx = g_slice_new0 (DetailedConnectContext); + ctx->self = g_object_ref (self); + ctx->modem = MM_BASE_MODEM (g_object_ref (modem)); + ctx->primary = g_object_ref (primary); + ctx->cancellable = g_object_ref (cancellable); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + connect_3gpp); + ctx->retries = 4; + + /* Get a 'net' data port */ + ctx->data = mm_base_modem_peek_best_data_port (MM_BASE_MODEM (modem), + MM_PORT_TYPE_NET); + if (!ctx->data) { + g_simple_async_result_set_error ( + ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_CONNECTED, + "Couldn't connect: no available net port available"); + detailed_connect_context_complete_and_free (ctx); + return; + } + + connect_3gpp_authenticate (ctx); +} + /*****************************************************************************/ /* 3GPP Disonnection sequence */ diff --git a/plugins/option/mm-broadband-bearer-hso.c b/plugins/option/mm-broadband-bearer-hso.c index 194f1a89..1830bb2f 100644 --- a/plugins/option/mm-broadband-bearer-hso.c +++ b/plugins/option/mm-broadband-bearer-hso.c @@ -54,28 +54,6 @@ typedef struct { GSimpleAsyncResult *result; } GetIpConfig3gppContext; -static GetIpConfig3gppContext * -get_ip_config_3gpp_context_new (MMBroadbandBearerHso *self, - MMBaseModem *modem, - MMAtSerialPort *primary, - guint cid, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GetIpConfig3gppContext *ctx; - - ctx = g_new0 (GetIpConfig3gppContext, 1); - ctx->self = g_object_ref (self); - ctx->modem = g_object_ref (modem); - ctx->primary = g_object_ref (primary); - ctx->cid = cid; - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - get_ip_config_3gpp_context_new); - return ctx; -} - static void get_ip_config_context_complete_and_free (GetIpConfig3gppContext *ctx) { @@ -84,7 +62,7 @@ get_ip_config_context_complete_and_free (GetIpConfig3gppContext *ctx) g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); - g_free (ctx); + g_slice_free (GetIpConfig3gppContext, ctx); } static gboolean @@ -210,8 +188,19 @@ get_ip_config_3gpp (MMBroadbandBearer *self, GAsyncReadyCallback callback, gpointer user_data) { + GetIpConfig3gppContext *ctx; gchar *command; + ctx = g_slice_new0 (GetIpConfig3gppContext); + ctx->self = g_object_ref (self); + ctx->modem = g_object_ref (modem); + ctx->primary = g_object_ref (primary); + ctx->cid = cid; + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + get_ip_config_3gpp); + command = g_strdup_printf ("AT_OWANDATA=%d", cid); mm_base_modem_at_command_full ( MM_BASE_MODEM (modem), @@ -222,12 +211,7 @@ get_ip_config_3gpp (MMBroadbandBearer *self, FALSE, /* raw */ NULL, /* cancellable */ (GAsyncReadyCallback)ip_config_ready, - get_ip_config_3gpp_context_new (MM_BROADBAND_BEARER_HSO (self), - MM_BASE_MODEM (modem), - primary, - cid, - callback, - user_data)); + ctx); g_free (command); } @@ -241,49 +225,23 @@ typedef struct { guint cid; GCancellable *cancellable; GSimpleAsyncResult *result; + MMPort *data; guint auth_idx; GError *saved_error; } Dial3gppContext; -static Dial3gppContext * -dial_3gpp_context_new (MMBroadbandBearerHso *self, - MMBaseModem *modem, - MMAtSerialPort *primary, - guint cid, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Dial3gppContext *ctx; - - ctx = g_new0 (Dial3gppContext, 1); - ctx->self = g_object_ref (self); - ctx->modem = g_object_ref (modem); - ctx->primary = g_object_ref (primary); - ctx->cid = cid; - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - dial_3gpp_context_new); - ctx->cancellable = g_object_ref (cancellable); - - /* Always start with the index that worked last time - * (will be 0 the first time)*/ - ctx->auth_idx = self->priv->auth_idx; - - return ctx; -} - static void dial_3gpp_context_complete_and_free (Dial3gppContext *ctx) { g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->data) + g_object_unref (ctx->data); g_object_unref (ctx->cancellable); g_object_unref (ctx->result); g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); - g_free (ctx); + g_slice_free (Dial3gppContext, ctx); } static gboolean @@ -313,12 +271,15 @@ dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx) return TRUE; } -static gboolean +static MMPort * dial_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); } static void @@ -400,7 +361,9 @@ mm_broadband_bearer_hso_report_connection_status (MMBroadbandBearerHso *self, return; } - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_set_op_res_gpointer (ctx->result, + g_object_ref (ctx->data), + (GDestroyNotify)g_object_unref); dial_3gpp_context_complete_and_free (ctx); return; @@ -713,21 +676,43 @@ static void dial_3gpp (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, /* unused by us */ guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { + Dial3gppContext *ctx; + g_assert (primary != NULL); - authenticate (dial_3gpp_context_new (MM_BROADBAND_BEARER_HSO (self), - modem, - primary, - cid, - cancellable, - callback, - user_data)); + ctx = g_slice_new0 (Dial3gppContext); + ctx->self = g_object_ref (self); + ctx->modem = g_object_ref (modem); + ctx->primary = g_object_ref (primary); + ctx->cid = cid; + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + dial_3gpp); + ctx->cancellable = g_object_ref (cancellable); + + /* Always start with the index that worked last time + * (will be 0 the first time)*/ + ctx->auth_idx = ctx->self->priv->auth_idx; + + /* We need a net data port */ + ctx->data = mm_base_modem_get_best_data_port (modem, MM_PORT_TYPE_NET); + if (!ctx->data) { + g_simple_async_result_set_error ( + ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_NOT_FOUND, + "No valid data port found to launch connection"); + dial_3gpp_context_complete_and_free (ctx); + return; + } + + authenticate (ctx); } /*****************************************************************************/ diff --git a/plugins/sierra/mm-broadband-bearer-sierra.c b/plugins/sierra/mm-broadband-bearer-sierra.c index 17473d12..7a07b609 100644 --- a/plugins/sierra/mm-broadband-bearer-sierra.c +++ b/plugins/sierra/mm-broadband-bearer-sierra.c @@ -69,12 +69,15 @@ dial_3gpp_context_complete_and_free (Dial3gppContext *ctx) g_slice_free (Dial3gppContext, ctx); } -static gboolean +static MMPort * dial_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); } static void dial_3gpp_context_step (Dial3gppContext *ctx); @@ -86,7 +89,8 @@ parent_dial_3gpp_ready (MMBroadbandBearer *self, { GError *error = NULL; - if (!MM_BROADBAND_BEARER_CLASS (mm_broadband_bearer_sierra_parent_class)->dial_3gpp_finish (self, res, &error)) { + ctx->data = MM_BROADBAND_BEARER_CLASS (mm_broadband_bearer_sierra_parent_class)->dial_3gpp_finish (self, res, &error); + if (!ctx->data) { g_simple_async_result_take_error (ctx->result, error); dial_3gpp_context_complete_and_free (ctx); return; @@ -251,7 +255,9 @@ dial_3gpp_context_step (Dial3gppContext *ctx) ctx->step++; case DIAL_3GPP_STEP_CONNECT: - if (!MM_IS_AT_SERIAL_PORT (ctx->data)) { + /* We need a net or AT data port */ + ctx->data = mm_base_modem_get_best_data_port (ctx->modem, MM_PORT_TYPE_NET); + if (ctx->data) { gchar *command; command = g_strdup_printf ("!SCACT=1,%d", ctx->cid); @@ -273,7 +279,6 @@ dial_3gpp_context_step (Dial3gppContext *ctx) MM_BROADBAND_BEARER (ctx->self), ctx->modem, ctx->primary, - ctx->data, ctx->cid, ctx->cancellable, (GAsyncReadyCallback)parent_dial_3gpp_ready, @@ -281,7 +286,9 @@ dial_3gpp_context_step (Dial3gppContext *ctx) return; case DIAL_3GPP_STEP_LAST: - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_set_op_res_gpointer (ctx->result, + g_object_ref (ctx->data), + (GDestroyNotify)g_object_unref); dial_3gpp_context_complete_and_free (ctx); return; } @@ -291,7 +298,6 @@ static void dial_3gpp (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -311,7 +317,6 @@ dial_3gpp (MMBroadbandBearer *self, user_data, dial_3gpp); ctx->cancellable = g_object_ref (cancellable); - ctx->data = g_object_ref (data); ctx->step = DIAL_3GPP_STEP_FIRST; dial_3gpp_context_step (ctx); diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c index 86ff8123..7407682d 100644 --- a/src/mm-base-modem.c +++ b/src/mm-base-modem.c @@ -699,16 +699,18 @@ mm_base_modem_peek_port_qmi_for_data (MMBaseModem *self, #endif /* WITH_QMI */ MMPort * -mm_base_modem_get_best_data_port (MMBaseModem *self) +mm_base_modem_get_best_data_port (MMBaseModem *self, + MMPortType type) { MMPort *port; - port = mm_base_modem_peek_best_data_port (self); + port = mm_base_modem_peek_best_data_port (self, type); return (port ? g_object_ref (port) : NULL); } MMPort * -mm_base_modem_peek_best_data_port (MMBaseModem *self) +mm_base_modem_peek_best_data_port (MMBaseModem *self, + MMPortType type) { GList *l; @@ -716,8 +718,11 @@ mm_base_modem_peek_best_data_port (MMBaseModem *self) /* Return first not-connected data port */ for (l = self->priv->data; l; l = g_list_next (l)) { - if (!mm_port_get_connected ((MMPort *)l->data)) + if (!mm_port_get_connected ((MMPort *)l->data) && + (mm_port_get_port_type ((MMPort *)l->data) == type || + type == MM_PORT_TYPE_UNKNOWN)) { return (MMPort *)l->data; + } } return NULL; diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h index 9d4e3a1b..95ab21f6 100644 --- a/src/mm-base-modem.h +++ b/src/mm-base-modem.h @@ -127,7 +127,7 @@ MMQmiPort *mm_base_modem_peek_port_qmi (MMBaseModem *self); MMQmiPort *mm_base_modem_peek_port_qmi_for_data (MMBaseModem *self, MMPort *data, GError **error); #endif MMAtSerialPort *mm_base_modem_peek_best_at_port (MMBaseModem *self, GError **error); -MMPort *mm_base_modem_peek_best_data_port (MMBaseModem *self); +MMPort *mm_base_modem_peek_best_data_port (MMBaseModem *self, MMPortType type); GList *mm_base_modem_peek_data_ports (MMBaseModem *self); MMAtSerialPort *mm_base_modem_get_port_primary (MMBaseModem *self); @@ -140,7 +140,7 @@ MMQmiPort *mm_base_modem_get_port_qmi (MMBaseModem *self); MMQmiPort *mm_base_modem_get_port_qmi_for_data (MMBaseModem *self, MMPort *data, GError **error); #endif MMAtSerialPort *mm_base_modem_get_best_at_port (MMBaseModem *self, GError **error); -MMPort *mm_base_modem_get_best_data_port (MMBaseModem *self); +MMPort *mm_base_modem_get_best_data_port (MMBaseModem *self, MMPortType type); GList *mm_base_modem_get_data_ports (MMBaseModem *self); void mm_base_modem_set_hotplugged (MMBaseModem *self, diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c index a4131387..e31f7381 100644 --- a/src/mm-bearer-qmi.c +++ b/src/mm-bearer-qmi.c @@ -791,7 +791,7 @@ _connect (MMBearer *self, g_assert (modem); /* Grab a data port */ - data = mm_base_modem_get_best_data_port (modem); + data = mm_base_modem_get_best_data_port (modem, MM_PORT_TYPE_NET); if (!data) { g_simple_async_report_error_in_idle ( G_OBJECT (self), diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c index b0a46713..2b0819c1 100644 --- a/src/mm-broadband-bearer.c +++ b/src/mm-broadband-bearer.c @@ -76,10 +76,12 @@ typedef struct { MMBaseModem *modem; MMAtSerialPort *primary; MMAtSerialPort *secondary; - MMPort *data; GCancellable *cancellable; GSimpleAsyncResult *result; + MMPort *data; + gboolean close_data_on_exit; + /* 3GPP-specific */ guint cid; guint max_cid; @@ -102,10 +104,14 @@ detailed_connect_context_complete_and_free (DetailedConnectContext *ctx) g_simple_async_result_complete_in_idle (ctx->result); g_object_unref (ctx->result); g_object_unref (ctx->cancellable); - g_object_unref (ctx->data); g_object_unref (ctx->primary); if (ctx->secondary) g_object_unref (ctx->secondary); + if (ctx->data) { + if (ctx->close_data_on_exit) + mm_serial_port_close (MM_SERIAL_PORT (ctx->data)); + g_object_unref (ctx->data); + } g_object_unref (ctx->self); g_object_unref (ctx->modem); g_slice_free (DetailedConnectContext, ctx); @@ -143,7 +149,6 @@ detailed_connect_context_new (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -155,7 +160,6 @@ detailed_connect_context_new (MMBroadbandBearer *self, ctx->modem = MM_BASE_MODEM (g_object_ref (modem)); ctx->primary = g_object_ref (primary); ctx->secondary = (secondary ? g_object_ref (secondary) : NULL); - ctx->data = g_object_ref (data); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, @@ -168,6 +172,37 @@ detailed_connect_context_new (MMBroadbandBearer *self, } /*****************************************************************************/ +/* Generic implementations (both 3GPP and CDMA) are always AT-port based */ + +static MMAtSerialPort * +common_get_at_data_port (MMBaseModem *modem, + GError **error) +{ + MMPort *data; + + /* Look for best data port, NULL if none available. */ + data = mm_base_modem_peek_best_data_port (modem, MM_PORT_TYPE_AT); + if (!data) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_CONNECTED, + "Couldn't connect: no port available"); + return NULL; + } + + g_assert (MM_IS_AT_SERIAL_PORT (data)); + + if (!mm_serial_port_open (MM_SERIAL_PORT (data), error)) { + g_prefix_error (error, "Couldn't connect: cannot keep data port open."); + return NULL; + } + + mm_dbg ("Connection through a plain serial AT port (%s)", mm_port_get_device (data)); + + return MM_AT_SERIAL_PORT (g_object_ref (data)); +} + +/*****************************************************************************/ /* CDMA CONNECT * * CDMA connection procedure of a bearer involves several steps: @@ -199,6 +234,9 @@ dial_cdma_ready (MMBaseModem *modem, /* else... Yuhu! */ + /* Keep port open during connection */ + ctx->close_data_on_exit = FALSE; + /* Generic CDMA connections are done over PPP always */ g_assert (MM_IS_AT_SERIAL_PORT (ctx->data)); config = mm_bearer_ip_config_new (); @@ -231,7 +269,7 @@ cdma_connect_context_dial (DetailedConnectContext *ctx) command = g_strdup ("DT#777"); mm_base_modem_at_command_full (ctx->modem, - ctx->primary, + MM_AT_SERIAL_PORT (ctx->data), command, 90, FALSE, @@ -339,32 +377,33 @@ connect_cdma (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, /* unused by us */ - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { DetailedConnectContext *ctx; - MMPort *real_data; + GError *error = NULL; g_assert (primary != NULL); - if (MM_IS_AT_SERIAL_PORT (data)) - real_data = data; - else { - mm_dbg ("Ignoring 'net' interface in CDMA connection"); - real_data = MM_PORT (primary); - } - ctx = detailed_connect_context_new (self, modem, primary, NULL, - real_data, cancellable, callback, user_data); + /* Grab dial port. This gets a reference to the dial port and OPENs it. + * If we fail, we'll need to close it ourselves. */ + ctx->data = (MMPort *)common_get_at_data_port (ctx->modem, &error); + if (!ctx->data) { + g_simple_async_result_take_error (ctx->result, error); + detailed_connect_context_complete_and_free (ctx); + return; + } + ctx->close_data_on_exit = TRUE; + if (mm_bearer_properties_get_rm_protocol ( mm_bearer_peek_config (MM_BEARER (self))) != MM_MODEM_CDMA_RM_PROTOCOL_UNKNOWN) { @@ -393,10 +432,12 @@ typedef struct { MMBroadbandBearer *self; MMBaseModem *modem; MMAtSerialPort *primary; - MMAtSerialPort *dial_port; GCancellable *cancellable; GSimpleAsyncResult *result; GError *saved_error; + + MMAtSerialPort *dial_port; + gboolean close_dial_port_on_exit; } Dial3gppContext; static void @@ -404,10 +445,11 @@ dial_3gpp_context_complete_and_free (Dial3gppContext *ctx) { if (ctx->saved_error) g_error_free (ctx->saved_error); + if (ctx->dial_port) + g_object_unref (ctx->dial_port); g_object_unref (ctx->cancellable); g_simple_async_result_complete (ctx->result); g_object_unref (ctx->result); - g_object_unref (ctx->dial_port); g_object_unref (ctx->primary); g_object_unref (ctx->modem); g_object_unref (ctx->self); @@ -441,12 +483,15 @@ dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx) return TRUE; } -static gboolean +static MMPort * dial_3gpp_finish (MMBroadbandBearer *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + + return MM_PORT (g_object_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)))); } static void @@ -475,6 +520,9 @@ extended_error_ready (MMBaseModem *modem, ctx->saved_error = NULL; + /* Close the dialling port as we got an error */ + mm_serial_port_close (MM_SERIAL_PORT (ctx->dial_port)); + /* Done with errors */ dial_3gpp_context_complete_and_free (ctx); } @@ -503,7 +551,9 @@ atd_ready (MMBaseModem *modem, return; } - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_set_op_res_gpointer (ctx->result, + g_object_ref (ctx->dial_port), + (GDestroyNotify)g_object_unref); dial_3gpp_context_complete_and_free (ctx); } @@ -511,7 +561,6 @@ static void dial_3gpp (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -519,23 +568,29 @@ dial_3gpp (MMBroadbandBearer *self, { gchar *command; Dial3gppContext *ctx; + GError *error = NULL; g_assert (primary != NULL); ctx = g_slice_new0 (Dial3gppContext); ctx->self = g_object_ref (self); ctx->modem = g_object_ref (modem); - /* Dial port might not be the primary port */ ctx->primary = g_object_ref (primary); - ctx->dial_port = (data && MM_IS_AT_SERIAL_PORT (data) ? - g_object_ref (data) : - g_object_ref (primary)); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, dial_3gpp); ctx->cancellable = g_object_ref (cancellable); + /* Grab dial port. This gets a reference to the dial port and OPENs it. + * If we fail, we'll need to close it ourselves. */ + ctx->dial_port = common_get_at_data_port (ctx->modem, &error); + if (!ctx->dial_port) { + g_simple_async_result_take_error (ctx->result, error); + dial_3gpp_context_complete_and_free (ctx); + return; + } + /* Use default *99 to connect */ command = g_strdup_printf ("ATD*99***%d#", cid); mm_base_modem_at_command_full (ctx->modem, @@ -584,6 +639,10 @@ get_ip_config_3gpp_ready (MMBroadbandModem *modem, return; } + /* Keep port open during connection */ + if (MM_IS_AT_SERIAL_PORT (ctx->data)) + ctx->close_data_on_exit = FALSE; + g_simple_async_result_set_op_res_gpointer ( ctx->result, mm_bearer_connect_result_new (ctx->data, ipv4_config, ipv6_config), @@ -604,9 +663,8 @@ dial_3gpp_ready (MMBroadbandModem *modem, MMBearerIpConfig *config; GError *error = NULL; - if (!MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->dial_3gpp_finish (ctx->self, - res, - &error)) { + ctx->data = MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->dial_3gpp_finish (ctx->self, res, &error); + if (!ctx->data) { /* Clear CID when it failed to connect. */ ctx->self->priv->cid = 0; g_simple_async_result_take_error (ctx->result, error); @@ -614,6 +672,11 @@ dial_3gpp_ready (MMBroadbandModem *modem, return; } + /* If the dialling operation used an AT port, it is assumed to have an extra + * open() count. */ + if (MM_IS_AT_SERIAL_PORT (ctx->data)) + ctx->close_data_on_exit = TRUE; + if (MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp && MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp_finish) { /* Launch specific IP config retrieval */ @@ -631,6 +694,10 @@ dial_3gpp_ready (MMBroadbandModem *modem, /* Yuhu! */ + /* Keep port open during connection */ + if (MM_IS_AT_SERIAL_PORT (ctx->data)) + ctx->close_data_on_exit = FALSE; + /* If no specific IP retrieval requested, set the default implementation * (PPP if data port is AT, DHCP otherwise) */ config = mm_bearer_ip_config_new (); @@ -674,7 +741,6 @@ initialize_pdp_context_ready (MMBaseModem *modem, MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->dial_3gpp (ctx->self, ctx->modem, ctx->primary, - ctx->data, ctx->cid, ctx->cancellable, (GAsyncReadyCallback)dial_3gpp_ready, @@ -920,7 +986,6 @@ connect_3gpp (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -933,7 +998,6 @@ connect_3gpp (MMBroadbandBearer *self, modem, primary, secondary, - data, cancellable, callback, user_data); @@ -955,7 +1019,6 @@ connect_3gpp (MMBroadbandBearer *self, typedef struct { MMBroadbandBearer *self; GSimpleAsyncResult *result; - MMPort *suggested_data; } ConnectContext; static void @@ -963,7 +1026,6 @@ connect_context_complete_and_free (ConnectContext *ctx) { g_simple_async_result_complete_in_idle (ctx->result); g_object_unref (ctx->result); - g_object_unref (ctx->suggested_data); g_object_unref (ctx->self); g_slice_free (ConnectContext, ctx); } @@ -1044,7 +1106,6 @@ connect (MMBearer *self, { MMBaseModem *modem = NULL; MMAtSerialPort *primary; - MMPort *suggested_data; ConnectContext *ctx; /* Don't try to connect if already connected */ @@ -1092,44 +1153,9 @@ connect (MMBearer *self, return; } - /* Look for best data port, NULL if none available. */ - suggested_data = mm_base_modem_peek_best_data_port (modem); - if (!suggested_data) { - g_simple_async_report_error_in_idle ( - G_OBJECT (self), - callback, - user_data, - MM_CORE_ERROR, - MM_CORE_ERROR_CONNECTED, - "Couldn't connect: all available data ports already connected"); - g_object_unref (modem); - return; - } - - /* If data port is AT, we need to ensure it's open during the whole - * connection. For the case where the primary port is used as data port, - * which is actually always right now, this is already ensured because the - * primary port is kept open as long as the modem is enabled, but anyway - * there's no real problem in keeping an open count here as well. */ - if (MM_IS_AT_SERIAL_PORT (suggested_data)) { - GError *error = NULL; - - if (!mm_serial_port_open (MM_SERIAL_PORT (suggested_data), &error)) { - g_prefix_error (&error, "Couldn't connect: cannot keep data port open."); - g_simple_async_report_take_gerror_in_idle ( - G_OBJECT (self), - callback, - user_data, - error); - g_object_unref (modem); - return; - } - } - /* In this context, we only keep the stuff we'll need later */ ctx = g_slice_new0 (ConnectContext); ctx->self = g_object_ref (self); - ctx->suggested_data = g_object_ref (suggested_data); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, @@ -1142,7 +1168,6 @@ connect (MMBearer *self, MM_BROADBAND_MODEM (modem), primary, mm_base_modem_peek_port_secondary (modem), - suggested_data, cancellable, (GAsyncReadyCallback) connect_3gpp_ready, ctx); @@ -1157,7 +1182,6 @@ connect (MMBearer *self, MM_BROADBAND_MODEM (modem), primary, mm_base_modem_peek_port_secondary (modem), - suggested_data, cancellable, (GAsyncReadyCallback) connect_cdma_ready, ctx); diff --git a/src/mm-broadband-bearer.h b/src/mm-broadband-bearer.h index 5e35be50..35d04a93 100644 --- a/src/mm-broadband-bearer.h +++ b/src/mm-broadband-bearer.h @@ -52,7 +52,6 @@ struct _MMBroadbandBearerClass { MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); @@ -64,12 +63,11 @@ struct _MMBroadbandBearerClass { void (* dial_3gpp) (MMBroadbandBearer *self, MMBaseModem *modem, MMAtSerialPort *primary, - MMPort *data, guint cid, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); - gboolean (* dial_3gpp_finish) (MMBroadbandBearer *self, + MMPort * (* dial_3gpp_finish) (MMBroadbandBearer *self, GAsyncResult *res, GError **error); @@ -107,7 +105,6 @@ struct _MMBroadbandBearerClass { MMBroadbandModem *modem, MMAtSerialPort *primary, MMAtSerialPort *secondary, - MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); |