static void allocate_cid_ready (QmiDevice *device, GAsyncResult *res, AllocateCidContext *ctx) { GError *error = NULL; QmiMessage *reply; guint8 cid; QmiService service; reply = qmi_device_command_finish (device, res, &error); if (!reply) { g_prefix_error (&error, "CID allocation failed: "); g_simple_async_result_take_error (ctx->result, error); allocate_cid_context_complete_and_free (ctx); return; } /* Parse reply */ cid = 0; service = QMI_SERVICE_UNKNOWN; if (!qmi_message_ctl_allocate_cid_reply_parse (reply, &cid, &service, &error)) { g_prefix_error (&error, "CID allocation reply parsing failed: "); g_simple_async_result_take_error (ctx->result, error); allocate_cid_context_complete_and_free (ctx); qmi_message_unref (reply); return; } /* The service we got must match the one we requested */ if (service != ctx->service) { g_simple_async_result_set_error (ctx->result, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED, "Service mismatch (%s vs %s)", qmi_service_get_string (service), qmi_service_get_string (ctx->service)); allocate_cid_context_complete_and_free (ctx); qmi_message_unref (reply); return; } g_debug ("Allocated client ID '%u' for service '%s'", cid, qmi_service_get_string (ctx->service)); /* Set the CID as result */ g_simple_async_result_set_op_res_gpointer (ctx->result, GUINT_TO_POINTER ((guint)cid), NULL); allocate_cid_context_complete_and_free (ctx); qmi_message_unref (reply); }
void mm_port_qmi_close (MMPortQmi *self) { GList *l; GError *error = NULL; g_return_if_fail (MM_IS_PORT_QMI (self)); if (!self->priv->qmi_device) return; /* Release all allocated clients */ for (l = self->priv->services; l; l = g_list_next (l)) { ServiceInfo *info = l->data; mm_dbg ("Releasing client for service '%s'...", qmi_service_get_string (info->service)); qmi_device_release_client (self->priv->qmi_device, info->client, QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID, 3, NULL, NULL, NULL); g_clear_object (&info->client); } g_list_free_full (self->priv->services, (GDestroyNotify)g_free); self->priv->services = NULL; /* Close and release the device */ if (!qmi_device_close (self->priv->qmi_device, &error)) { mm_warn ("Couldn't properly close QMI device: %s", error->message); g_error_free (error); } g_clear_object (&self->priv->qmi_device); }
static gboolean ensure_qmi_client (GTask *task, MMSimQmi *self, QmiService service, QmiClient **o_client) { MMBaseModem *modem = NULL; QmiClient *client; MMPortQmi *port; g_object_get (self, MM_BASE_SIM_MODEM, &modem, NULL); g_assert (MM_IS_BASE_MODEM (modem)); port = mm_base_modem_peek_port_qmi (modem); g_object_unref (modem); if (!port) { if (task) { g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't peek QMI port"); g_object_unref (task); } return FALSE; } client = mm_port_qmi_peek_client (port, service, MM_PORT_QMI_FLAG_DEFAULT); if (!client) { if (task) { g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't peek client for service '%s'", qmi_service_get_string (service)); g_object_unref (task); } return FALSE; } *o_client = client; return TRUE; }
void mm_port_qmi_allocate_client (MMPortQmi *self, QmiService service, MMPortQmiFlag flag, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { AllocateClientContext *ctx; if (!!mm_port_qmi_peek_client (self, service, flag)) { g_simple_async_report_error_in_idle (G_OBJECT (self), callback, user_data, MM_CORE_ERROR, MM_CORE_ERROR_EXISTS, "Client for service '%s' already allocated", qmi_service_get_string (service)); return; } ctx = g_new0 (AllocateClientContext, 1); ctx->self = g_object_ref (self); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, mm_port_qmi_allocate_client); ctx->info = g_new0 (ServiceInfo, 1); ctx->info->service = service; ctx->info->flag = flag; qmi_device_allocate_client (self->priv->qmi_device, service, QMI_CID_NONE, 10, cancellable, (GAsyncReadyCallback)allocate_client_ready, ctx); }
static void allocate_client_ready (QmiDevice *qmi_device, GAsyncResult *res, AllocateClientContext *ctx) { GError *error = NULL; ctx->info->client = qmi_device_allocate_client_finish (qmi_device, res, &error); if (!ctx->info->client) { g_prefix_error (&error, "Couldn't create client for service '%s': ", qmi_service_get_string (ctx->info->service)); g_simple_async_result_take_error (ctx->result, error); } else { g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); /* Move the service info to our internal list */ ctx->self->priv->services = g_list_prepend (ctx->self->priv->services, ctx->info); ctx->info = NULL; } allocate_client_context_complete_and_free (ctx); }
gchar * qmi_message_get_printable (QmiMessage *self, const gchar *line_prefix) { GString *printable; gchar *qmi_flags_str; const gchar *qmi_message_str; struct tlv *tlv; if (!qmi_message_check (self, NULL)) return NULL; if (!line_prefix) line_prefix = ""; printable = g_string_new (""); g_string_append_printf (printable, "%sQMUX:\n" "%s length = %u (0x%04x)\n" "%s flags = 0x%02x\n" "%s service = \"%s\" (0x%02x)\n" "%s client = %u (0x%02x)\n", line_prefix, line_prefix, qmux_length (self), qmux_length (self), line_prefix, qmi_message_get_qmux_flags (self), line_prefix, qmi_service_get_string (qmi_message_get_service (self)), qmi_message_get_service (self), line_prefix, qmi_message_get_client_id (self), qmi_message_get_client_id (self)); if (qmi_message_get_service (self) == QMI_SERVICE_CTL) qmi_flags_str = qmi_ctl_flag_build_string_from_mask (qmi_message_get_qmi_flags (self)); else qmi_flags_str = qmi_service_flag_build_string_from_mask (qmi_message_get_qmi_flags (self)); switch (qmi_message_get_service (self)) { case QMI_SERVICE_CTL: qmi_message_str = qmi_ctl_message_get_string (qmi_message_get_message_id (self)); break; case QMI_SERVICE_DMS: qmi_message_str = qmi_dms_message_get_string (qmi_message_get_message_id (self)); break; case QMI_SERVICE_WDS: qmi_message_str = qmi_wds_message_get_string (qmi_message_get_message_id (self)); break; default: qmi_message_str = "unknown"; break; } g_string_append_printf (printable, "%sQMI:\n" "%s flags = \"%s\" (0x%02x)\n" "%s transaction = %u (0x%04x)\n" "%s message = \"%s\" (0x%04x)\n" "%s tlv_length = %u (0x%04x)\n", line_prefix, line_prefix, qmi_flags_str, qmi_message_get_qmi_flags (self), line_prefix, qmi_message_get_transaction_id (self), qmi_message_get_transaction_id (self), line_prefix, qmi_message_str, qmi_message_get_message_id (self), line_prefix, qmi_tlv_length (self), qmi_tlv_length (self)); g_free (qmi_flags_str); for (tlv = qmi_tlv_first (self); tlv; tlv = qmi_tlv_next (self, tlv)) { gchar *value_hex; value_hex = qmi_utils_str_hex (tlv->value, le16toh (tlv->length), ':'); g_string_append_printf (printable, "%sTLV:\n" "%s type = 0x%02x\n" "%s length = %u (0x%04x)\n" "%s value = %s\n", line_prefix, line_prefix, tlv->type, line_prefix, le16toh (tlv->length), le16toh (tlv->length), line_prefix, value_hex); g_free (value_hex); } return g_string_free (printable, FALSE); }