broadband-bearer: allow implementations to override the port used for connection

This commit is contained in:
Aleksander Morgado
2012-08-22 16:00:12 +02:00
parent 3dfb48d75a
commit e38828c318
3 changed files with 61 additions and 29 deletions

View File

@@ -98,6 +98,7 @@ detailed_connect_context_complete_and_free (DetailedConnectContext *ctx)
static gboolean static gboolean
connect_3gpp_finish (MMBroadbandBearer *self, connect_3gpp_finish (MMBroadbandBearer *self,
GAsyncResult *res, GAsyncResult *res,
MMPort **data,
MMBearerIpConfig **ipv4_config, MMBearerIpConfig **ipv4_config,
MMBearerIpConfig **ipv6_config, MMBearerIpConfig **ipv6_config,
GError **error) GError **error)
@@ -112,6 +113,9 @@ connect_3gpp_finish (MMBroadbandBearer *self,
/* In the default implementation, we assume only IPv4 is supported */ /* In the default implementation, we assume only IPv4 is supported */
*ipv4_config = g_object_ref (config); *ipv4_config = g_object_ref (config);
*ipv6_config = NULL; *ipv6_config = NULL;
/* We used the input suggested data port */
*data = NULL;
return TRUE; return TRUE;
} }

View File

@@ -33,6 +33,7 @@
#include "mm-utils.h" #include "mm-utils.h"
#include "mm-log.h" #include "mm-log.h"
#include "mm-modem-helpers.h" #include "mm-modem-helpers.h"
#include "mm-serial-enums-types.h"
static void async_initable_iface_init (GAsyncInitableIface *iface); static void async_initable_iface_init (GAsyncInitableIface *iface);
@@ -95,6 +96,7 @@ static const gchar *connection_forbidden_reason_str [CONNECTION_FORBIDDEN_REASON
/*****************************************************************************/ /*****************************************************************************/
/* Detailed connect result, used in both CDMA and 3GPP sequences */ /* Detailed connect result, used in both CDMA and 3GPP sequences */
typedef struct { typedef struct {
MMPort *data;
MMBearerIpConfig *ipv4_config; MMBearerIpConfig *ipv4_config;
MMBearerIpConfig *ipv6_config; MMBearerIpConfig *ipv6_config;
} DetailedConnectResult; } DetailedConnectResult;
@@ -106,16 +108,21 @@ detailed_connect_result_free (DetailedConnectResult *result)
g_object_unref (result->ipv4_config); g_object_unref (result->ipv4_config);
if (result->ipv6_config) if (result->ipv6_config)
g_object_unref (result->ipv6_config); g_object_unref (result->ipv6_config);
g_free (result); if (result->data)
g_object_unref (result->data);
g_slice_free (DetailedConnectResult, result);
} }
static DetailedConnectResult * static DetailedConnectResult *
detailed_connect_result_new (MMBearerIpConfig *ipv4_config, detailed_connect_result_new (MMPort *data,
MMBearerIpConfig *ipv4_config,
MMBearerIpConfig *ipv6_config) MMBearerIpConfig *ipv6_config)
{ {
DetailedConnectResult *result; DetailedConnectResult *result;
result = g_new0 (DetailedConnectResult, 1); result = g_slice_new0 (DetailedConnectResult);
if (data)
result->data = g_object_ref (data);
if (ipv4_config) if (ipv4_config)
result->ipv4_config = g_object_ref (ipv4_config); result->ipv4_config = g_object_ref (ipv4_config);
if (ipv6_config) if (ipv6_config)
@@ -142,6 +149,7 @@ typedef struct {
static gboolean static gboolean
detailed_connect_finish (MMBroadbandBearer *self, detailed_connect_finish (MMBroadbandBearer *self,
GAsyncResult *res, GAsyncResult *res,
MMPort **data,
MMBearerIpConfig **ipv4_config, MMBearerIpConfig **ipv4_config,
MMBearerIpConfig **ipv6_config, MMBearerIpConfig **ipv6_config,
GError **error) GError **error)
@@ -153,6 +161,7 @@ detailed_connect_finish (MMBroadbandBearer *self,
result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
*data = (result->data ? g_object_ref (result->data) : NULL);
*ipv4_config = (result->ipv4_config ? g_object_ref (result->ipv4_config) : NULL); *ipv4_config = (result->ipv4_config ? g_object_ref (result->ipv4_config) : NULL);
*ipv6_config = (result->ipv6_config ? g_object_ref (result->ipv6_config) : NULL); *ipv6_config = (result->ipv6_config ? g_object_ref (result->ipv6_config) : NULL);
return TRUE; return TRUE;
@@ -271,7 +280,7 @@ dial_cdma_ready (MMBaseModem *modem,
/* Assume only IPv4 is given */ /* Assume only IPv4 is given */
g_simple_async_result_set_op_res_gpointer ( g_simple_async_result_set_op_res_gpointer (
ctx->result, ctx->result,
detailed_connect_result_new (config, NULL), detailed_connect_result_new (ctx->data, config, NULL),
(GDestroyNotify)detailed_connect_result_free); (GDestroyNotify)detailed_connect_result_free);
detailed_connect_context_complete_and_free (ctx); detailed_connect_context_complete_and_free (ctx);
@@ -453,11 +462,11 @@ typedef struct {
static Dial3gppContext * static Dial3gppContext *
dial_3gpp_context_new (MMBroadbandBearer *self, dial_3gpp_context_new (MMBroadbandBearer *self,
MMBaseModem *modem, MMBaseModem *modem,
MMAtSerialPort *primary, MMAtSerialPort *primary,
GCancellable *cancellable, GCancellable *cancellable,
GAsyncReadyCallback callback, GAsyncReadyCallback callback,
gpointer user_data) gpointer user_data)
{ {
Dial3gppContext *ctx; Dial3gppContext *ctx;
@@ -649,7 +658,7 @@ get_ip_config_3gpp_ready (MMBroadbandModem *modem,
g_simple_async_result_set_op_res_gpointer ( g_simple_async_result_set_op_res_gpointer (
ctx->result, ctx->result,
detailed_connect_result_new (ipv4_config, ipv6_config), detailed_connect_result_new (ctx->data, ipv4_config, ipv6_config),
(GDestroyNotify)detailed_connect_result_free); (GDestroyNotify)detailed_connect_result_free);
detailed_connect_context_complete_and_free (ctx); detailed_connect_context_complete_and_free (ctx);
@@ -677,7 +686,6 @@ dial_3gpp_ready (MMBroadbandModem *modem,
return; return;
} }
if (MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp && if (MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp &&
MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp_finish) { MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp_finish) {
/* Launch specific IP config retrieval */ /* Launch specific IP config retrieval */
@@ -705,7 +713,7 @@ dial_3gpp_ready (MMBroadbandModem *modem,
g_simple_async_result_set_op_res_gpointer ( g_simple_async_result_set_op_res_gpointer (
ctx->result, ctx->result,
detailed_connect_result_new (config, NULL), detailed_connect_result_new (ctx->data, config, NULL),
(GDestroyNotify)detailed_connect_result_free); (GDestroyNotify)detailed_connect_result_free);
detailed_connect_context_complete_and_free (ctx); detailed_connect_context_complete_and_free (ctx);
@@ -1026,7 +1034,7 @@ connect_result_free (ConnectResult *result)
typedef struct { typedef struct {
MMBroadbandBearer *self; MMBroadbandBearer *self;
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
MMPort *data; MMPort *suggested_data;
} ConnectContext; } ConnectContext;
static void static void
@@ -1034,7 +1042,7 @@ connect_context_complete_and_free (ConnectContext *ctx)
{ {
g_simple_async_result_complete_in_idle (ctx->result); g_simple_async_result_complete_in_idle (ctx->result);
g_object_unref (ctx->result); g_object_unref (ctx->result);
g_object_unref (ctx->data); g_object_unref (ctx->suggested_data);
g_object_unref (ctx->self); g_object_unref (ctx->self);
g_free (ctx); g_free (ctx);
} }
@@ -1063,21 +1071,34 @@ connect_finish (MMBearer *self,
static void static void
connect_succeeded (ConnectContext *ctx, connect_succeeded (ConnectContext *ctx,
ConnectionType connection_type, ConnectionType connection_type,
MMPort *data,
MMBearerIpConfig *ipv4_config, MMBearerIpConfig *ipv4_config,
MMBearerIpConfig *ipv6_config) MMBearerIpConfig *ipv6_config)
{ {
ConnectResult *result; ConnectResult *result;
MMPort *real_data;
if (data) {
if (data != ctx->suggested_data)
mm_dbg ("Suggested to use port '%s/%s' for connection, but using '%s/%s' instead",
mm_port_subsys_get_string (mm_port_get_subsys (ctx->suggested_data)),
mm_port_get_device (ctx->suggested_data),
mm_port_subsys_get_string (mm_port_get_subsys (data)),
mm_port_get_device (data));
real_data = data;
} else
real_data = g_object_ref (ctx->suggested_data);
/* Port is connected; update the state */ /* Port is connected; update the state */
mm_port_set_connected (ctx->data, TRUE); mm_port_set_connected (real_data, TRUE);
/* Keep connected port and type of connection */ /* Keep connected port and type of connection */
ctx->self->priv->port = g_object_ref (ctx->data); ctx->self->priv->port = g_object_ref (real_data);
ctx->self->priv->connection_type = connection_type; ctx->self->priv->connection_type = connection_type;
/* Build result */ /* Build result */
result = g_new0 (ConnectResult, 1); result = g_new0 (ConnectResult, 1);
result->data = g_object_ref (ctx->data); result->data = real_data;
result->ipv4_config = ipv4_config; result->ipv4_config = ipv4_config;
result->ipv6_config = ipv6_config; result->ipv6_config = ipv6_config;
@@ -1094,8 +1115,8 @@ connect_failed (ConnectContext *ctx,
GError *error) GError *error)
{ {
/* On errors, close the data port */ /* On errors, close the data port */
if (MM_IS_AT_SERIAL_PORT (ctx->data)) if (MM_IS_AT_SERIAL_PORT (ctx->suggested_data))
mm_serial_port_close (MM_SERIAL_PORT (ctx->data)); mm_serial_port_close (MM_SERIAL_PORT (ctx->suggested_data));
g_simple_async_result_take_error (ctx->result, error); g_simple_async_result_take_error (ctx->result, error);
connect_context_complete_and_free (ctx); connect_context_complete_and_free (ctx);
@@ -1109,15 +1130,17 @@ connect_cdma_ready (MMBroadbandBearer *self,
GError *error = NULL; GError *error = NULL;
MMBearerIpConfig *ipv4_config = NULL; MMBearerIpConfig *ipv4_config = NULL;
MMBearerIpConfig *ipv6_config = NULL; MMBearerIpConfig *ipv6_config = NULL;
MMPort *data = NULL;
if (!MM_BROADBAND_BEARER_GET_CLASS (self)->connect_cdma_finish (self, if (!MM_BROADBAND_BEARER_GET_CLASS (self)->connect_cdma_finish (self,
res, res,
&data,
&ipv4_config, &ipv4_config,
&ipv6_config, &ipv6_config,
&error)) &error))
connect_failed (ctx, error); connect_failed (ctx, error);
else else
connect_succeeded (ctx, CONNECTION_TYPE_CDMA, ipv4_config, ipv6_config); connect_succeeded (ctx, CONNECTION_TYPE_CDMA, data, ipv4_config, ipv6_config);
} }
static void static void
@@ -1128,15 +1151,17 @@ connect_3gpp_ready (MMBroadbandBearer *self,
GError *error = NULL; GError *error = NULL;
MMBearerIpConfig *ipv4_config = NULL; MMBearerIpConfig *ipv4_config = NULL;
MMBearerIpConfig *ipv6_config = NULL; MMBearerIpConfig *ipv6_config = NULL;
MMPort *data = NULL;
if (!MM_BROADBAND_BEARER_GET_CLASS (self)->connect_3gpp_finish (self, if (!MM_BROADBAND_BEARER_GET_CLASS (self)->connect_3gpp_finish (self,
res, res,
&data,
&ipv4_config, &ipv4_config,
&ipv6_config, &ipv6_config,
&error)) &error))
connect_failed (ctx, error); connect_failed (ctx, error);
else else
connect_succeeded (ctx, CONNECTION_TYPE_3GPP, ipv4_config, ipv6_config); connect_succeeded (ctx, CONNECTION_TYPE_3GPP, data, ipv4_config, ipv6_config);
} }
static void static void
@@ -1147,7 +1172,7 @@ connect (MMBearer *self,
{ {
MMBaseModem *modem = NULL; MMBaseModem *modem = NULL;
MMAtSerialPort *primary; MMAtSerialPort *primary;
MMPort *data; MMPort *suggested_data;
ConnectContext *ctx; ConnectContext *ctx;
/* Don't try to connect if already connected */ /* Don't try to connect if already connected */
@@ -1196,8 +1221,8 @@ connect (MMBearer *self,
} }
/* Look for best data port, NULL if none available. */ /* Look for best data port, NULL if none available. */
data = mm_base_modem_peek_best_data_port (modem); suggested_data = mm_base_modem_peek_best_data_port (modem);
if (!data) { if (!suggested_data) {
g_simple_async_report_error_in_idle ( g_simple_async_report_error_in_idle (
G_OBJECT (self), G_OBJECT (self),
callback, callback,
@@ -1214,10 +1239,10 @@ connect (MMBearer *self,
* which is actually always right now, this is already ensured because the * 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 * 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. */ * there's no real problem in keeping an open count here as well. */
if (MM_IS_AT_SERIAL_PORT (data)) { if (MM_IS_AT_SERIAL_PORT (suggested_data)) {
GError *error = NULL; GError *error = NULL;
if (!mm_serial_port_open (MM_SERIAL_PORT (data), &error)) { if (!mm_serial_port_open (MM_SERIAL_PORT (suggested_data), &error)) {
g_prefix_error (&error, "Couldn't connect: cannot keep data port open."); g_prefix_error (&error, "Couldn't connect: cannot keep data port open.");
g_simple_async_report_take_gerror_in_idle ( g_simple_async_report_take_gerror_in_idle (
G_OBJECT (self), G_OBJECT (self),
@@ -1232,7 +1257,7 @@ connect (MMBearer *self,
/* In this context, we only keep the stuff we'll need later */ /* In this context, we only keep the stuff we'll need later */
ctx = g_new0 (ConnectContext, 1); ctx = g_new0 (ConnectContext, 1);
ctx->self = g_object_ref (self); ctx->self = g_object_ref (self);
ctx->data = g_object_ref (data); ctx->suggested_data = g_object_ref (suggested_data);
ctx->result = g_simple_async_result_new (G_OBJECT (self), ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback, callback,
user_data, user_data,
@@ -1247,7 +1272,7 @@ connect (MMBearer *self,
MM_BROADBAND_MODEM (modem), MM_BROADBAND_MODEM (modem),
primary, primary,
mm_base_modem_peek_port_secondary (modem), mm_base_modem_peek_port_secondary (modem),
data, suggested_data,
cancellable, cancellable,
(GAsyncReadyCallback) connect_3gpp_ready, (GAsyncReadyCallback) connect_3gpp_ready,
ctx); ctx);
@@ -1268,7 +1293,7 @@ connect (MMBearer *self,
MM_BROADBAND_MODEM (modem), MM_BROADBAND_MODEM (modem),
primary, primary,
mm_base_modem_peek_port_secondary (modem), mm_base_modem_peek_port_secondary (modem),
data, suggested_data,
cancellable, cancellable,
(GAsyncReadyCallback) connect_cdma_ready, (GAsyncReadyCallback) connect_cdma_ready,
ctx); ctx);
@@ -1288,6 +1313,7 @@ connect (MMBearer *self,
/*****************************************************************************/ /*****************************************************************************/
/* Detailed disconnect context, used in both CDMA and 3GPP sequences */ /* Detailed disconnect context, used in both CDMA and 3GPP sequences */
typedef struct { typedef struct {
MMBroadbandBearer *self; MMBroadbandBearer *self;
MMBaseModem *modem; MMBaseModem *modem;

View File

@@ -62,6 +62,7 @@ struct _MMBroadbandBearerClass {
gpointer user_data); gpointer user_data);
gboolean (* connect_3gpp_finish) (MMBroadbandBearer *self, gboolean (* connect_3gpp_finish) (MMBroadbandBearer *self,
GAsyncResult *res, GAsyncResult *res,
MMPort **data,
MMBearerIpConfig **ipv4_config, MMBearerIpConfig **ipv4_config,
MMBearerIpConfig **ipv6_config, MMBearerIpConfig **ipv6_config,
GError **error); GError **error);
@@ -118,6 +119,7 @@ struct _MMBroadbandBearerClass {
gpointer user_data); gpointer user_data);
gboolean (* connect_cdma_finish) (MMBroadbandBearer *self, gboolean (* connect_cdma_finish) (MMBroadbandBearer *self,
GAsyncResult *res, GAsyncResult *res,
MMPort **data,
MMBearerIpConfig **ipv4_config, MMBearerIpConfig **ipv4_config,
MMBearerIpConfig **ipv6_config, MMBearerIpConfig **ipv6_config,
GError **error); GError **error);