mirror of
https://github.com/estkme-group/lpac
synced 2025-06-29 08:12:57 +02:00
While the QMI driver which goes to /dev/foobar wants to go through the
qmi-proxy to not have to exclusively claim the device, the QMI-over-QRTR
driver doesn't work with the PROXY flag and just leads to the error
error: open QMI device failed: endpoint hangup
Fix this by passing the correct flag to qmi_device_open from both APDU
drivers.
Closes: #215
Fixes: 3bde4a1
(" driver(APDU): add QMI backend (#131)")
Co-authored-by: Luca Weiss <luca.weiss@fairphone.com>
234 lines
6.5 KiB
C
234 lines
6.5 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright (c) 2024, Luca Weiss <luca.weiss@fairphone.com>
|
|
*/
|
|
|
|
#include "qmi_helpers.h"
|
|
|
|
static void
|
|
async_result_ready(GObject *source_object,
|
|
GAsyncResult *res,
|
|
gpointer user_data)
|
|
{
|
|
GAsyncResult **result_out = user_data;
|
|
|
|
g_assert(*result_out == NULL);
|
|
*result_out = g_object_ref(res);
|
|
}
|
|
|
|
#ifdef LPAC_WITH_APDU_QMI_QRTR
|
|
QrtrBus *
|
|
qrtr_bus_new_sync(GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qrtr_bus_new(1000, /* ms */
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qrtr_bus_new_finish(result, error);
|
|
}
|
|
|
|
QmiDevice *
|
|
qmi_device_new_from_node_sync(QrtrNode *node,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_device_new_from_node(node,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_device_new_from_node_finish(result, error);
|
|
}
|
|
#endif
|
|
|
|
#ifdef LPAC_WITH_APDU_QMI
|
|
QmiDevice *
|
|
qmi_device_new_from_path(GFile *file,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
g_autofree gchar *id = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
id = g_file_get_path (file);
|
|
if (id)
|
|
qmi_device_new(file,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_device_new_finish(result, error);
|
|
}
|
|
#endif
|
|
|
|
gboolean
|
|
qmi_device_open_sync(QmiDevice *device,
|
|
QmiDeviceOpenFlags flags,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_device_open(device,
|
|
flags,
|
|
15,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_device_open_finish(device, result, error);
|
|
}
|
|
|
|
QmiClient *
|
|
qmi_device_allocate_client_sync(QmiDevice *device,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_device_allocate_client(device,
|
|
QMI_SERVICE_UIM,
|
|
QMI_CID_NONE,
|
|
10,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_device_allocate_client_finish(device, result, error);
|
|
}
|
|
|
|
gboolean
|
|
qmi_device_release_client_sync(QmiDevice *device,
|
|
QmiClient *client,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_device_release_client(device,
|
|
client,
|
|
QMI_DEVICE_RELEASE_CLIENT_FLAGS_RELEASE_CID,
|
|
10,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_device_release_client_finish(device, result, error);
|
|
}
|
|
|
|
QmiMessageUimOpenLogicalChannelOutput *
|
|
qmi_client_uim_open_logical_channel_sync(
|
|
QmiClientUim *client,
|
|
QmiMessageUimOpenLogicalChannelInput *input,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_client_uim_open_logical_channel(client,
|
|
input,
|
|
10,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_client_uim_open_logical_channel_finish(client, result, error);
|
|
}
|
|
|
|
QmiMessageUimLogicalChannelOutput *
|
|
qmi_client_uim_logical_channel_sync(
|
|
QmiClientUim *client,
|
|
QmiMessageUimLogicalChannelInput *input,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_client_uim_logical_channel(client,
|
|
input,
|
|
10,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_client_uim_logical_channel_finish(client, result, error);
|
|
}
|
|
|
|
QmiMessageUimSendApduOutput *
|
|
qmi_client_uim_send_apdu_sync(
|
|
QmiClientUim *client,
|
|
QmiMessageUimSendApduInput *input,
|
|
GMainContext *context,
|
|
GError **error)
|
|
{
|
|
g_autoptr(GMainContextPusher) pusher = NULL;
|
|
g_autoptr(GAsyncResult) result = NULL;
|
|
|
|
pusher = g_main_context_pusher_new(context);
|
|
|
|
qmi_client_uim_send_apdu(client,
|
|
input,
|
|
10,
|
|
NULL,
|
|
async_result_ready,
|
|
&result);
|
|
|
|
while (result == NULL)
|
|
g_main_context_iteration(context, TRUE);
|
|
|
|
return qmi_client_uim_send_apdu_finish(client, result, error);
|
|
}
|