ble-gatt: Add eventfd to handle pending write data 63/261563/2
authorSeonah Moon <seonah1.moon@samsung.com>
Wed, 21 Jul 2021 07:49:51 +0000 (16:49 +0900)
committerseonah moon <seonah1.moon@samsung.com>
Thu, 22 Jul 2021 09:36:51 +0000 (09:36 +0000)
Change-Id: I1c799fe039a7c6545326e29ce921cd4edb10a58e

plugins/ble-gatt/ble-gatt-plugin.cpp
plugins/libwebsockets/libwebsockets-plugin.cpp
src/include/vine-data-path-plugin.h
src/vine-data-path.cpp

index b9f3667..2fea5e3 100755 (executable)
@@ -17,6 +17,8 @@
 
 #include <bluetooth.h>
 #include <map>
+#include <poll.h>
+#include <sys/eventfd.h>
 
 #include "vine-data-path-plugin.h"
 #include "vine-log.h"
@@ -58,6 +60,8 @@ typedef struct {
 } gatt_client_s;
 
 struct vine_gatt_s {
+       int eventfd;
+
        bt_gatt_h service;
        bt_gatt_h characteristic;
        bt_gatt_h descriptor;
@@ -83,6 +87,8 @@ static vine_dp_plugin_callbacks g_callbacks = {
     .terminated_cb = NULL,
 };
 
+static map<int, struct vine_gatt_s *> g_eventfds;
+
 static vine_gatt_s *_create_gatt(void);
 
 static vine_data_path_error __convert_bt_error_to_data_path_error(int error)
@@ -246,6 +252,16 @@ static void __gatt_server_write_value_requested_cb(const char *remote_address,
 void __gatt_server_noti_state_changed_cb(bool notify, bt_gatt_server_h server,
                bt_gatt_h gatt_handle, void *user_data)
 {
+       RET_IF(user_data == NULL, "user_data is NULL.");
+       vine_gatt_s *gatt = (vine_gatt_s *)user_data;
+
+       if (notify) {
+               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_OP, gatt->eventfd, POLLOUT, gatt->user);
+
+               uint64_t v = 1;
+               if (write(gatt->eventfd, &v, sizeof(v)) == -1)
+                       VINE_LOGE("Write error(%d)", errno);
+       }
        VINE_LOGI("Noti state changed. notify[%d] characteristic[%p]", notify, gatt_handle);
 }
 
@@ -447,6 +463,7 @@ static vine_gatt_s *_create_gatt(void)
                return NULL;
        }
 
+       gatt->eventfd = eventfd(0, 0);
        gatt->recv_buffer = new VineQueue<gatt_data_s *>;
        return gatt;
 }
@@ -551,9 +568,18 @@ void gatt_register_callbacks(vine_dp_plugin_callbacks callbacks)
        g_callbacks = callbacks;
 }
 
-void gatt_process_event(int gatt_fd, int events)
+void gatt_process_event(int fd, int events)
 {
-       // Do nothing. use g_main_loop.
+       auto it = g_eventfds.find(fd);
+       if (it == g_eventfds.end()) {
+               VINE_LOGE("There is no matched gatt handle.");
+               close(fd);
+               return;
+       }
+
+       // TODO: handle pending write events.
+       vine_gatt_s *gatt = it->second;
+       VINE_LOGI("found gatt[%p]", gatt);
 }
 
 int gatt_create(vine_dp_plugin_h *handle, void *plugin_data, void *user)
@@ -588,6 +614,7 @@ int gatt_destroy(vine_dp_plugin_h handle)
                gatt->role.client = NULL;
        }
 
+       close(gatt->eventfd);
        gatt->service = NULL;
        gatt->characteristic = NULL;
        gatt->descriptor = NULL;
index c901e51..f9a5112 100755 (executable)
@@ -221,7 +221,7 @@ static void _notify_websocket_op_request()
        uint64_t v = 1;
        int _eventfd = eventfd(0, 0);
 
-       g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_OP, _eventfd, LWS_POLLOUT);
+       g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_OP, _eventfd, LWS_POLLOUT, NULL);
        if (write(_eventfd, &v, sizeof(v)) == -1)
                VINE_LOGE("Write error(%d)", errno);
 }
@@ -347,7 +347,7 @@ static void _add_websocket_poll_fd(struct lws_pollargs *args)
        VINE_LOGI("websocket pollfd[%p] fd[%d] is added.", pollfd, args->fd);
 
        if (g_callbacks.pollfd_cb)
-               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_ADD, pollfd->fd, pollfd->events);
+               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_ADD, pollfd->fd, pollfd->events, NULL);
 }
 
 static void _delete_websocket_poll_fd(struct lws_pollargs *args)
@@ -364,7 +364,7 @@ static void _delete_websocket_poll_fd(struct lws_pollargs *args)
        }
 
        if (g_callbacks.pollfd_cb)
-               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_DEL, args->fd, args->events);
+               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_DEL, args->fd, args->events, NULL);
 }
 
 static void _change_websocket_poll_fd(struct lws_pollargs *args)
@@ -378,7 +378,7 @@ static void _change_websocket_poll_fd(struct lws_pollargs *args)
        pollfd->events = args->events;
 
        if (g_callbacks.pollfd_cb)
-               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_MOD, pollfd->fd, pollfd->events);
+               g_callbacks.pollfd_cb(VINE_DATA_PATH_POLLFD_MOD, pollfd->fd, pollfd->events, NULL);
 }
 
 static void _invoke_connected_cb(struct lws *wsi, bool connected, void *user_data)
index e74ad5c..55b21a9 100755 (executable)
@@ -73,7 +73,7 @@ typedef struct {
 } vine_dp_ssl;
 
 typedef struct {
-       void (*pollfd_cb)(vine_data_path_pollfd_op_e op, int fd, int event);
+       void (*pollfd_cb)(vine_data_path_pollfd_op_e op, int fd, int event, void *user_data);
        void (*opened_cb)(int result, int port, void *user_data);
        void (*accepted_cb)(vine_dp_addr_family_e addr_family, char *addr, int port, void *plugin_data, void *user_data);
        void (*connected_cb)(int result, void *user_data);
index 0458549..a723849 100755 (executable)
@@ -155,13 +155,15 @@ void __vine_dp_op_handler(int fd, int events, void *user_data)
                VINE_LOGE("Read error(%d)", errno);
                return;
        }
-       // TODO: Only LWS plugin supports polling functions.
-       // But, we need to modify pollfd_cb to pass datapath handle as the user_data
-       if (__vine_data_path_plugins[VINE_DATA_PATH_METHOD_LWS].fn.process_event)
-               __vine_data_path_plugins[VINE_DATA_PATH_METHOD_LWS].fn.process_event(fd, events);
+
+       vine_data_path_s *datapath = (vine_data_path_s *)user_data;
+       vine_data_path_method_e method = datapath ? datapath->method : VINE_DATA_PATH_METHOD_LWS;
+
+       if (__vine_data_path_plugins[method].fn.process_event)
+               __vine_data_path_plugins[method].fn.process_event(fd, events);
 }
 
-static void __pollfd_cb(vine_data_path_pollfd_op_e op, int fd, int events)
+static void __pollfd_cb(vine_data_path_pollfd_op_e op, int fd, int events, void *user_data)
 {
        switch (op) {
        case VINE_DATA_PATH_POLLFD_ADD:
@@ -174,7 +176,7 @@ static void __pollfd_cb(vine_data_path_pollfd_op_e op, int fd, int events)
                vine_event_loop_mod_io_handler(fd, events, __vine_dp_poll_handler, NULL);
                break;
        case VINE_DATA_PATH_POLLFD_OP:
-               vine_event_loop_add_io_handler(fd, events, __vine_dp_op_handler, NULL);
+               vine_event_loop_add_io_handler(fd, events, __vine_dp_op_handler, user_data);
                break;
        case VINE_DATA_PATH_POLLFD_LOCK_UNLOCK:
                // Do not anything.