diff options
author | Dan Williams <dcbw@redhat.com> | 2016-08-10 09:45:29 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2017-04-17 11:59:12 -0500 |
commit | 77fbcf534b8f787f55db549a9e651cc9e8959198 (patch) | |
tree | 05192be28096709e28f433dfd8e10026a5b1c20c | |
parent | 01cba808e4c333744fcf5d27d2d58ef1b5cdc812 (diff) |
broadband-modem-novatel: clean up access technology reporting
Instead of mixing the QCDM Novatel Snapshot code directly into the
access technology checking code, split it out with its own async
result. At the same time, make sure to open the QCDM port when
it's needed, instead of assuming its already open. Since it won't
always be.
-rw-r--r-- | plugins/novatel/mm-broadband-modem-novatel.c | 286 |
1 files changed, 145 insertions, 141 deletions
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c index 9fd14e2b..f752849d 100644 --- a/plugins/novatel/mm-broadband-modem-novatel.c +++ b/plugins/novatel/mm-broadband-modem-novatel.c @@ -397,107 +397,84 @@ set_current_modes (MMIfaceModem *self, } /*****************************************************************************/ -/* Load access technologies (Modem interface) */ - -typedef struct { - guint hdr_revision; /* QCDM_HDR_REV_x */ - MMModemAccessTechnology generic_act; - guint mask; -} SnapshotResult; - -typedef struct { - MMBaseModem *self; - MMPortSerialQcdm *port; - GSimpleAsyncResult *simple; - MMModemAccessTechnology generic_act; - guint mask; -} SnapshotContext; static void -snapshot_result_complete (GSimpleAsyncResult *simple, - guint hdr_revision, - MMModemAccessTechnology generic_act, - guint mask) +close_and_unref_port (MMPortSerialQcdm *port) { - SnapshotResult *r; - - r = g_new0 (SnapshotResult, 1); - r->hdr_revision = hdr_revision; - r->generic_act = generic_act; - r->mask = mask; - - g_simple_async_result_set_op_res_gpointer (simple, r, g_free); - g_simple_async_result_complete (simple); + mm_port_serial_close (MM_PORT_SERIAL (port)); + g_object_unref (port); } -static void -snapshot_result_complete_simple (GSimpleAsyncResult *simple, - MMModemAccessTechnology generic_act, - guint mask) +static gboolean +get_evdo_version_finish (MMBaseModem *self, + GAsyncResult *res, + guint *hdr_revision, /* QCDM_HDR_REV_* */ + GError **error) { - snapshot_result_complete (simple, QCDM_HDR_REV_UNKNOWN, generic_act, mask); -} + gssize result; -static void -snapshot_context_complete_and_free (SnapshotContext *ctx, guint hdr_revision) -{ - snapshot_result_complete (ctx->simple, - hdr_revision, - ctx->generic_act, - ctx->mask); - g_object_unref (ctx->simple); - g_object_unref (ctx->self); - g_object_unref (ctx->port); - g_free (ctx); + result = g_task_propagate_int (G_TASK (res), error); + if (result < 0) + return FALSE; + + *hdr_revision = (guint8) result; + return TRUE; } static void -nw_snapshot_old_cb (MMPortSerialQcdm *port, - GAsyncResult *res, - SnapshotContext *ctx) +nw_snapshot_old_ready (MMPortSerialQcdm *port, + GAsyncResult *res, + GTask *task) { QcdmResult *result; - guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN; GError *error = NULL; GByteArray *response; + guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN; 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 Novatel Modem MSM6500 snapshot: '%s'", error->message); - g_error_free (error); - snapshot_context_complete_and_free (ctx, QCDM_HDR_REV_UNKNOWN); + g_task_return_error (task, error); + g_object_unref (task); return; } /* Parse the response */ result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const gchar *) response->data, response->len, NULL); g_byte_array_unref (response); - if (result) { - qcdm_result_get_u8 (result, QCDM_CMD_NW_SUBSYS_MODEM_SNAPSHOT_CDMA_ITEM_HDR_REV, &hdr_revision); + if (!result) { qcdm_result_unref (result); - } else - mm_dbg ("Failed to get QCDM Novatel Modem MSM6500 snapshot."); + mm_dbg ("Failed to get QCDM Novatel Modem MSM6500 snapshot: %s", error->message); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* Success */ + qcdm_result_get_u8 (result, QCDM_CMD_NW_SUBSYS_MODEM_SNAPSHOT_CDMA_ITEM_HDR_REV, &hdr_revision); + qcdm_result_unref (result); - snapshot_context_complete_and_free (ctx, hdr_revision); + g_task_return_int (task, (gint) hdr_revision); + g_object_unref (task); } static void -nw_snapshot_new_cb (MMPortSerialQcdm *port, - GAsyncResult *res, - SnapshotContext *ctx) +nw_snapshot_new_ready (MMPortSerialQcdm *port, + GAsyncResult *res, + GTask *task) { QcdmResult *result; GByteArray *nwsnap; - guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN; GError *error = NULL; GByteArray *response; + guint8 hdr_revision = QCDM_HDR_REV_UNKNOWN; response = mm_port_serial_qcdm_command_finish (port, res, &error); if (error) { mm_dbg ("Couldn't run QCDM Novatel Modem MSM6800 snapshot: '%s'", error->message); - g_error_free (error); - snapshot_context_complete_and_free (ctx, QCDM_HDR_REV_UNKNOWN); + g_task_return_error (task, error); + g_object_unref (task); return; } @@ -505,9 +482,12 @@ nw_snapshot_new_cb (MMPortSerialQcdm *port, result = qcdm_cmd_nw_subsys_modem_snapshot_cdma_result ((const gchar *) response->data, response->len, NULL); g_byte_array_unref (response); if (result) { + /* Success */ qcdm_result_get_u8 (result, QCDM_CMD_NW_SUBSYS_MODEM_SNAPSHOT_CDMA_ITEM_HDR_REV, &hdr_revision); qcdm_result_unref (result); - snapshot_context_complete_and_free (ctx, hdr_revision); + + g_task_return_int (task, (gint) hdr_revision); + g_object_unref (task); return; } @@ -521,32 +501,40 @@ nw_snapshot_new_cb (MMPortSerialQcdm *port, nwsnap, 3, NULL, - (GAsyncReadyCallback)nw_snapshot_old_cb, - ctx); + (GAsyncReadyCallback)nw_snapshot_old_ready, + task); g_byte_array_unref (nwsnap); } -static gboolean -get_nw_modem_snapshot (MMBaseModem *self, - GSimpleAsyncResult *simple, - MMModemAccessTechnology generic_act, - guint mask) +static void +get_evdo_version (MMBaseModem *self, + GAsyncReadyCallback callback, + gpointer user_data) { - SnapshotContext *ctx; + GError *error = NULL; GByteArray *nwsnap; + GTask *task; MMPortSerialQcdm *port; - port = mm_base_modem_peek_port_qcdm (self); - if (!port) - return FALSE; + task = g_task_new (self, NULL, callback, user_data); - /* Setup context */ - ctx = g_new0 (SnapshotContext, 1); - ctx->self = g_object_ref (self); - ctx->port = g_object_ref (port); - ctx->simple = simple; - ctx->generic_act = generic_act; - ctx->mask = mask; + port = mm_base_modem_get_port_qcdm (self); + if (!port) { + error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "No available QCDM port."); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + g_task_set_task_data (task, port, (GDestroyNotify) close_and_unref_port); + + if (!mm_port_serial_open (MM_PORT_SERIAL (port), &error)) { + g_prefix_error (&error, "Couldn't open QCDM port: "); + g_task_return_error (task, error); + g_object_unref (task); + return; + } /* Try MSM6800 first since newer cards use that */ nwsnap = g_byte_array_sized_new (25); @@ -556,12 +544,20 @@ get_nw_modem_snapshot (MMBaseModem *self, nwsnap, 3, NULL, - (GAsyncReadyCallback)nw_snapshot_new_cb, - ctx); + (GAsyncReadyCallback)nw_snapshot_new_ready, + task); g_byte_array_unref (nwsnap); - return TRUE; } +/*****************************************************************************/ +/* Load access technologies (Modem interface) */ + +typedef struct { + MMModemAccessTechnology act; + guint mask; + guint hdr_revision; /* QCDM_HDR_REV_* */ +} AccessTechContext; + static gboolean modem_load_access_technologies_finish (MMIfaceModem *self, GAsyncResult *res, @@ -569,48 +565,45 @@ modem_load_access_technologies_finish (MMIfaceModem *self, guint *mask, GError **error) { - SnapshotResult *r; - MMModemAccessTechnology act; + GTask *task = G_TASK (res); + AccessTechContext *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; - r = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - - act = r->generic_act; - if (act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK) { - /* Update access technology with specific EVDO revision from QCDM */ - if (r->hdr_revision == QCDM_HDR_REV_0) { + /* Update access technology with specific EVDO revision from QCDM if we have them */ + if (ctx->act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK) { + if (ctx->hdr_revision == QCDM_HDR_REV_0) { mm_dbg ("Novatel Modem Snapshot EVDO revision: 0"); - act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK; - act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDO0; - } else if (r->hdr_revision == QCDM_HDR_REV_A) { + ctx->act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK; + ctx->act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDO0; + } else if (ctx->hdr_revision == QCDM_HDR_REV_A) { mm_dbg ("Novatel Modem Snapshot EVDO revision: A"); - act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK; - act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDOA; + ctx->act &= ~MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK; + ctx->act |= MM_MODEM_ACCESS_TECHNOLOGY_EVDOA; } else - mm_dbg ("Novatel Modem Snapshot EVDO revision: %d (unknown)", r->hdr_revision); + mm_dbg ("Novatel Modem Snapshot EVDO revision: %d (unknown)", ctx->hdr_revision); } - *access_technologies = act; - *mask = r->mask; + *access_technologies = ctx->act; + *mask = ctx->mask; return TRUE; } static void cnti_set_ready (MMBaseModem *self, GAsyncResult *res, - GSimpleAsyncResult *simple) + GTask *task) { + AccessTechContext *ctx = g_task_get_task_data (task); GError *error = NULL; const gchar *response; const gchar *p; response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); if (!response) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + g_task_return_error (task, error); + g_object_unref (task); return; } @@ -621,55 +614,64 @@ cnti_set_ready (MMBaseModem *self, MM_CORE_ERROR_FAILED, "Couldn't parse $CNTI result '%s'", response); - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + g_task_return_error (task, error); + g_object_unref (task); return; } - snapshot_result_complete_simple (simple, - mm_string_to_access_tech (p), - MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK); - g_object_unref (simple); + ctx->act = mm_string_to_access_tech (p); + ctx->mask = MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK; + g_task_return_boolean (task, TRUE); + g_object_unref (task); +} + +static void +evdo_version_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + AccessTechContext *ctx = g_task_get_task_data (task); + + if (!get_evdo_version_finish (self, res, &ctx->hdr_revision, &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + g_task_return_boolean (task, TRUE); + g_object_unref (task); } static void parent_load_access_technologies_ready (MMIfaceModem *self, GAsyncResult *res, - GSimpleAsyncResult *simple) + GTask *task) { - MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; - guint mask = 0; GError *error = NULL; + AccessTechContext *ctx = g_task_get_task_data (task); if (!iface_modem_parent->load_access_technologies_finish (self, res, - &act, - &mask, + &ctx->act, + &ctx->mask, &error)) { - g_simple_async_result_take_error (simple, error); - g_simple_async_result_complete (simple); - g_object_unref (simple); + g_task_return_error (task, error); + g_object_unref (task); return; } - /* No point in checking EVDO revision if EVDO isn't being used or if for - * some reason we don't have a QCDM port. - */ - if (!(act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK)) { - snapshot_result_complete (simple, QCDM_HDR_REV_UNKNOWN, act, mask); - g_object_unref (simple); + /* No point in checking EVDO revision if EVDO isn't being used */ + if (!(ctx->act & MM_IFACE_MODEM_CDMA_ALL_EVDO_ACCESS_TECHNOLOGIES_MASK)) { + g_task_return_boolean (task, TRUE); + g_object_unref (task); return; } - /* Pass along the access tech & mask that the parent determined so we - * can specialize it based on the EVDO revision from QCDM. - */ - if (!get_nw_modem_snapshot (MM_BASE_MODEM (self), simple, act, mask)) { - /* If there's any error, use the access tech that the parent interface determined */ - snapshot_result_complete (simple, QCDM_HDR_REV_UNKNOWN, act, mask); - g_object_unref (simple); - } + /* Get the EVDO revision from QCDM */ + get_evdo_version (MM_BASE_MODEM (self), + (GAsyncReadyCallback) evdo_version_ready, + task); } static void @@ -677,12 +679,14 @@ modem_load_access_technologies (MMIfaceModem *self, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *result; + AccessTechContext *ctx; + GTask *task; - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_load_access_technologies); + /* Setup context */ + task = g_task_new (self, NULL, callback, user_data); + + ctx = g_new0 (AccessTechContext, 1); + g_task_set_task_data (task, ctx, g_free); /* CDMA-only modems defer to parent for generic access technology * checking, but can determine EVDOr0 vs. EVDOrA through proprietary @@ -692,7 +696,7 @@ modem_load_access_technologies (MMIfaceModem *self, iface_modem_parent->load_access_technologies ( self, (GAsyncReadyCallback)parent_load_access_technologies_ready, - result); + task); return; } @@ -702,7 +706,7 @@ modem_load_access_technologies (MMIfaceModem *self, 3, FALSE, (GAsyncReadyCallback)cnti_set_ready, - result); + task); } /*****************************************************************************/ |