From dedc1f15c78e64002827581aef7df72a98c55759 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 10 Aug 2016 10:06:58 -0500 Subject: [PATCH] broadband-modem-novatel: clean up detailed registration state handling Allocate the results instead of passing them back on the stack, which removes the "can't complete in idle" restriction. Also always open the QCDM port since we can't assume it will be open already at this point. --- plugins/novatel/mm-broadband-modem-novatel.c | 167 +++++++++++-------- 1 file changed, 94 insertions(+), 73 deletions(-) diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c index f752849d..c431e717 100644 --- a/plugins/novatel/mm-broadband-modem-novatel.c +++ b/plugins/novatel/mm-broadband-modem-novatel.c @@ -898,23 +898,25 @@ messaging_enable_unsolicited_events (MMIfaceModemMessaging *self, /* Detailed registration state (CDMA interface) */ typedef struct { - MMModemCdmaRegistrationState detailed_cdma1x_state; - MMModemCdmaRegistrationState detailed_evdo_state; -} DetailedRegistrationStateResults; + MMModemCdmaRegistrationState cdma1x_state; + MMModemCdmaRegistrationState evdo_state; +} DetailedRegistrationStateResult; typedef struct { - MMBroadbandModem *self; - GSimpleAsyncResult *result; - DetailedRegistrationStateResults state; + MMPortSerialQcdm *port; + gboolean close_port; + MMModemCdmaRegistrationState cdma1x_state; + MMModemCdmaRegistrationState evdo_state; } DetailedRegistrationStateContext; static void -detailed_registration_state_context_complete_and_free (DetailedRegistrationStateContext *ctx) +detailed_registration_state_context_free (DetailedRegistrationStateContext *ctx) { - /* Always not in idle! we're passing a struct in stack as result */ - g_simple_async_result_complete (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->self); + if (ctx->port) { + if (ctx->close_port) + mm_port_serial_close (MM_PORT_SERIAL (ctx->port)); + g_object_unref (ctx->port); + } g_free (ctx); } @@ -925,14 +927,14 @@ modem_cdma_get_detailed_registration_state_finish (MMIfaceModemCdma *self, MMModemCdmaRegistrationState *detailed_evdo_state, GError **error) { - DetailedRegistrationStateResults *results; + GTask *task = G_TASK (res); + DetailedRegistrationStateContext *ctx = g_task_get_task_data (task);; - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + if (!g_task_propagate_boolean (task, error)) return FALSE; - results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - *detailed_cdma1x_state = results->detailed_cdma1x_state; - *detailed_evdo_state = results->detailed_evdo_state; + *detailed_cdma1x_state = ctx->cdma1x_state; + *detailed_evdo_state = ctx->evdo_state; return TRUE; } @@ -984,84 +986,86 @@ parse_modem_eri (DetailedRegistrationStateContext *ctx, QcdmResult *result) else new_state = MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING; - if (ctx->state.detailed_cdma1x_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) - ctx->state.detailed_cdma1x_state = new_state; - if (ctx->state.detailed_evdo_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) - ctx->state.detailed_evdo_state = new_state; + if (ctx->cdma1x_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) + ctx->cdma1x_state = new_state; + if (ctx->evdo_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) + ctx->evdo_state = new_state; } static void reg_eri_6500_cb (MMPortSerialQcdm *port, GAsyncResult *res, - DetailedRegistrationStateContext *ctx) + GTask *task) { + DetailedRegistrationStateContext *ctx = g_task_get_task_data (task); GError *error = NULL; GByteArray *response; + QcdmResult *result; response = mm_port_serial_qcdm_command_finish (port, res, &error); if (error) { /* Just ignore the error and complete with the input info */ mm_dbg ("Couldn't run QCDM MSM6500 ERI: '%s'", error->message); g_error_free (error); - } else { - QcdmResult *result; - - result = qcdm_cmd_nw_subsys_eri_result ((const gchar *) response->data, response->len, NULL); - g_byte_array_unref (response); - if (result) { - parse_modem_eri (ctx, result); - qcdm_result_unref (result); - } + goto done; } - /* NOTE: always complete NOT in idle here */ - g_simple_async_result_set_op_res_gpointer (ctx->result, &ctx->state, NULL); - detailed_registration_state_context_complete_and_free (ctx); + result = qcdm_cmd_nw_subsys_eri_result ((const gchar *) response->data, response->len, NULL); + g_byte_array_unref (response); + if (result) { + parse_modem_eri (ctx, result); + qcdm_result_unref (result); + } + +done: + g_task_return_boolean (task, TRUE); + g_object_unref (task); } static void reg_eri_6800_cb (MMPortSerialQcdm *port, GAsyncResult *res, - DetailedRegistrationStateContext *ctx) + GTask *task) { + DetailedRegistrationStateContext *ctx = g_task_get_task_data (task); GError *error = NULL; GByteArray *response; + GByteArray *nweri; + QcdmResult *result; response = mm_port_serial_qcdm_command_finish (port, res, &error); if (error) { /* Just ignore the error and complete with the input info */ mm_dbg ("Couldn't run QCDM MSM6800 ERI: '%s'", error->message); g_error_free (error); - } else { - QcdmResult *result; - - /* Parse the response */ - result = qcdm_cmd_nw_subsys_eri_result ((const gchar *) response->data, response->len, NULL); - g_byte_array_unref (response); - if (result) { - parse_modem_eri (ctx, result); - qcdm_result_unref (result); - } else { - GByteArray *nweri; - - /* Try for MSM6500 */ - nweri = g_byte_array_sized_new (25); - nweri->len = qcdm_cmd_nw_subsys_eri_new ((char *) nweri->data, 25, QCDM_NW_CHIPSET_6500); - g_assert (nweri->len); - mm_port_serial_qcdm_command (port, - nweri, - 3, - NULL, - (GAsyncReadyCallback)reg_eri_6500_cb, - ctx); - g_byte_array_unref (nweri); - return; - } + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; } - /* NOTE: always complete NOT in idle here */ - g_simple_async_result_set_op_res_gpointer (ctx->result, &ctx->state, NULL); - detailed_registration_state_context_complete_and_free (ctx); + /* Parse the response */ + result = qcdm_cmd_nw_subsys_eri_result ((const gchar *) response->data, response->len, NULL); + g_byte_array_unref (response); + if (result) { + /* Success */ + parse_modem_eri (ctx, result); + qcdm_result_unref (result); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + /* Try for MSM6500 */ + nweri = g_byte_array_sized_new (25); + nweri->len = qcdm_cmd_nw_subsys_eri_new ((char *) nweri->data, 25, QCDM_NW_CHIPSET_6500); + g_assert (nweri->len); + mm_port_serial_qcdm_command (port, + nweri, + 3, + NULL, + (GAsyncReadyCallback)reg_eri_6500_cb, + task); + g_byte_array_unref (nweri); } static void @@ -1072,31 +1076,48 @@ modem_cdma_get_detailed_registration_state (MMIfaceModemCdma *self, gpointer user_data) { DetailedRegistrationStateContext *ctx; + GTask *task; GByteArray *nweri; - MMPortSerialQcdm *port; + GError *error = NULL; /* Setup context */ + task = g_task_new (self, NULL, callback, user_data); ctx = g_new0 (DetailedRegistrationStateContext, 1); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_cdma_get_detailed_registration_state); - ctx->state.detailed_cdma1x_state = cdma1x_state; - ctx->state.detailed_evdo_state = evdo_state; + g_task_set_task_data (task, ctx, (GDestroyNotify) detailed_registration_state_context_free); - port = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self)); + ctx->cdma1x_state = cdma1x_state; + ctx->evdo_state = evdo_state; + + ctx->port = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self)); + if (!ctx->port) { + /* Ignore errors and use non-detailed registration state */ + mm_dbg ("No available QCDM port."); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->port), &error)) { + /* Ignore errors and use non-detailed registration state */ + mm_dbg ("Couldn't open QCDM port: %s", error->message); + g_error_free (error); + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + ctx->close_port = TRUE; /* Try MSM6800 first since newer cards use that */ nweri = g_byte_array_sized_new (25); nweri->len = qcdm_cmd_nw_subsys_eri_new ((char *) nweri->data, 25, QCDM_NW_CHIPSET_6800); g_assert (nweri->len); - mm_port_serial_qcdm_command (port, + mm_port_serial_qcdm_command (ctx->port, nweri, 3, NULL, (GAsyncReadyCallback)reg_eri_6800_cb, - ctx); + task); g_byte_array_unref (nweri); }