diff options
-rw-r--r-- | plugins/novatel/mm-broadband-modem-novatel.c | 165 |
1 files changed, 93 insertions, 72 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; + goto done; + } - 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); - } + 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); } - /* 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); +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; + } + + /* 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; } - /* 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); + /* 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); + + ctx->cdma1x_state = cdma1x_state; + ctx->evdo_state = evdo_state; - port = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self)); + 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); } |