diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-16 13:17:06 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-16 14:53:26 +0100 |
commit | cd7d4c301928f25ece4dfba903fe2f6dedd14100 (patch) | |
tree | d71c16184bc6f5bf489091ba8815c26ce8020247 | |
parent | 6900348b643a762ed26834af86410ede83f67da2 (diff) |
broadband-bearer: let subclasses handle their own IP config retrieval mechanism
Mainly given for bearers requiring static IP addresses in net ports.
-rw-r--r-- | src/mm-broadband-bearer.c | 148 | ||||
-rw-r--r-- | src/mm-broadband-bearer.h | 16 |
2 files changed, 139 insertions, 25 deletions
diff --git a/src/mm-broadband-bearer.c b/src/mm-broadband-bearer.c index 034bf545..309fadd0 100644 --- a/src/mm-broadband-bearer.c +++ b/src/mm-broadband-bearer.c @@ -139,11 +139,43 @@ mm_broadband_bearer_get_3gpp_cid (MMBroadbandBearer *self) } /*****************************************************************************/ +/* Detailed connect result, used in both CDMA and 3GPP sequences */ +typedef struct { + MMBearerIpConfig *ipv4_config; + MMBearerIpConfig *ipv6_config; +} DetailedConnectResult; + +static void +detailed_connect_result_free (DetailedConnectResult *result) +{ + if (result->ipv4_config) + g_object_unref (result->ipv4_config); + if (result->ipv6_config) + g_object_unref (result->ipv6_config); + g_free (result); +} + +static DetailedConnectResult * +detailed_connect_result_new (MMBearerIpConfig *ipv4_config, + MMBearerIpConfig *ipv6_config) +{ + DetailedConnectResult *result; + + result = g_new0 (DetailedConnectResult, 1); + if (ipv4_config) + result->ipv4_config = g_object_ref (ipv4_config); + if (ipv6_config) + result->ipv6_config = g_object_ref (ipv6_config); + return result; +} + +/*****************************************************************************/ /* Detailed connect context, used in both CDMA and 3GPP sequences */ typedef struct { MMBroadbandBearer *self; MMBaseModem *modem; MMAtSerialPort *primary; + MMAtSerialPort *secondary; MMPort *data; GCancellable *cancellable; GSimpleAsyncResult *result; @@ -160,16 +192,15 @@ detailed_connect_finish (MMBroadbandBearer *self, MMBearerIpConfig **ipv6_config, GError **error) { - MMBearerIpConfig *config; + DetailedConnectResult *result; if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) return FALSE; - config = 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)); - /* In the default implementation, we assume we'll have the same configs */ - *ipv4_config = g_object_ref (config); - *ipv6_config = g_object_ref (config); + *ipv4_config = (result->ipv4_config ? g_object_ref (result->ipv4_config) : NULL); + *ipv6_config = (result->ipv6_config ? g_object_ref (result->ipv6_config) : NULL); return TRUE; } @@ -181,28 +212,13 @@ detailed_connect_context_complete_and_free (DetailedConnectContext *ctx) g_object_unref (ctx->cancellable); g_object_unref (ctx->data); g_object_unref (ctx->primary); + if (ctx->secondary) + g_object_unref (ctx->secondary); g_object_unref (ctx->self); g_object_unref (ctx->modem); g_free (ctx); } -static void -detailed_connect_context_complete_and_free_successful (DetailedConnectContext *ctx) -{ - MMBearerIpConfig *config; - - /* If serial port, set PPP method. Otherwise, assume DHCP is needed. */ - config = mm_bearer_ip_config_new (); - mm_bearer_ip_config_set_method (config, - (MM_IS_AT_SERIAL_PORT (ctx->data) ? - MM_BEARER_IP_METHOD_PPP : - MM_BEARER_IP_METHOD_DHCP)); - g_simple_async_result_set_op_res_gpointer (ctx->result, - config, - (GDestroyNotify)g_object_unref); - detailed_connect_context_complete_and_free (ctx); -} - static gboolean detailed_connect_context_set_error_if_cancelled (DetailedConnectContext *ctx, GError **error) @@ -234,6 +250,7 @@ static DetailedConnectContext * detailed_connect_context_new (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, + MMAtSerialPort *secondary, MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -245,6 +262,7 @@ detailed_connect_context_new (MMBroadbandBearer *self, ctx->self = g_object_ref (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, @@ -274,6 +292,7 @@ dial_cdma_ready (MMBaseModem *modem, DetailedConnectContext *ctx) { GError *error = NULL; + MMBearerIpConfig *config; /* DO NOT check for cancellable here. If we got here without errors, the * bearer is really connected and therefore we need to reflect that in @@ -287,7 +306,22 @@ dial_cdma_ready (MMBaseModem *modem, } /* else... Yuhu! */ - detailed_connect_context_complete_and_free_successful (ctx); + + /* If serial port, set PPP method. Otherwise, assume DHCP is needed. */ + config = mm_bearer_ip_config_new (); + mm_bearer_ip_config_set_method (config, + (MM_IS_AT_SERIAL_PORT (ctx->data) ? + MM_BEARER_IP_METHOD_PPP : + MM_BEARER_IP_METHOD_DHCP)); + + /* Assume only IPv4 is given */ + g_simple_async_result_set_op_res_gpointer ( + ctx->result, + detailed_connect_result_new (config, NULL), + (GDestroyNotify)detailed_connect_result_free); + detailed_connect_context_complete_and_free (ctx); + + g_object_unref (config); } static void @@ -422,6 +456,7 @@ connect_cdma (MMBroadbandBearer *self, ctx = detailed_connect_context_new (self, modem, primary, + NULL, data, cancellable, callback, @@ -635,10 +670,42 @@ dial_3gpp (MMBroadbandBearer *self, */ static void +get_ip_config_3gpp_ready (MMBroadbandModem *modem, + GAsyncResult *res, + DetailedConnectContext *ctx) +{ + MMBearerIpConfig *ipv4_config = NULL; + MMBearerIpConfig *ipv6_config = NULL; + GError *error = NULL; + + if (!MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp_finish (ctx->self, + res, + &ipv4_config, + &ipv6_config, + &error)) { + g_simple_async_result_take_error (ctx->result, error); + detailed_connect_context_complete_and_free (ctx); + return; + } + + g_simple_async_result_set_op_res_gpointer ( + ctx->result, + detailed_connect_result_new (ipv4_config, ipv6_config), + (GDestroyNotify)detailed_connect_result_free); + detailed_connect_context_complete_and_free (ctx); + + if (ipv4_config) + g_object_unref (ipv4_config); + if (ipv6_config) + g_object_unref (ipv6_config); +} + +static void dial_3gpp_ready (MMBroadbandModem *modem, GAsyncResult *res, DetailedConnectContext *ctx) { + MMBearerIpConfig *config; GError *error = NULL; if (!MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->dial_3gpp_finish (ctx->self, @@ -652,8 +719,38 @@ dial_3gpp_ready (MMBroadbandModem *modem, /* Keep CID around while connected */ ctx->self->priv->cid = ctx->cid; + 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 */ + MM_BROADBAND_BEARER_GET_CLASS (ctx->self)->get_ip_config_3gpp ( + ctx->self, + MM_BROADBAND_MODEM (ctx->modem), + ctx->primary, + ctx->secondary, + ctx->data, + ctx->cid, + (GAsyncReadyCallback)get_ip_config_3gpp_ready, + ctx); + return; + } + /* Yuhu! */ - detailed_connect_context_complete_and_free_successful (ctx); + + /* If no specific IP retrieval requested, set the default implementation + * (PPP if data port is AT, DHCP otherwise) */ + config = mm_bearer_ip_config_new (); + mm_bearer_ip_config_set_method (config, + (MM_IS_AT_SERIAL_PORT (ctx->data) ? + MM_BEARER_IP_METHOD_PPP : + MM_BEARER_IP_METHOD_DHCP)); + + g_simple_async_result_set_op_res_gpointer ( + ctx->result, + detailed_connect_result_new (config, NULL), + (GDestroyNotify)detailed_connect_result_free); + detailed_connect_context_complete_and_free (ctx); + + g_object_unref (config); } static void @@ -897,7 +994,7 @@ static void connect_3gpp (MMBroadbandBearer *self, MMBroadbandModem *modem, MMAtSerialPort *primary, - MMAtSerialPort *secondary, /* unused by us */ + MMAtSerialPort *secondary, MMPort *data, GCancellable *cancellable, GAsyncReadyCallback callback, @@ -910,6 +1007,7 @@ connect_3gpp (MMBroadbandBearer *self, ctx = detailed_connect_context_new (self, modem, primary, + secondary, data, cancellable, callback, diff --git a/src/mm-broadband-bearer.h b/src/mm-broadband-bearer.h index a7619e51..8c2b2ac7 100644 --- a/src/mm-broadband-bearer.h +++ b/src/mm-broadband-bearer.h @@ -78,6 +78,22 @@ struct _MMBroadbandBearerClass { GAsyncResult *res, GError **error); + /* IP config retrieval sub-part of 3GPP connection. + * Only really required when using net port + static IP address. */ + void (* get_ip_config_3gpp) (MMBroadbandBearer *self, + MMBroadbandModem *modem, + MMAtSerialPort *primary, + MMAtSerialPort *secondary, + MMPort *data, + guint cid, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* get_ip_config_3gpp_finish) (MMBroadbandBearer *self, + GAsyncResult *res, + MMBearerIpConfig **ipv4_config, + MMBearerIpConfig **ipv6_config, + GError **error); + /* Full 3GPP disconnection sequence */ void (* disconnect_3gpp) (MMBroadbandBearer *self, MMBroadbandModem *modem, |