#include <bluetooth.h>
#include <map>
+#include <poll.h>
+#include <sys/eventfd.h>
#include "vine-data-path-plugin.h"
#include "vine-log.h"
} gatt_client_s;
struct vine_gatt_s {
+ int eventfd;
+
bt_gatt_h service;
bt_gatt_h characteristic;
bt_gatt_h descriptor;
.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)
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);
}
return NULL;
}
+ gatt->eventfd = eventfd(0, 0);
gatt->recv_buffer = new VineQueue<gatt_data_s *>;
return gatt;
}
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)
gatt->role.client = NULL;
}
+ close(gatt->eventfd);
gatt->service = NULL;
gatt->characteristic = NULL;
gatt->descriptor = NULL;
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);
}
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)
}
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)
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)
} 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);
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:
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.