diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2021-01-27 13:02:37 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2021-01-28 12:32:26 +0100 |
commit | 21599cb776d49e40dbf8b520980606cfec84c9cb (patch) | |
tree | a4066b379995f384720501437e845ad9ec12e04d /src | |
parent | 1e82887ae5ed8e6c12a2168c9dcd68a8137f1cbf (diff) |
libqmi-glib,endpoint-qrtr: port to use the QrtrClient
Diffstat (limited to 'src')
-rw-r--r-- | src/libqmi-glib/qmi-endpoint-qrtr.c | 549 |
1 files changed, 232 insertions, 317 deletions
diff --git a/src/libqmi-glib/qmi-endpoint-qrtr.c b/src/libqmi-glib/qmi-endpoint-qrtr.c index f666fcf..7f8b734 100644 --- a/src/libqmi-glib/qmi-endpoint-qrtr.c +++ b/src/libqmi-glib/qmi-endpoint-qrtr.c @@ -34,6 +34,7 @@ #include "qmi-endpoint-qrtr.h" #include "qmi-errors.h" +#include "qmi-enum-types.h" #include "qmi-error-types.h" #include "qmi-message.h" @@ -52,22 +53,12 @@ G_DEFINE_TYPE (QmiEndpointQrtr, qmi_endpoint_qrtr, QMI_TYPE_ENDPOINT) struct _QmiEndpointQrtrPrivate { QrtrNode *node; - guint node_removed_id; - gboolean node_removed; - - /* Holds ClientInfo entries */ - GList *client_list; - /* Map of client id -> ClientInfo */ - GTree *client_map; - /* Map of socket -> ClientInfo */ - GHashTable *socket_map; -}; + guint node_removed_id; + gboolean node_removed; -typedef struct { - guint client_id; - GSocket *socket; - GSource *source; -} ClientInfo; + gboolean endpoint_open; + GList *clients; +}; /*****************************************************************************/ @@ -88,216 +79,191 @@ add_qmi_message_to_buffer (QmiEndpointQrtr *self, qmi_message_unref (message); } -static gboolean -qrtr_message_cb (GSocket *gsocket, - GIOCondition cond, - QmiEndpointQrtr *self) -{ - g_autoptr(GError) error = NULL; - g_autoptr(GSocketAddress) addr = NULL; - struct sockaddr_qrtr sq; - g_autoptr(GByteArray) buf = NULL; - gssize next_datagram_size; - gssize bytes_received; - ClientInfo *info; - QmiService service; - guint client; - QmiMessage *message; - - info = g_hash_table_lookup (self->priv->socket_map, gsocket); - if (!info) { - /* We're no longer watching this socket. */ - return FALSE; - } - - next_datagram_size = g_socket_get_available_bytes (gsocket); - buf = g_byte_array_new (); - g_byte_array_set_size (buf, next_datagram_size); - - bytes_received = g_socket_receive_from (gsocket, &addr, (gchar *)buf->data, - next_datagram_size, NULL, &error); - if (bytes_received < 0) { - g_warning ("[%s] Socket IO failure: %s", - qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); - g_signal_emit_by_name (QMI_ENDPOINT (self), QMI_ENDPOINT_SIGNAL_HANGUP); - return FALSE; - } - - if (bytes_received != next_datagram_size) { - g_debug ("[%s] Datagram was not expected size", qmi_endpoint_get_name (QMI_ENDPOINT (self))); - return TRUE; - } - - /* Figure out where we got this message from */ - if (!g_socket_address_to_native (addr, &sq, sizeof(sq), &error)) { - g_warning ("[%s] Could not parse QRTR address: %s", - qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); - return TRUE; - } +/*****************************************************************************/ - if (sq.sq_family != AF_QIPCRTR || - sq.sq_node != qrtr_node_get_id (self->priv->node) || - sq.sq_port == QRTR_PORT_CTRL) { - /* ignore all CTRL messages or ones not from our node, we only want real - * QMI messages */ - return TRUE; - } +#define QRTR_CLIENT_DATA_SERVICE "service" +#define QRTR_CLIENT_DATA_CID "cid" - /* Create a fake QMUX header and add this message to the buffer */ - service = qrtr_node_lookup_service (self->priv->node, sq.sq_port); - client = info->client_id; - message = qmi_message_new_from_data (service, client, buf, &error); - if (!message) { - g_warning ("[%s] Got malformed QMI message: %s", - qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); - return TRUE; - } +typedef struct { + QmiService service; + guint cid; + QrtrClient *client; + guint client_message_id; +} ClientInfo; - add_qmi_message_to_buffer (self, message); - return TRUE; +static void +client_info_free (ClientInfo *client_info) +{ + g_signal_handler_disconnect (client_info->client, client_info->client_message_id); + g_object_unref (client_info->client); + g_slice_free (ClientInfo, client_info); } static void -node_removed_cb (QrtrNode *node, - QmiEndpointQrtr *self) +client_info_list_free (GList *list) { - self->priv->node_removed = TRUE; - g_signal_emit_by_name (QMI_ENDPOINT (self), QMI_ENDPOINT_SIGNAL_HANGUP); + g_list_free_full (list, (GDestroyNotify) client_info_free); } +static ClientInfo * +client_info_lookup (QmiEndpointQrtr *self, + QmiService service, + guint cid) +{ + GList *l; -/*****************************************************************************/ -/* Client info operations */ + for (l = self->priv->clients; l; l = g_list_next (l)) { + ClientInfo *client_info = l->data; -static void -client_info_destroy (ClientInfo *info) -{ - if (info->source) { - g_source_destroy (info->source); - g_source_unref (info->source); + if ((service == client_info->service) && + (cid == client_info->cid)) + return client_info; } - if (info->socket) { - g_socket_close (info->socket, NULL); - g_clear_object (&info->socket); - } - g_slice_free (ClientInfo, info); + return NULL; } static gint -client_map_key_cmp (gconstpointer v1, - gconstpointer v2) +client_info_cmp (const ClientInfo *a, + const ClientInfo *b) { - return GPOINTER_TO_INT (v1) - GPOINTER_TO_INT (v2); + if (a->service != b->service) + return a->service - b->service; + return a->cid - b->cid; } -static gboolean -client_map_traverse_func (gpointer key, - gpointer value, - gpointer data) +static void +client_message_cb (QrtrClient *qrtr_client, + GByteArray *qrtr_message, + QmiEndpointQrtr *self) { - if (GPOINTER_TO_UINT (key) > *(guint *)data + 1) - return TRUE; + QmiMessage *message; + guint service; + guint cid; + g_autoptr(GError) error = NULL; - *(guint *)data = GPOINTER_TO_UINT (key); - return FALSE; -} + service = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (qrtr_client), QRTR_CLIENT_DATA_SERVICE)); + cid = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (qrtr_client), QRTR_CLIENT_DATA_CID)); -static guint -get_next_free_id (GTree *client_map) -{ - guint last_contiguous_id = -1; - g_tree_foreach (client_map, client_map_traverse_func, &last_contiguous_id); - return last_contiguous_id + 1; + /* Create a fake QMUX header and add this message to the buffer */ + message = qmi_message_new_from_data (service, cid, qrtr_message, &error); + if (!message) + g_warning ("[%s] Got malformed QMI message: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); + else + add_qmi_message_to_buffer (self, message); } -static gint -allocate_client (QmiEndpointQrtr *self, GError **error) +static ClientInfo * +client_info_new (QmiEndpointQrtr *self, + QmiService service, + GError **error) { - GError *inner_error = NULL; - int socket_fd; - GSocket *gsocket; - guint client_id; - ClientInfo *info; - - if (!self->priv->client_map) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "[%s] Endpoint is not open", - qmi_endpoint_get_name (QMI_ENDPOINT (self))); - return -QMI_PROTOCOL_ERROR_INTERNAL; + ClientInfo *client_info; + QrtrClient *qrtr_client; + GList *l; + guint max_cid = 0; + guint min_available_cid = 1; + guint cid = 0; + gint32 port; + + for (l = self->priv->clients; l; l = g_list_next (l)) { + client_info = l->data; + + if (service != client_info->service) + continue; + + max_cid = client_info->cid; + if (min_available_cid == client_info->cid) + min_available_cid++; } - client_id = get_next_free_id (self->priv->client_map); - if (client_id > G_MAXUINT8) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "[%s] Client IDs have been exhausted", - qmi_endpoint_get_name (QMI_ENDPOINT (self))); - return -QMI_PROTOCOL_ERROR_CLIENT_IDS_EXHAUSTED; + cid = max_cid + 1; + if (cid > G_MAXUINT8) { + cid = min_available_cid; + if (min_available_cid > G_MAXUINT8) { + g_set_error (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_CLIENT_IDS_EXHAUSTED, + "Client IDs have been exhausted"); + return NULL; + } } - socket_fd = socket (AF_QIPCRTR, SOCK_DGRAM, 0); - if (socket_fd < 0) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "[%s] Could not open QRTR socket: %s", - qmi_endpoint_get_name (QMI_ENDPOINT (self)), strerror(errno)); - return -QMI_PROTOCOL_ERROR_INTERNAL; + port = qrtr_node_lookup_port (self->priv->node, service); + if (port < 0) { + g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_UNSUPPORTED, + "Service not supported"); + return NULL; } - gsocket = g_socket_new_from_fd (socket_fd, &inner_error); - if (!gsocket) { - g_propagate_prefixed_error (error, inner_error, - "[%s] Socket setup failed: ", - qmi_endpoint_get_name (QMI_ENDPOINT (self))); - close (socket_fd); - return -QMI_PROTOCOL_ERROR_INTERNAL; + qrtr_client = qrtr_client_new (self->priv->node, (guint)port, NULL, error); + if (!qrtr_client) { + g_prefix_error (error, "Couldn't create QRTR client: "); + return NULL; } - g_socket_set_timeout (gsocket, 0); + /* store service and cid info in the client itself for quicker access */ + g_object_set_data (G_OBJECT (qrtr_client), QRTR_CLIENT_DATA_SERVICE, GUINT_TO_POINTER (service)); + g_object_set_data (G_OBJECT (qrtr_client), QRTR_CLIENT_DATA_CID, GUINT_TO_POINTER (cid)); + + client_info = g_slice_new0 (ClientInfo); + client_info->service = service; + client_info->cid = cid; + client_info->client = qrtr_client; + client_info->client_message_id = g_signal_connect (qrtr_client, + QRTR_CLIENT_SIGNAL_MESSAGE, + G_CALLBACK (client_message_cb), + self); - info = g_slice_new0 (ClientInfo); - info->client_id = client_id; - info->socket = gsocket; - info->source = g_socket_create_source (gsocket, G_IO_IN, NULL); - g_source_set_callback (info->source, (GSourceFunc) qrtr_message_cb, - self, NULL); - g_source_attach (info->source, NULL); + self->priv->clients = g_list_insert_sorted (self->priv->clients, + client_info, + (GCompareFunc)client_info_cmp); - self->priv->client_list = g_list_append (self->priv->client_list, info); - g_tree_insert (self->priv->client_map, GUINT_TO_POINTER (info->client_id), info); - g_hash_table_insert (self->priv->socket_map, gsocket, info); - return info->client_id; + return client_info; } -static void -release_client (QmiEndpointQrtr *self, guint client_id) +/*****************************************************************************/ +/* Client info operations */ + +static guint +allocate_client (QmiEndpointQrtr *self, + QmiService service, + GError **error) { - ClientInfo *info; + ClientInfo *client_info; - info = g_tree_lookup (self->priv->client_map, GUINT_TO_POINTER (client_id)); - if (!info) - return; + if (!self->priv->endpoint_open) { + g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, + "Endpoint is not open"); + return 0; + } - g_hash_table_remove (self->priv->socket_map, info->socket); - g_tree_remove (self->priv->client_map, GUINT_TO_POINTER (client_id)); - self->priv->client_list = g_list_remove (self->priv->client_list, info); - client_info_destroy (info); + client_info = client_info_new (self, service, error); + if (!client_info) + return 0; + + return client_info->cid; } static void -client_list_destroy (GList *list) +release_client (QmiEndpointQrtr *self, + QmiService service, + guint cid) { - g_list_free_full (list, (GDestroyNotify) client_info_destroy); + ClientInfo *client_info; + + client_info = client_info_lookup (self, service, cid); + if (!client_info) + return; + + self->priv->clients = g_list_remove (self->priv->clients, client_info); + client_info_free (client_info); } /*****************************************************************************/ static gboolean -construct_alloc_tlv (QmiMessage *message, guint8 service, guint8 client) +construct_alloc_tlv (QmiMessage *message, + guint8 service, + guint8 client) { gsize init_offset; @@ -311,77 +277,76 @@ construct_alloc_tlv (QmiMessage *message, guint8 service, guint8 client) } static void -handle_alloc_cid (QmiEndpointQrtr *self, QmiMessage *message) +handle_alloc_cid (QmiEndpointQrtr *self, + QmiMessage *message) { - gsize offset = 0; - gsize init_offset; - guint8 service; - gint client_id; - QmiMessage *response; - QmiProtocolError result = QMI_PROTOCOL_ERROR_NONE; - GError *error = NULL; + gsize offset = 0; + gsize init_offset; + guint8 service; + guint cid; + QmiProtocolError result = QMI_PROTOCOL_ERROR_NONE; + g_autoptr(QmiMessage) response = NULL; + g_autoptr(GError) error = NULL; if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_TLV_ALLOCATION_INFO, NULL, &error)) == 0) || !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service, &error)) { - g_debug ("Error allocating CID: could not parse message: %s", error->message); - g_error_free (error); + g_debug ("[%s] error allocating CID: could not parse message: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); result = QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE; } - client_id = allocate_client (self, &error); - if (client_id < 0) { - g_debug ("Error allocating CID: could not parse message: %s", error->message); - g_error_free (error); - result = -client_id; + cid = allocate_client (self, service, &error); + if (!cid) { + g_debug ("[%s] error allocating CID: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); + result = QMI_PROTOCOL_ERROR_INTERNAL; } response = qmi_message_response_new (message, result); if (!response) return; - if (!construct_alloc_tlv (response, service, client_id)) { - qmi_message_unref (response); + if (!construct_alloc_tlv (response, service, cid)) return; - } - add_qmi_message_to_buffer (self, response); + add_qmi_message_to_buffer (self, g_steal_pointer (&response)); } static void -handle_release_cid (QmiEndpointQrtr *self, QmiMessage *message) +handle_release_cid (QmiEndpointQrtr *self, + QmiMessage *message) { - gsize offset = 0; - gsize init_offset; - guint8 service; - guint8 client_id = 0; - QmiMessage *response; - QmiProtocolError result = QMI_PROTOCOL_ERROR_NONE; - GError *error = NULL; + gsize offset = 0; + gsize init_offset; + guint8 service; + guint8 cid = 0; + QmiProtocolError result = QMI_PROTOCOL_ERROR_NONE; + g_autoptr(QmiMessage) response = NULL; + g_autoptr(GError) error = NULL; if (((init_offset = qmi_message_tlv_read_init (message, QMI_MESSAGE_TLV_ALLOCATION_INFO, NULL, &error)) == 0) || !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &service, &error) || - !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &client_id, &error)) { - g_debug ("Error releasing CID: could not parse message: %s", error->message); - g_error_free (error); + !qmi_message_tlv_read_guint8 (message, init_offset, &offset, &cid, &error)) { + g_debug ("[%s] error releasing CID: could not parse message: %s", + qmi_endpoint_get_name (QMI_ENDPOINT (self)), error->message); result = QMI_PROTOCOL_ERROR_MALFORMED_MESSAGE; } - release_client (self, client_id); + release_client (self, service, cid); response = qmi_message_response_new (message, result); if (!response) return; - if (!construct_alloc_tlv (response, service, client_id)) { - qmi_message_unref (response); + if (!construct_alloc_tlv (response, service, cid)) return; - } - add_qmi_message_to_buffer (self, response); + add_qmi_message_to_buffer (self, g_steal_pointer (&response)); } static void -handle_sync (QmiEndpointQrtr *self, QmiMessage *message) +handle_sync (QmiEndpointQrtr *self, + QmiMessage *message) { QmiMessage *response; @@ -394,30 +359,20 @@ handle_sync (QmiEndpointQrtr *self, QmiMessage *message) static void unhandled_message (QmiEndpointQrtr *self, - QmiMessage *message, - gboolean log_warning) + QmiMessage *message) { QmiMessage *response; - if (log_warning) { - gchar *message_text; - - message_text = qmi_message_get_printable_full (message, NULL, " "); - g_warning ("[%s] Unhandled client message:\n%s", - qmi_endpoint_get_name (QMI_ENDPOINT (self)), - message_text); - g_free (message_text); - } - response = qmi_message_response_new (message, QMI_PROTOCOL_ERROR_NOT_SUPPORTED); if (!response) return; + add_qmi_message_to_buffer (self, response); } static void handle_ctl_message (QmiEndpointQrtr *self, - QmiMessage *message) + QmiMessage *message) { switch (qmi_message_get_message_id (message)) { case QMI_MESSAGE_CTL_ALLOCATE_CID: @@ -430,11 +385,8 @@ handle_ctl_message (QmiEndpointQrtr *self, handle_sync (self, message); break; case QMI_MESSAGE_CTL_GET_VERSION_INFO: - /* Messages we expect to see should not be logged. */ - unhandled_message (self, message, FALSE); - break; default: - unhandled_message (self, message, TRUE); + unhandled_message (self, message); break; } } @@ -457,12 +409,11 @@ endpoint_open (QmiEndpoint *endpoint, GAsyncReadyCallback callback, gpointer user_data) { - QmiEndpointQrtr *self; - GTask *task; + QmiEndpointQrtr *self = QMI_ENDPOINT_QRTR (endpoint); + GTask *task; g_assert (!use_proxy); - self = QMI_ENDPOINT_QRTR (endpoint); task = g_task_new (self, cancellable, callback, user_data); if (self->priv->node_removed) { @@ -474,7 +425,7 @@ endpoint_open (QmiEndpoint *endpoint, return; } - if (self->priv->client_map) { + if (self->priv->endpoint_open) { g_task_return_new_error (task, QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, @@ -483,9 +434,9 @@ endpoint_open (QmiEndpoint *endpoint, return; } - g_assert (self->priv->client_list == NULL); - self->priv->client_map = g_tree_new (client_map_key_cmp); - self->priv->socket_map = g_hash_table_new (g_direct_hash, g_direct_equal); + g_assert (self->priv->clients == NULL); + self->priv->endpoint_open = TRUE; + g_task_return_boolean (task, TRUE); g_object_unref (task); } @@ -493,7 +444,7 @@ endpoint_open (QmiEndpoint *endpoint, static gboolean endpoint_is_open (QmiEndpoint *self) { - return !!(QMI_ENDPOINT_QRTR (self)->priv->client_map); + return QMI_ENDPOINT_QRTR (self)->priv->endpoint_open; } static gboolean @@ -503,93 +454,53 @@ endpoint_send (QmiEndpoint *endpoint, GCancellable *cancellable, GError **error) { - QmiEndpointQrtr *self; - gconstpointer raw_message; - gsize raw_message_len; - guint client_id; - ClientInfo *client; - QmiService service; - struct sockaddr_qrtr addr; - gint sockfd; - gint rc; - GError *inner_error = NULL; - gint sq_port; - - self = QMI_ENDPOINT_QRTR (endpoint); - - /* Figure out if we have a valid client */ + QmiEndpointQrtr *self = QMI_ENDPOINT_QRTR (endpoint); + ClientInfo *client_info; + QmiService service; + guint cid; + gconstpointer raw_message; + gsize raw_message_len; + g_autoptr(GByteArray) qrtr_message = NULL; + + /* We implement the CTL service here, so divert those messages */ service = qmi_message_get_service (message); - client_id = qmi_message_get_client_id (message); - client = g_tree_lookup (self->priv->client_map, GUINT_TO_POINTER (client_id)); if (service == QMI_SERVICE_CTL) { - if (client && client->socket) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "Client %u is not a CTL client", client_id); - return FALSE; - } - if (!client) { - /* Dummy entry for CTL client with no socket */ - ClientInfo *info; - - info = g_slice_new0 (ClientInfo); - info->client_id = client_id; - self->priv->client_list = g_list_append (self->priv->client_list, info); - g_tree_insert (self->priv->client_map, GUINT_TO_POINTER (info->client_id), info); - } - /* We implement the control client here, so divert those messages */ handle_ctl_message (self, message); return TRUE; } - /* It's a normal service, so we should have an open client for it. */ - if (!client) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_WRONG_STATE, - "Client %u is not open", client_id); + cid = qmi_message_get_client_id (message); + client_info = client_info_lookup (self, service, cid); + if (!client_info) { + g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_WRONG_STATE, + "Unknown client %u for service %s", cid, qmi_service_get_string (service)); return FALSE; } - /* Lookup port */ - sq_port = qrtr_node_lookup_port (self->priv->node, service); - if (sq_port == -1) { - g_set_error (error, - QMI_CORE_ERROR, - QMI_CORE_ERROR_FAILED, - "Service %u has no servers", service); - return FALSE; - } - - /* Set up QRTR bus destination address */ - addr.sq_family = AF_QIPCRTR; - addr.sq_node = qrtr_node_get_id (self->priv->node); - addr.sq_port = (guint) sq_port; - - /* Get raw message */ - raw_message = qmi_message_get_data (message, &raw_message_len, &inner_error); + /* Build raw QRTR message without QMUX header */ + raw_message = qmi_message_get_data (message, &raw_message_len, error); if (!raw_message) { - g_propagate_prefixed_error (error, inner_error, "Message was invalid: "); - return FALSE; - } - - sockfd = g_socket_get_fd (client->socket); - rc = sendto (sockfd, (void *)raw_message, raw_message_len, - 0, (struct sockaddr *)&addr, sizeof (addr)); - if (rc < 0) { - g_set_error (error, - G_IO_ERROR, - g_io_error_from_errno (errno), - "Failed to send QMI packet"); + g_prefix_error (error, "Invalid QMI message: "); return FALSE; } + qrtr_message = g_byte_array_sized_new (raw_message_len); + g_byte_array_append (qrtr_message, raw_message, raw_message_len); - return TRUE; + return qrtr_client_send (client_info->client, + qrtr_message, + cancellable, + error); } /*****************************************************************************/ +static void +internal_close (QmiEndpointQrtr *self) +{ + g_clear_pointer (&self->priv->clients, client_info_list_free); + self->priv->endpoint_open = FALSE; +} + static gboolean endpoint_close_finish (QmiEndpoint *self, GAsyncResult *res, @@ -605,21 +516,27 @@ endpoint_close (QmiEndpoint *endpoint, GAsyncReadyCallback callback, gpointer user_data) { - QmiEndpointQrtr *self; - GTask *task; + QmiEndpointQrtr *self = QMI_ENDPOINT_QRTR (endpoint); + GTask *task; - self = QMI_ENDPOINT_QRTR (endpoint); task = g_task_new (self, cancellable, callback, user_data); - g_clear_pointer (&self->priv->socket_map, g_hash_table_destroy); - g_clear_pointer (&self->priv->client_map, g_tree_destroy); - g_clear_pointer (&self->priv->client_list, client_list_destroy); + internal_close (self); + g_task_return_boolean (task, TRUE); g_object_unref (task); } /*****************************************************************************/ +static void +node_removed_cb (QrtrNode *node, + QmiEndpointQrtr *self) +{ + self->priv->node_removed = TRUE; + g_signal_emit_by_name (QMI_ENDPOINT (self), QMI_ENDPOINT_SIGNAL_HANGUP); +} + QmiEndpointQrtr * qmi_endpoint_qrtr_new (QrtrNode *node) { @@ -662,9 +579,7 @@ dispose (GObject *object) { QmiEndpointQrtr *self = QMI_ENDPOINT_QRTR (object); - g_clear_pointer (&self->priv->socket_map, g_hash_table_destroy); - g_clear_pointer (&self->priv->client_map, g_tree_destroy); - g_clear_pointer (&self->priv->client_list, client_list_destroy); + internal_close (self); if (self->priv->node) { if (self->priv->node_removed_id) { |