static void dell_custom_init (MMPortProbe *probe, MMPortSerialAt *port, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CustomInitContext *ctx; GUdevDevice *udevDevice; udevDevice = mm_port_probe_peek_port (probe); ctx = g_slice_new0 (CustomInitContext); ctx->result = g_simple_async_result_new (G_OBJECT (probe), callback, user_data, dell_custom_init); ctx->probe = g_object_ref (probe); ctx->port = g_object_ref (port); ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; ctx->gmi_retries = 3; ctx->cgmi_retries = 3; ctx->ati_retries = 3; /* Dell-branded Telit modems always answer to +GMI * Avoid +CGMI and ATI sending for minimizing port probing time */ if (g_udev_device_get_property_as_boolean (udevDevice, "ID_MM_TELIT_PORTS_TAGGED")) { ctx->cgmi_retries = 0; ctx->ati_retries = 0; } custom_init_step (ctx); }
static void nwdmat_ready (MMPortSerialAt *port, GAsyncResult *res, CustomInitContext *ctx) { const gchar *response; GError *error = NULL; response = mm_port_serial_at_command_finish (port, res, &error); if (error) { if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) { custom_init_step (ctx); goto out; } mm_dbg ("(Novatel) Error flipping secondary ports to AT mode: %s", error->message); } /* Finish custom_init */ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); custom_init_context_complete_and_free (ctx); out: if (error) g_error_free (error); }
static void custom_init_step_next_command (CustomInitContext *ctx) { if (ctx->gmi_retries > 0) ctx->gmi_retries = 0; else if (ctx->cgmi_retries > 0) ctx->cgmi_retries = 0; else if (ctx->ati_retries > 0) ctx->ati_retries = 0; custom_init_step (ctx); }
static void novatel_custom_init (MMPortProbe *probe, MMPortSerialAt *port, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CustomInitContext *ctx; ctx = g_slice_new (CustomInitContext); ctx->result = g_simple_async_result_new (G_OBJECT (probe), callback, user_data, novatel_custom_init); ctx->probe = g_object_ref (probe); ctx->port = g_object_ref (port); ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; ctx->nwdmat_retries = 3; ctx->wait_time = 2; custom_init_step (ctx); }
static void response_ready (MMPortSerialAt *port, GAsyncResult *res, CustomInitContext *ctx) { const gchar *response; GError *error = NULL; gchar *lower; DellManufacturer manufacturer; response = mm_port_serial_at_command_finish (port, res, &error); if (error) { /* Non-timeout error, jump to next command */ if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) { mm_dbg ("(Dell) Error probing AT port: %s", error->message); g_error_free (error); custom_init_step_next_command (ctx); return; } /* Directly retry same command on timeout */ custom_init_step (ctx); g_error_free (error); return; } /* Guess manufacturer from response */ lower = g_ascii_strdown (response, -1); if (strstr (lower, "novatel")) manufacturer = DELL_MANUFACTURER_NOVATEL; else if (strstr (lower, "sierra")) manufacturer = DELL_MANUFACTURER_SIERRA; else if (strstr (lower, "ericsson")) manufacturer = DELL_MANUFACTURER_ERICSSON; else if (strstr (lower, "telit")) manufacturer = DELL_MANUFACTURER_TELIT; else manufacturer = DELL_MANUFACTURER_UNKNOWN; g_free (lower); /* Tag based on manufacturer */ if (manufacturer != DELL_MANUFACTURER_UNKNOWN) { g_object_set_data (G_OBJECT (ctx->probe), TAG_DELL_MANUFACTURER, GUINT_TO_POINTER (manufacturer)); /* Run additional custom init, if needed */ if (manufacturer == DELL_MANUFACTURER_NOVATEL) { mm_common_novatel_custom_init (ctx->probe, ctx->port, ctx->cancellable, (GAsyncReadyCallback) novatel_custom_init_ready, ctx); return; } if (manufacturer == DELL_MANUFACTURER_SIERRA) { mm_common_sierra_custom_init (ctx->probe, ctx->port, ctx->cancellable, (GAsyncReadyCallback) sierra_custom_init_ready, ctx); return; } if (manufacturer == DELL_MANUFACTURER_TELIT) { telit_custom_init (ctx->probe, ctx->port, ctx->cancellable, (GAsyncReadyCallback) telit_custom_init_ready, ctx); return; } /* Finish custom_init */ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); custom_init_context_complete_and_free (ctx); return; } /* If we got a response, but we didn't get an expected string, try with next command */ custom_init_step_next_command (ctx); }
static gboolean custom_init_wait_cb (CustomInitContext *ctx) { custom_init_step (ctx); return FALSE; }