broadband-bearer: let subclasses handle their own IP config retrieval mechanism

Mainly given for bearers requiring static IP addresses in net ports.
This commit is contained in:
Aleksander Morgado
2012-03-16 13:17:06 +01:00
parent 6900348b64
commit cd7d4c3019
2 changed files with 139 additions and 25 deletions

View File

@@ -138,12 +138,44 @@ mm_broadband_bearer_get_3gpp_cid (MMBroadbandBearer *self)
return self->priv->cid;
}
/*****************************************************************************/
/* 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,
@@ -634,11 +669,43 @@ dial_3gpp (MMBroadbandBearer *self,
* 4) Initiate call.
*/
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,

View File

@@ -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,