From df57c468df1f7f2e2f38f3db3c087cc4ca56fed1 Mon Sep 17 00:00:00 2001 From: Frederic Berat Date: Thu, 3 Dec 2015 13:22:26 +0100 Subject: dlt-daemon: Connection activation rework The activation of the connection is now centralized in one common function. Signed-off-by: Frederic Berat Change-Id: I86703eab411088905a85f526d5102875e2c92b7e --- src/daemon/dlt-daemon.c | 3 +- src/daemon/dlt_daemon_connection_types.h | 1 + src/daemon/dlt_daemon_event_handler.c | 137 +++++++++++++++++++++++++------ src/daemon/dlt_daemon_event_handler.h | 6 +- src/gateway/dlt_gateway.c | 9 +- 5 files changed, 122 insertions(+), 34 deletions(-) diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 674ece5..d03cd02 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -3106,8 +3106,7 @@ int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_ /* Closure is done while unregistering has for any connection */ dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, - sock, - DLT_CONNECTION_CLIENT_MSG_TCP); + sock); if(daemon_local->client_connections==0) diff --git a/src/daemon/dlt_daemon_connection_types.h b/src/daemon/dlt_daemon_connection_types.h index 353889c..1e1186b 100644 --- a/src/daemon/dlt_daemon_connection_types.h +++ b/src/daemon/dlt_daemon_connection_types.h @@ -75,6 +75,7 @@ typedef struct DltConnection { DltConnectionType type; /**< Represents what type of handle is this (like FIFO, serial, client, server) */ DltConnectionStatus status; /**< Status of connection */ struct DltConnection *next; /**< For multiple client connection using linked list */ + int ev_mask; /**< Mask to set when registering the connection for events */ } DltConnection; #endif /* DLT_DAEMON_CONNECTION_TYPES_H */ diff --git a/src/daemon/dlt_daemon_event_handler.c b/src/daemon/dlt_daemon_event_handler.c index 23288f6..80817a4 100644 --- a/src/daemon/dlt_daemon_event_handler.c +++ b/src/daemon/dlt_daemon_event_handler.c @@ -139,8 +139,7 @@ int dlt_daemon_handle_event(DltEventHandler *pEvent, */ dlt_event_handler_unregister_connection(pEvent, daemon_local, - fd, - type); + fd); continue; } @@ -276,6 +275,97 @@ static void dlt_daemon_add_connection(DltEventHandler *ev, *temp = connection; } +/** @brief Check for connection activation + * + * If the connection is active and it's not allowed anymore or it the user + * ask for deactivation, the connection will be deactivated. + * If the connection is inactive, the user asks for activation and it's + * allowed for it to be activated, the connection will be activated. + * + * @param evhdl The event handler structure. + * @param con The connection to act on + * @param activation_type The type of activation requested ((DE)ACTIVATE) + * + * @return 0 on success, -1 otherwise + */ +int dlt_connection_check_activate(DltEventHandler *evhdl, + DltConnection *con, + int activation_type) +{ + char local_str[DLT_DAEMON_TEXTBUFSIZE] = { '\0' }; + + if (!evhdl || !con || !con->receiver) + { + snprintf(local_str, + DLT_DAEMON_TEXTBUFSIZE, + "%s: wrong parameters (%p %p).\n", + __func__, + evhdl, + con); + dlt_log(LOG_ERR, local_str); + return -1; + } + + switch (con->status) + { + case ACTIVE: + if (activation_type == DEACTIVATE) + { + snprintf(local_str, + DLT_DAEMON_TEXTBUFSIZE, + "Deactivate connection type: %d\n", + con->type); + dlt_log(LOG_INFO, local_str); + + if (epoll_ctl(evhdl->epfd, + EPOLL_CTL_DEL, + con->receiver->fd, + NULL) == -1) + { + dlt_log(LOG_ERR, "epoll_ctl() in deactivate failed!\n"); + return -1; + } + + con->status = INACTIVE; + } + break; + case INACTIVE: + if (activation_type == ACTIVATE) + { + struct epoll_event ev; /* Content will be copied by the kernel */ + ev.events = con->ev_mask; + ev.data.ptr = (void *)con; + + snprintf(local_str, + DLT_DAEMON_TEXTBUFSIZE, + "Activate connection type: %d\n", + con->type); + dlt_log(LOG_INFO, local_str); + + + if (epoll_ctl(evhdl->epfd, + EPOLL_CTL_ADD, + con->receiver->fd, + &ev) == -1) + { + dlt_log(LOG_ERR, "epoll_ctl() in activate failed!\n"); + return -1; + } + con->status = ACTIVE; + } + break; + default: + snprintf(local_str, + DLT_DAEMON_TEXTBUFSIZE, + "Unknown connection status: %d\n", + con->status); + dlt_log(LOG_ERR, local_str); + return -1; + } + + return 0; +} + /** @brief Registers a connection for event handling and takes its ownership. * * As we add the connection to the list of connection, we take its ownership. @@ -297,34 +387,28 @@ int dlt_event_handler_register_connection(DltEventHandler *evhdl, DltConnection *connection, int mask) { - struct epoll_event ev; /* Content will be copied by the kernel */ - int fd = -1; - if (!evhdl || !connection || !connection->receiver) { dlt_log(LOG_ERR, "Wrong parameters when registering connection.\n"); return -1; } - fd = connection->receiver->fd; - dlt_daemon_add_connection(evhdl, connection); - ev.events = mask; - ev.data.ptr = (void *)connection; - - if (epoll_ctl(evhdl->epfd, EPOLL_CTL_ADD, fd, &ev) == -1) - { - dlt_log(LOG_ERR, "epoll_ctl() failed!\n"); - dlt_daemon_remove_connection(evhdl, connection); - return -1; - } - - if ((connection->type == DLT_CONNECTION_CLIENT_MSG_TCP) || (connection->type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) + if ((connection->type == DLT_CONNECTION_CLIENT_MSG_TCP) || + (connection->type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) { daemon_local->client_connections++; } - return 0; + /* On creation the connection is not active by default */ + connection->status = INACTIVE; + + connection->next = NULL; + connection->ev_mask = mask; + + return dlt_connection_check_activate(evhdl, + connection, + ACTIVATE); } /** @brief Unregisters a connection from the event handler and destroys it. @@ -338,14 +422,12 @@ int dlt_event_handler_register_connection(DltEventHandler *evhdl, * @param evhdl The event handler structure where the connection list is. * @param daemon_local Structure containing needed information. * @param fd The file descriptor of the connection to be unregistered. - * @param type the connection type. * * @return 0 on success, -1 otherwise. */ int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, DltDaemonLocal *daemon_local, - int fd, - DltConnectionType type) + int fd) { /* Look for the pointer in the client list. * There shall be only one event handler with the same fd. @@ -358,8 +440,8 @@ int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, return -1; } - if ((type == DLT_CONNECTION_CLIENT_MSG_TCP) || - (type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) + if ((temp->type == DLT_CONNECTION_CLIENT_MSG_TCP) || + (temp->type == DLT_CONNECTION_CLIENT_MSG_SERIAL)) { daemon_local->client_connections--; @@ -370,6 +452,13 @@ int dlt_event_handler_unregister_connection(DltEventHandler *evhdl, } } + if (dlt_connection_check_activate(evhdl, + temp, + DEACTIVATE) < 0) + { + dlt_log(LOG_ERR, "Unable to unregister event.\n"); + } + /* Cannot fail as far as dlt_daemon_find_connection succeed */ return dlt_daemon_remove_connection(evhdl, temp); } diff --git a/src/daemon/dlt_daemon_event_handler.h b/src/daemon/dlt_daemon_event_handler.h index cd5d8ca..532cd1f 100644 --- a/src/daemon/dlt_daemon_event_handler.h +++ b/src/daemon/dlt_daemon_event_handler.h @@ -51,7 +51,9 @@ int dlt_event_handler_register_connection(DltEventHandler *, int dlt_event_handler_unregister_connection(DltEventHandler *, DltDaemonLocal *, - int, - DltConnectionType); + int); +int dlt_connection_check_activate(DltEventHandler *, + DltConnection *, + int); #endif /* DLT_DAEMON_EVENT_HANDLER_H */ diff --git a/src/gateway/dlt_gateway.c b/src/gateway/dlt_gateway.c index 89e97a5..c88d35e 100644 --- a/src/gateway/dlt_gateway.c +++ b/src/gateway/dlt_gateway.c @@ -793,8 +793,7 @@ int dlt_gateway_process_passive_node_messages(DltDaemon *daemon, con->status = DLT_GATEWAY_DISCONNECTED; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, - receiver->fd, - DLT_CONNECTION_GATEWAY) != 0) + receiver->fd) != 0) { dlt_log(LOG_ERR, "Remove passive node Connection failed\n"); } @@ -854,8 +853,7 @@ int dlt_gateway_process_passive_node_messages(DltDaemon *daemon, con->trigger = DLT_GATEWAY_DISABLED; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, - receiver->fd, - DLT_CONNECTION_GATEWAY) + receiver->fd) != 0) { dlt_log(LOG_ERR, "Remove passive node Connection failed\n"); @@ -1095,8 +1093,7 @@ int dlt_gateway_process_on_demand_request(DltGateway *gateway, con->status = DLT_GATEWAY_DISCONNECTED; if (dlt_event_handler_unregister_connection(&daemon_local->pEvent, daemon_local, - con->client.sock, - DLT_CONNECTION_GATEWAY) != 0) + con->client.sock) != 0) { dlt_log(LOG_ERR, "Remove passive node event handler connection failed\n"); -- cgit v1.2.1