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:
@@ -29,6 +29,158 @@
|
||||
|
||||
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 *
|
||||
@@ -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
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user