broadband-modem-qmi: keep the QMI port open for the whole lifetime of the modem

The QMI port is opened during the modem initialization, and kept open until the
modem gets destroyed.
This commit is contained in:
Aleksander Morgado
2012-07-13 12:19:19 +02:00
parent 19da38a330
commit b2ea82ed3b

View File

@@ -29,6 +29,158 @@
G_DEFINE_TYPE (MMBroadbandModemQmi, mm_broadband_modem_qmi, MM_TYPE_BROADBAND_MODEM); G_DEFINE_TYPE (MMBroadbandModemQmi, mm_broadband_modem_qmi, MM_TYPE_BROADBAND_MODEM);
/*****************************************************************************/
/* First initialization step */
typedef struct {
MMBroadbandModem *self;
GSimpleAsyncResult *result;
MMQmiPort *qmi;
QmiService services[32];
guint service_index;
} InitializationStartedContext;
static void
initialization_started_context_complete_and_free (InitializationStartedContext *ctx)
{
g_simple_async_result_complete_in_idle (ctx->result);
if (ctx->qmi)
g_object_unref (ctx->qmi);
g_object_unref (ctx->result);
g_object_unref (ctx->self);
g_free (ctx);
}
static gpointer
initialization_started_finish (MMBroadbandModem *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
/* Just parent's pointer passed here */
return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
}
static void
parent_initialization_started_ready (MMBroadbandModem *self,
GAsyncResult *res,
InitializationStartedContext *ctx)
{
gpointer parent_ctx;
GError *error = NULL;
parent_ctx = MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_parent_class)->initialization_started_finish (
self,
res,
&error);
if (error) {
g_prefix_error (&error, "Couldn't start parent initialization: ");
g_simple_async_result_take_error (ctx->result, error);
} else
g_simple_async_result_set_op_res_gpointer (ctx->result, parent_ctx, NULL);
initialization_started_context_complete_and_free (ctx);
}
static void
parent_initialization_started (InitializationStartedContext *ctx)
{
MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_parent_class)->initialization_started (
ctx->self,
(GAsyncReadyCallback)parent_initialization_started_ready,
ctx);
}
static void allocate_next_client (InitializationStartedContext *ctx);
static void
qmi_port_allocate_client_ready (MMQmiPort *qmi,
GAsyncResult *res,
InitializationStartedContext *ctx)
{
GError *error = NULL;
if (!mm_qmi_port_allocate_client_finish (qmi, res, &error)) {
mm_dbg ("Couldn't allocate client for service '%s': %s",
qmi_service_get_string (ctx->services[ctx->service_index]),
error->message);
g_error_free (error);
}
ctx->service_index++;
allocate_next_client (ctx);
}
static void
allocate_next_client (InitializationStartedContext *ctx)
{
if (ctx->services[ctx->service_index] == QMI_SERVICE_UNKNOWN) {
/* Done we are, launch parent's callback */
parent_initialization_started (ctx);
return;
}
/* Otherwise, allocate next client */
mm_qmi_port_allocate_client (ctx->qmi,
ctx->services[ctx->service_index],
NULL,
(GAsyncReadyCallback)qmi_port_allocate_client_ready,
ctx);
}
static void
qmi_port_open_ready (MMQmiPort *qmi,
GAsyncResult *res,
InitializationStartedContext *ctx)
{
GError *error = NULL;
if (!mm_qmi_port_open_finish (qmi, res, &error)) {
g_simple_async_result_take_error (ctx->result, error);
initialization_started_context_complete_and_free (ctx);
return;
}
allocate_next_client (ctx);
}
static void
initialization_started (MMBroadbandModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
InitializationStartedContext *ctx;
ctx = g_new0 (InitializationStartedContext, 1);
ctx->self = g_object_ref (self);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
initialization_started);
ctx->qmi = mm_base_modem_get_port_qmi (MM_BASE_MODEM (self));
g_assert (ctx->qmi);
if (mm_qmi_port_is_open (ctx->qmi)) {
/* Nothing to be done, just launch parent's callback */
parent_initialization_started (ctx);
return;
}
/* Setup services to open */
ctx->services[0] = QMI_SERVICE_DMS;
ctx->services[1] = QMI_SERVICE_WDS;
ctx->services[2] = QMI_SERVICE_NAS;
ctx->services[3] = QMI_SERVICE_UNKNOWN;
/* Now open our QMI port */
mm_qmi_port_open (ctx->qmi,
NULL,
(GAsyncReadyCallback)qmi_port_open_ready,
ctx);
}
/*****************************************************************************/ /*****************************************************************************/
MMBroadbandModemQmi * MMBroadbandModemQmi *
@@ -52,7 +204,30 @@ mm_broadband_modem_qmi_init (MMBroadbandModemQmi *self)
{ {
} }
static void
finalize (GObject *object)
{
MMQmiPort *qmi;
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (object);
qmi = mm_base_modem_peek_port_qmi (MM_BASE_MODEM (self));
/* If we did open the QMI port during initialization, close it now */
if (qmi &&
mm_qmi_port_is_open (qmi)) {
mm_qmi_port_close (qmi);
}
G_OBJECT_CLASS (mm_broadband_modem_qmi_parent_class)->finalize (object);
}
static void static void
mm_broadband_modem_qmi_class_init (MMBroadbandModemQmiClass *klass) mm_broadband_modem_qmi_class_init (MMBroadbandModemQmiClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass);
MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass);
object_class->finalize = finalize;
broadband_modem_class->initialization_started = initialization_started;
broadband_modem_class->initialization_started_finish = initialization_started_finish;
} }