Seperate GATT from BLE plugin 06/260806/2
authorSeonah Moon <seonah1.moon@samsung.com>
Mon, 5 Jul 2021 02:21:58 +0000 (11:21 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Wed, 7 Jul 2021 02:41:42 +0000 (11:41 +0900)
Change-Id: I341ad739a779a0d4659da478e6acf00d8c4a8d2c

CMakeLists.txt
plugins/ble-gatt/CMakeLists.txt [new file with mode: 0755]
plugins/ble-gatt/ble-gatt-plugin.cpp [new file with mode: 0755]
plugins/ble-gatt/ble-gatt-plugin.h [new file with mode: 0755]
plugins/ble/gatt-plugin.cpp [deleted file]

index eae505517fdb606e541f1678a005ef7dafabee45..a6834a7e14cbefa216c934a9da90289109611d08 100755 (executable)
@@ -127,6 +127,7 @@ ENDIF(USE_LIBWEBSOCKETS)
 ADD_SUBDIRECTORY(plugins/dns-sd)
 IF(BT_SUPPORT)
        ADD_SUBDIRECTORY(plugins/ble)
+       ADD_SUBDIRECTORY(plugins/ble-gatt)
 ENDIF(BT_SUPPORT)
 
 ADD_SUBDIRECTORY(include)
diff --git a/plugins/ble-gatt/CMakeLists.txt b/plugins/ble-gatt/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..977029e
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+
+SET(BLE_GATT_PLUGIN "vine-plugin-ble-gatt")
+
+SET(BLE_GATT_PLUGIN_VERSION_MAJOR "1")
+SET(BLE_GATT_PLUGIN_VERSION_MINOR "0")
+SET(BLE_GATT_PLUGIN_VERSION_PATCH "0")
+SET(BLE_GATT_PLUGIN_VERSION ${BLE_GATT_PLUGIN_VERSION_MAJOR}.${BLE_GATT_PLUGIN_VERSION_MINOR}.${BLE_GATT_PLUGIN_VERSION_PATCH})
+
+PKG_CHECK_MODULES(BLE_DEPS REQUIRED "capi-network-bluetooth")
+
+INCLUDE_DIRECTORIES(
+    ${VINE_PATH}/include
+    ${VINE_LOGGER_PATH}
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${${fw_name}_INCLUDE_DIRS}
+       ${BLE_DEPS_INCLUDE_DIRS}
+)
+
+FILE(GLOB VINE_BLE_GATT_PLUGIN_SOURCES *.cpp)
+
+ADD_DEFINITIONS("-fvisibility=default")
+ADD_LIBRARY(${BLE_GATT_PLUGIN} SHARED ${VINE_BLE_GATT_PLUGIN_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${BLE_GATT_PLUGIN}
+    PROPERTIES
+        SOVERSION ${BLE_GATT_PLUGIN_VERSION_MAJOR}
+)
+
+TARGET_LINK_LIBRARIES(${BLE_GATT_PLUGIN}
+    ${VINE_LOGGER}
+    ${BLE_DEPS_LIBRARIES}
+    ${fw_name_deps_LIBRARIES}
+    dl
+)
+
+INSTALL(TARGETS ${BLE_GATT_PLUGIN} DESTINATION "${LIB_DIR}")
diff --git a/plugins/ble-gatt/ble-gatt-plugin.cpp b/plugins/ble-gatt/ble-gatt-plugin.cpp
new file mode 100755 (executable)
index 0000000..19898d0
--- /dev/null
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#include <bluetooth.h>
+
+#include "vine-data-path-plugin.h"
+#include "vine-log.h"
+#include "vine-utils.h"
+
+using namespace std;
+
+// TODO: change UUIDs
+#define VINE_GATT_SERVICE_UUID "000018f2-0000-1000-8000-00805f9b34fb"
+#define VINE_GATT_CHAR_UUID "00002af6-0000-1000-8000-00805f9b34fb"
+#define VINE_GATT_DESC_UUID "fa87c0d0-afac-11de-8a39-0800200c9a66"
+
+typedef enum {
+       VINE_GATT_ROLE_UNKNOWN = 0,
+       VINE_GATT_ROLE_SERVER,
+       VINE_GATT_ROLE_CLIENT,
+} vine_gatt_role_e;
+
+typedef struct {
+       bt_gatt_h service;
+       bt_gatt_h characteristic;
+       bt_gatt_h descriptor;
+
+       vine_gatt_role_e type;
+       union {
+               bt_gatt_server_h server;
+               bt_gatt_client_h client;
+       } role;
+
+       char *remote_address;
+       bool is_accepted;
+       void *user; // vine_data_path_h
+} vine_gatt_s;
+
+static vine_dp_plugin_callbacks g_callbacks = {
+    .pollfd_cb = NULL,
+    .opened_cb = NULL,
+    .accepted_cb = NULL,
+    .connected_cb = NULL,
+    .received_cb = NULL,
+    .written_cb = NULL,
+    .terminated_cb = NULL,
+};
+
+static vine_gatt_s *_create_gatt(void);
+
+static vine_data_path_error __convert_bt_error_to_data_path_error(int error)
+{
+       switch (error) {
+       case BT_ERROR_NONE:
+               return VINE_DATA_PATH_ERROR_NONE;
+       case BT_ERROR_OUT_OF_MEMORY:
+               return VINE_DATA_PATH_ERROR_OUT_OF_MEMORY;
+       case BT_ERROR_INVALID_PARAMETER:
+               return VINE_DATA_PATH_ERROR_INVALID_PARAMETER;
+       case BT_ERROR_OPERATION_FAILED:
+       default:
+               return VINE_DATA_PATH_ERROR_OPERATION_FAILED;
+       }
+}
+
+static void __invoke_accepted_cb(const char *remote_address, vine_gatt_s *gatt, void *user_data)
+{
+       if (!g_callbacks.accepted_cb)
+               return;
+
+       vine_gatt_s *accepted_gatt = _create_gatt();
+       RET_IF(accepted_gatt == NULL, "Failed to create accepted_gatt.");
+
+       accepted_gatt->remote_address = STRDUP(remote_address);
+
+       // refer to server's gatt handles.
+       accepted_gatt->service = gatt->service;
+       accepted_gatt->characteristic = gatt->characteristic;
+       accepted_gatt->descriptor = gatt->descriptor;
+
+       accepted_gatt->is_accepted = true;
+       accepted_gatt->user = user_data;
+
+       g_callbacks.accepted_cb(VINE_DP_NOT_IP, accepted_gatt->remote_address, 0, accepted_gatt, user_data);
+}
+
+static void __invoke_connected_cb(int result, void *user_data)
+{
+       if (!g_callbacks.connected_cb)
+               return;
+       g_callbacks.connected_cb(result, user_data);
+}
+
+static void __invoke_terminated_cb(void *user_data)
+{
+       if (!g_callbacks.terminated_cb)
+               return;
+       g_callbacks.terminated_cb(user_data);
+}
+
+// Server Callbacks
+static void __gatt_server_read_value_requested_cb(
+        const char *remote_address, int request_id,
+        bt_gatt_server_h server, bt_gatt_h gatt_handle,
+        int offset, void *user_data)
+{
+       // TODO: Send response.
+}
+
+static void __gatt_server_write_value_requested_cb(const char *remote_address,
+        int request_id, bt_gatt_server_h server,
+        bt_gatt_h gatt_handle, bool response_needed, int offset,
+        const char *value, int len, void *user_data)
+{
+       VINE_LOGI("Got write value requestment from %s.", remote_address);
+
+       // TODO: Send response.
+}
+
+void __gatt_server_noti_state_changed_cb(bool notify, bt_gatt_server_h server,
+               bt_gatt_h gatt_handle, void *user_data)
+{
+       VINE_LOGI("Noti state changed. notify[%d] characteristic[%p]", notify, gatt_handle);
+}
+
+// Client Callbacks
+static void __gatt_client_service_changed_cb(bt_gatt_client_h client,
+               bt_gatt_client_service_change_type_e type, const char *uuid, void *user_data)
+{
+       VINE_LOGI("gatt[%p] service[%s] is %s",
+                       type == BT_GATT_CLIENT_SERVICE_ADDED ? "added." : "removed." );
+}
+
+static int __update_gatt_service_info(const char *remote_address, vine_gatt_s *gatt)
+{
+       RET_VAL_IF(gatt == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "gatt is NULL");
+       RET_VAL_IF(remote_address == NULL,
+                       VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "remote_address is NULL");
+
+       bt_gatt_client_h client = NULL;
+       bt_gatt_h service = NULL;
+       bt_gatt_h characteristic = NULL;
+       int ret;
+
+       ret = bt_gatt_client_create(remote_address, &client);
+       if (ret != BT_ERROR_NONE || !client)
+               return __convert_bt_error_to_data_path_error(ret);
+
+       ret = bt_gatt_client_set_service_changed_cb(client, __gatt_client_service_changed_cb, gatt);
+       if (ret != BT_ERROR_NONE)
+               goto ERR;
+
+       ret = bt_gatt_client_get_service(client, VINE_GATT_SERVICE_UUID, &service);
+       if (ret != BT_ERROR_NONE)
+               goto ERR;
+
+    ret = bt_gatt_service_get_characteristic(service, VINE_GATT_CHAR_UUID, &characteristic);
+       if (ret != BT_ERROR_NONE)
+               goto ERR;
+
+       gatt->role.client = client;
+       gatt->service = service;
+       gatt->characteristic = characteristic;
+
+       VINE_LOGE("Succeeded to update GATT service info.");
+       return VINE_DATA_PATH_ERROR_NONE;
+
+ERR:
+       VINE_LOGE("Failed to update GATT service info.");
+       bt_gatt_client_destroy(client);
+       return __convert_bt_error_to_data_path_error(ret);
+}
+
+static void __gatt_connection_state_changed_cb(int result, bool connected,
+                                      const char *remote_address, void *user_data)
+{
+       RET_IF(user_data == NULL, "user_data is NULL");
+
+       vine_gatt_s *gatt = (vine_gatt_s *)user_data;
+
+       VINE_LOGI("gatt[%p] result[%d] connected[%d] remote address[%s]",
+                       gatt, result, connected, remote_address);
+
+       if (!connected) {
+               __invoke_terminated_cb(gatt->user);
+               return;
+       }
+
+       if (gatt->type == VINE_GATT_ROLE_SERVER) {
+               __invoke_accepted_cb(remote_address, gatt, gatt->user);
+       } else if (gatt->type == VINE_GATT_ROLE_CLIENT) {
+               if (__update_gatt_service_info(remote_address, gatt) != VINE_DATA_PATH_ERROR_NONE) {
+                       bt_gatt_disconnect(remote_address);
+                       result = -1;
+               }
+               __invoke_connected_cb(result, gatt->user);
+       }
+}
+
+static vine_gatt_s *_create_gatt(void)
+{
+       vine_gatt_s *gatt = (vine_gatt_s *)calloc(1, sizeof(vine_gatt_s));
+       RET_VAL_IF(gatt == NULL, NULL, "Out of memory");
+
+       if (bt_gatt_set_connection_state_changed_cb(__gatt_connection_state_changed_cb,
+                               (void *)gatt) != BT_ERROR_NONE) {
+               VINE_LOGE("Failed to register GATT connection state changed callback");
+               free(gatt);
+               return NULL;
+       }
+       return gatt;
+}
+
+static bt_gatt_h _add_gatt_characteristic(bt_gatt_h service, vine_dp_plugin_h handle)
+{
+       bt_gatt_h characteristic = NULL;
+       char initial_value[1] = {'0'}; // TODO: will be changed.
+       int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+       int properties = BT_GATT_PROPERTY_BROADCAST | BT_GATT_PROPERTY_READ |
+               BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
+
+       if (bt_gatt_characteristic_create(VINE_GATT_CHAR_UUID,
+                               permissions, properties,
+                               initial_value, sizeof(initial_value), &characteristic) != BT_ERROR_NONE)
+               return NULL;
+
+       if (bt_gatt_server_set_read_value_requested_cb(characteristic,
+                               __gatt_server_read_value_requested_cb, handle) != BT_ERROR_NONE)
+               goto ERR;
+
+       if (bt_gatt_server_set_write_value_requested_cb(characteristic,
+                               __gatt_server_write_value_requested_cb, handle) != BT_ERROR_NONE)
+               goto ERR;
+
+       if (bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
+                               __gatt_server_noti_state_changed_cb, handle) != BT_ERROR_NONE)
+               goto ERR;
+
+       if (bt_gatt_service_add_characteristic(service, characteristic) != BT_ERROR_NONE)
+               goto ERR;
+
+       VINE_LOGI("Succeeded to add GATT characteristic.");
+       return characteristic;
+
+ERR:
+       bt_gatt_characteristic_destroy(characteristic);
+       return NULL;
+}
+
+static bt_gatt_h _add_gatt_descriptor(bt_gatt_h characteristic)
+{
+       bt_gatt_h descriptor = NULL;
+       char initial_value[1] = {'0'}; // TODO: will be changed
+       int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+
+       // TODO: Change UUID
+       if (bt_gatt_descriptor_create("2902", permissions,
+                               initial_value, sizeof(initial_value), &descriptor) != BT_ERROR_NONE)
+               return NULL;
+
+       if (bt_gatt_characteristic_add_descriptor(characteristic, descriptor) != BT_ERROR_NONE) {
+               bt_gatt_descriptor_destroy(descriptor);
+               return NULL;
+       }
+       return descriptor;
+}
+
+int gatt_init(void)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+void gatt_deinit(void)
+{
+}
+
+void gatt_register_callbacks(vine_dp_plugin_callbacks callbacks)
+{
+       g_callbacks = callbacks;
+}
+
+void gatt_process_event(int gatt_fd, int events)
+{
+       // Do nothing. use g_main_loop.
+}
+
+int gatt_create(vine_dp_plugin_h *handle, void *plugin_data, void *user)
+{
+       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
+       RET_VAL_IF(user == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "user is NULL");
+
+       vine_gatt_s *gatt = _create_gatt();
+       RET_VAL_IF(gatt == NULL, VINE_DATA_PATH_ERROR_OUT_OF_MEMORY, "Out of memory");
+
+       gatt->user = user;
+       *handle = gatt;
+
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_destroy(vine_dp_plugin_h handle)
+{
+       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
+
+       vine_gatt_s *gatt = (vine_gatt_s *)handle;
+
+       if (gatt->type == VINE_GATT_ROLE_SERVER) {
+               bt_gatt_server_destroy(gatt->role.server);
+               gatt->role.server = NULL;
+               bt_gatt_service_destroy(gatt->service);
+               bt_gatt_characteristic_destroy(gatt->characteristic);
+               bt_gatt_descriptor_destroy(gatt->descriptor);
+       } else if (gatt->type == VINE_GATT_ROLE_CLIENT) {
+               // bt_gatt_h handles will be freed during bt_gatt_client_destroy().
+               bt_gatt_client_destroy(gatt->role.client);
+               gatt->role.client = NULL;
+       }
+
+       gatt->service = NULL;
+       gatt->characteristic = NULL;
+       gatt->descriptor = NULL;
+       free(gatt->remote_address);
+       gatt->remote_address = NULL;
+       free(gatt);
+
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+// All parameters except handle are not used in BT GATT.
+int gatt_open(vine_dp_plugin_h handle, int addr_family,
+               int gatt_port, const char *iface_name, int max_conn, vine_dp_ssl ssl) // server only
+{
+       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
+
+       vine_gatt_s *gatt = (vine_gatt_s *)handle;
+       bt_gatt_server_h server = NULL;
+       bt_gatt_h service = NULL;
+       bt_gatt_h characteristic = NULL;
+       bt_gatt_h descriptor = NULL;
+       int ret = BT_ERROR_OPERATION_FAILED;
+
+       // This returns OPERATION_FAILED when already initialized. ignore it.
+       bt_gatt_server_initialize();
+
+       ret = bt_gatt_server_create(&server);
+       if (ret != BT_ERROR_NONE || !server) {
+               VINE_LOGE("Failed to create GATT server");
+               goto ERR;
+       }
+
+       ret = bt_gatt_service_create(VINE_GATT_SERVICE_UUID, BT_GATT_SERVICE_TYPE_PRIMARY, &service);
+        if (ret != BT_ERROR_NONE) {
+               VINE_LOGE("Failed to create service.");
+               goto ERR;
+       }
+
+       characteristic = _add_gatt_characteristic(service, handle);
+       if (!characteristic) {
+               VINE_LOGE("Failed to add characteristc.");
+               goto ERR;
+       }
+
+       descriptor = _add_gatt_descriptor(characteristic);
+       if (!characteristic) {
+               VINE_LOGE("Failed to add descriptor.");
+               goto ERR;
+       }
+
+    ret = bt_gatt_server_register_service(server, service);
+       if (ret != BT_ERROR_NONE) {
+               VINE_LOGE("Failed to register service.");
+               goto ERR;
+       }
+
+    ret = bt_gatt_server_start();
+       if (ret != BT_ERROR_NONE) {
+               VINE_LOGE("Failed to start GATT server.");
+               goto ERR;
+       }
+
+       gatt->type = VINE_GATT_ROLE_SERVER;
+       gatt->role.server = server;
+       gatt->service = service;
+       gatt->characteristic = characteristic;
+       gatt->descriptor = descriptor;
+
+       VINE_LOGI("Succeeded to start GATT server.");
+       return VINE_DATA_PATH_ERROR_NONE;
+
+ERR:
+       if (server)
+               bt_gatt_server_destroy(server);
+       if (service)
+               bt_gatt_service_destroy(service);
+       if (characteristic)
+               bt_gatt_characteristic_destroy(characteristic);
+       if (descriptor)
+               bt_gatt_descriptor_destroy(descriptor);
+       return ret;
+}
+
+// All parameters except handle and addr are not used in BT GATT.
+int gatt_connect(vine_dp_plugin_h handle, int addr_family,
+               const char *addr, int gatt_port, const char *iface_name, vine_dp_ssl ssl)
+{
+       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
+       RET_VAL_IF(addr == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "addr is NULL");
+
+       vine_gatt_s *gatt = (vine_gatt_s *)handle;
+       bt_gatt_client_h client = NULL;
+       int ret;
+
+       ret = bt_gatt_connect(addr, false);
+       if (ret != BT_ERROR_NONE) {
+               VINE_LOGE("Failed to connect remote LE based service.");
+               return __convert_bt_error_to_data_path_error(ret);
+       }
+
+       gatt->type = VINE_GATT_ROLE_CLIENT;
+       gatt->role.client = client;
+       gatt->remote_address = STRDUP(addr);
+
+       VINE_LOGI("Succeed to request to GATT connect.");
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_read(vine_dp_plugin_h handle, unsigned char *buf, size_t len)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_write(vine_dp_plugin_h handle, unsigned char *buf, size_t len)
+{
+       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
+       RET_VAL_IF(buf == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "buf is NULL");
+       RET_VAL_IF(len <= 0, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "len is less than 0");
+
+       // TODO
+       // vine_gatt_s *gatt = (vine_gatt_s *)handle;
+
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_close(vine_dp_plugin_h handle)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_get_local_address_info(vine_dp_plugin_h handle,
+               int *addr_family, char local_ip[], int *port)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_set_token(vine_dp_plugin_h handle, const char *token)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_get_token(vine_dp_plugin_h handle, char **token)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+int gatt_set_host_name(vine_dp_plugin_h handle, const char *name)
+{
+       return VINE_DATA_PATH_ERROR_NONE;
+}
+
+void vine_data_path_plugin_init(vine_dp_plugin_fn *fn)
+{
+       fn->init = gatt_init;
+       fn->deinit = gatt_deinit;
+       fn->register_callbacks = gatt_register_callbacks;
+       fn->process_event = gatt_process_event;
+
+       fn->create = gatt_create;
+       fn->destroy = gatt_destroy;
+       fn->open = gatt_open;
+       fn->connect = gatt_connect;
+       fn->read = gatt_read;
+       fn->write = gatt_write;
+       fn->close = gatt_close;
+
+       fn->get_local_address_info = gatt_get_local_address_info;
+
+       fn->set_token = gatt_set_token;
+       fn->get_token = gatt_get_token;
+       fn->set_host_name = gatt_set_host_name;
+}
diff --git a/plugins/ble-gatt/ble-gatt-plugin.h b/plugins/ble-gatt/ble-gatt-plugin.h
new file mode 100755 (executable)
index 0000000..d1766f0
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+#pragma once
diff --git a/plugins/ble/gatt-plugin.cpp b/plugins/ble/gatt-plugin.cpp
deleted file mode 100755 (executable)
index 19898d0..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
-*/
-
-#include <bluetooth.h>
-
-#include "vine-data-path-plugin.h"
-#include "vine-log.h"
-#include "vine-utils.h"
-
-using namespace std;
-
-// TODO: change UUIDs
-#define VINE_GATT_SERVICE_UUID "000018f2-0000-1000-8000-00805f9b34fb"
-#define VINE_GATT_CHAR_UUID "00002af6-0000-1000-8000-00805f9b34fb"
-#define VINE_GATT_DESC_UUID "fa87c0d0-afac-11de-8a39-0800200c9a66"
-
-typedef enum {
-       VINE_GATT_ROLE_UNKNOWN = 0,
-       VINE_GATT_ROLE_SERVER,
-       VINE_GATT_ROLE_CLIENT,
-} vine_gatt_role_e;
-
-typedef struct {
-       bt_gatt_h service;
-       bt_gatt_h characteristic;
-       bt_gatt_h descriptor;
-
-       vine_gatt_role_e type;
-       union {
-               bt_gatt_server_h server;
-               bt_gatt_client_h client;
-       } role;
-
-       char *remote_address;
-       bool is_accepted;
-       void *user; // vine_data_path_h
-} vine_gatt_s;
-
-static vine_dp_plugin_callbacks g_callbacks = {
-    .pollfd_cb = NULL,
-    .opened_cb = NULL,
-    .accepted_cb = NULL,
-    .connected_cb = NULL,
-    .received_cb = NULL,
-    .written_cb = NULL,
-    .terminated_cb = NULL,
-};
-
-static vine_gatt_s *_create_gatt(void);
-
-static vine_data_path_error __convert_bt_error_to_data_path_error(int error)
-{
-       switch (error) {
-       case BT_ERROR_NONE:
-               return VINE_DATA_PATH_ERROR_NONE;
-       case BT_ERROR_OUT_OF_MEMORY:
-               return VINE_DATA_PATH_ERROR_OUT_OF_MEMORY;
-       case BT_ERROR_INVALID_PARAMETER:
-               return VINE_DATA_PATH_ERROR_INVALID_PARAMETER;
-       case BT_ERROR_OPERATION_FAILED:
-       default:
-               return VINE_DATA_PATH_ERROR_OPERATION_FAILED;
-       }
-}
-
-static void __invoke_accepted_cb(const char *remote_address, vine_gatt_s *gatt, void *user_data)
-{
-       if (!g_callbacks.accepted_cb)
-               return;
-
-       vine_gatt_s *accepted_gatt = _create_gatt();
-       RET_IF(accepted_gatt == NULL, "Failed to create accepted_gatt.");
-
-       accepted_gatt->remote_address = STRDUP(remote_address);
-
-       // refer to server's gatt handles.
-       accepted_gatt->service = gatt->service;
-       accepted_gatt->characteristic = gatt->characteristic;
-       accepted_gatt->descriptor = gatt->descriptor;
-
-       accepted_gatt->is_accepted = true;
-       accepted_gatt->user = user_data;
-
-       g_callbacks.accepted_cb(VINE_DP_NOT_IP, accepted_gatt->remote_address, 0, accepted_gatt, user_data);
-}
-
-static void __invoke_connected_cb(int result, void *user_data)
-{
-       if (!g_callbacks.connected_cb)
-               return;
-       g_callbacks.connected_cb(result, user_data);
-}
-
-static void __invoke_terminated_cb(void *user_data)
-{
-       if (!g_callbacks.terminated_cb)
-               return;
-       g_callbacks.terminated_cb(user_data);
-}
-
-// Server Callbacks
-static void __gatt_server_read_value_requested_cb(
-        const char *remote_address, int request_id,
-        bt_gatt_server_h server, bt_gatt_h gatt_handle,
-        int offset, void *user_data)
-{
-       // TODO: Send response.
-}
-
-static void __gatt_server_write_value_requested_cb(const char *remote_address,
-        int request_id, bt_gatt_server_h server,
-        bt_gatt_h gatt_handle, bool response_needed, int offset,
-        const char *value, int len, void *user_data)
-{
-       VINE_LOGI("Got write value requestment from %s.", remote_address);
-
-       // TODO: Send response.
-}
-
-void __gatt_server_noti_state_changed_cb(bool notify, bt_gatt_server_h server,
-               bt_gatt_h gatt_handle, void *user_data)
-{
-       VINE_LOGI("Noti state changed. notify[%d] characteristic[%p]", notify, gatt_handle);
-}
-
-// Client Callbacks
-static void __gatt_client_service_changed_cb(bt_gatt_client_h client,
-               bt_gatt_client_service_change_type_e type, const char *uuid, void *user_data)
-{
-       VINE_LOGI("gatt[%p] service[%s] is %s",
-                       type == BT_GATT_CLIENT_SERVICE_ADDED ? "added." : "removed." );
-}
-
-static int __update_gatt_service_info(const char *remote_address, vine_gatt_s *gatt)
-{
-       RET_VAL_IF(gatt == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "gatt is NULL");
-       RET_VAL_IF(remote_address == NULL,
-                       VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "remote_address is NULL");
-
-       bt_gatt_client_h client = NULL;
-       bt_gatt_h service = NULL;
-       bt_gatt_h characteristic = NULL;
-       int ret;
-
-       ret = bt_gatt_client_create(remote_address, &client);
-       if (ret != BT_ERROR_NONE || !client)
-               return __convert_bt_error_to_data_path_error(ret);
-
-       ret = bt_gatt_client_set_service_changed_cb(client, __gatt_client_service_changed_cb, gatt);
-       if (ret != BT_ERROR_NONE)
-               goto ERR;
-
-       ret = bt_gatt_client_get_service(client, VINE_GATT_SERVICE_UUID, &service);
-       if (ret != BT_ERROR_NONE)
-               goto ERR;
-
-    ret = bt_gatt_service_get_characteristic(service, VINE_GATT_CHAR_UUID, &characteristic);
-       if (ret != BT_ERROR_NONE)
-               goto ERR;
-
-       gatt->role.client = client;
-       gatt->service = service;
-       gatt->characteristic = characteristic;
-
-       VINE_LOGE("Succeeded to update GATT service info.");
-       return VINE_DATA_PATH_ERROR_NONE;
-
-ERR:
-       VINE_LOGE("Failed to update GATT service info.");
-       bt_gatt_client_destroy(client);
-       return __convert_bt_error_to_data_path_error(ret);
-}
-
-static void __gatt_connection_state_changed_cb(int result, bool connected,
-                                      const char *remote_address, void *user_data)
-{
-       RET_IF(user_data == NULL, "user_data is NULL");
-
-       vine_gatt_s *gatt = (vine_gatt_s *)user_data;
-
-       VINE_LOGI("gatt[%p] result[%d] connected[%d] remote address[%s]",
-                       gatt, result, connected, remote_address);
-
-       if (!connected) {
-               __invoke_terminated_cb(gatt->user);
-               return;
-       }
-
-       if (gatt->type == VINE_GATT_ROLE_SERVER) {
-               __invoke_accepted_cb(remote_address, gatt, gatt->user);
-       } else if (gatt->type == VINE_GATT_ROLE_CLIENT) {
-               if (__update_gatt_service_info(remote_address, gatt) != VINE_DATA_PATH_ERROR_NONE) {
-                       bt_gatt_disconnect(remote_address);
-                       result = -1;
-               }
-               __invoke_connected_cb(result, gatt->user);
-       }
-}
-
-static vine_gatt_s *_create_gatt(void)
-{
-       vine_gatt_s *gatt = (vine_gatt_s *)calloc(1, sizeof(vine_gatt_s));
-       RET_VAL_IF(gatt == NULL, NULL, "Out of memory");
-
-       if (bt_gatt_set_connection_state_changed_cb(__gatt_connection_state_changed_cb,
-                               (void *)gatt) != BT_ERROR_NONE) {
-               VINE_LOGE("Failed to register GATT connection state changed callback");
-               free(gatt);
-               return NULL;
-       }
-       return gatt;
-}
-
-static bt_gatt_h _add_gatt_characteristic(bt_gatt_h service, vine_dp_plugin_h handle)
-{
-       bt_gatt_h characteristic = NULL;
-       char initial_value[1] = {'0'}; // TODO: will be changed.
-       int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
-       int properties = BT_GATT_PROPERTY_BROADCAST | BT_GATT_PROPERTY_READ |
-               BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_NOTIFY;
-
-       if (bt_gatt_characteristic_create(VINE_GATT_CHAR_UUID,
-                               permissions, properties,
-                               initial_value, sizeof(initial_value), &characteristic) != BT_ERROR_NONE)
-               return NULL;
-
-       if (bt_gatt_server_set_read_value_requested_cb(characteristic,
-                               __gatt_server_read_value_requested_cb, handle) != BT_ERROR_NONE)
-               goto ERR;
-
-       if (bt_gatt_server_set_write_value_requested_cb(characteristic,
-                               __gatt_server_write_value_requested_cb, handle) != BT_ERROR_NONE)
-               goto ERR;
-
-       if (bt_gatt_server_set_characteristic_notification_state_change_cb(characteristic,
-                               __gatt_server_noti_state_changed_cb, handle) != BT_ERROR_NONE)
-               goto ERR;
-
-       if (bt_gatt_service_add_characteristic(service, characteristic) != BT_ERROR_NONE)
-               goto ERR;
-
-       VINE_LOGI("Succeeded to add GATT characteristic.");
-       return characteristic;
-
-ERR:
-       bt_gatt_characteristic_destroy(characteristic);
-       return NULL;
-}
-
-static bt_gatt_h _add_gatt_descriptor(bt_gatt_h characteristic)
-{
-       bt_gatt_h descriptor = NULL;
-       char initial_value[1] = {'0'}; // TODO: will be changed
-       int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
-
-       // TODO: Change UUID
-       if (bt_gatt_descriptor_create("2902", permissions,
-                               initial_value, sizeof(initial_value), &descriptor) != BT_ERROR_NONE)
-               return NULL;
-
-       if (bt_gatt_characteristic_add_descriptor(characteristic, descriptor) != BT_ERROR_NONE) {
-               bt_gatt_descriptor_destroy(descriptor);
-               return NULL;
-       }
-       return descriptor;
-}
-
-int gatt_init(void)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-void gatt_deinit(void)
-{
-}
-
-void gatt_register_callbacks(vine_dp_plugin_callbacks callbacks)
-{
-       g_callbacks = callbacks;
-}
-
-void gatt_process_event(int gatt_fd, int events)
-{
-       // Do nothing. use g_main_loop.
-}
-
-int gatt_create(vine_dp_plugin_h *handle, void *plugin_data, void *user)
-{
-       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
-       RET_VAL_IF(user == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "user is NULL");
-
-       vine_gatt_s *gatt = _create_gatt();
-       RET_VAL_IF(gatt == NULL, VINE_DATA_PATH_ERROR_OUT_OF_MEMORY, "Out of memory");
-
-       gatt->user = user;
-       *handle = gatt;
-
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_destroy(vine_dp_plugin_h handle)
-{
-       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
-
-       vine_gatt_s *gatt = (vine_gatt_s *)handle;
-
-       if (gatt->type == VINE_GATT_ROLE_SERVER) {
-               bt_gatt_server_destroy(gatt->role.server);
-               gatt->role.server = NULL;
-               bt_gatt_service_destroy(gatt->service);
-               bt_gatt_characteristic_destroy(gatt->characteristic);
-               bt_gatt_descriptor_destroy(gatt->descriptor);
-       } else if (gatt->type == VINE_GATT_ROLE_CLIENT) {
-               // bt_gatt_h handles will be freed during bt_gatt_client_destroy().
-               bt_gatt_client_destroy(gatt->role.client);
-               gatt->role.client = NULL;
-       }
-
-       gatt->service = NULL;
-       gatt->characteristic = NULL;
-       gatt->descriptor = NULL;
-       free(gatt->remote_address);
-       gatt->remote_address = NULL;
-       free(gatt);
-
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-// All parameters except handle are not used in BT GATT.
-int gatt_open(vine_dp_plugin_h handle, int addr_family,
-               int gatt_port, const char *iface_name, int max_conn, vine_dp_ssl ssl) // server only
-{
-       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
-
-       vine_gatt_s *gatt = (vine_gatt_s *)handle;
-       bt_gatt_server_h server = NULL;
-       bt_gatt_h service = NULL;
-       bt_gatt_h characteristic = NULL;
-       bt_gatt_h descriptor = NULL;
-       int ret = BT_ERROR_OPERATION_FAILED;
-
-       // This returns OPERATION_FAILED when already initialized. ignore it.
-       bt_gatt_server_initialize();
-
-       ret = bt_gatt_server_create(&server);
-       if (ret != BT_ERROR_NONE || !server) {
-               VINE_LOGE("Failed to create GATT server");
-               goto ERR;
-       }
-
-       ret = bt_gatt_service_create(VINE_GATT_SERVICE_UUID, BT_GATT_SERVICE_TYPE_PRIMARY, &service);
-        if (ret != BT_ERROR_NONE) {
-               VINE_LOGE("Failed to create service.");
-               goto ERR;
-       }
-
-       characteristic = _add_gatt_characteristic(service, handle);
-       if (!characteristic) {
-               VINE_LOGE("Failed to add characteristc.");
-               goto ERR;
-       }
-
-       descriptor = _add_gatt_descriptor(characteristic);
-       if (!characteristic) {
-               VINE_LOGE("Failed to add descriptor.");
-               goto ERR;
-       }
-
-    ret = bt_gatt_server_register_service(server, service);
-       if (ret != BT_ERROR_NONE) {
-               VINE_LOGE("Failed to register service.");
-               goto ERR;
-       }
-
-    ret = bt_gatt_server_start();
-       if (ret != BT_ERROR_NONE) {
-               VINE_LOGE("Failed to start GATT server.");
-               goto ERR;
-       }
-
-       gatt->type = VINE_GATT_ROLE_SERVER;
-       gatt->role.server = server;
-       gatt->service = service;
-       gatt->characteristic = characteristic;
-       gatt->descriptor = descriptor;
-
-       VINE_LOGI("Succeeded to start GATT server.");
-       return VINE_DATA_PATH_ERROR_NONE;
-
-ERR:
-       if (server)
-               bt_gatt_server_destroy(server);
-       if (service)
-               bt_gatt_service_destroy(service);
-       if (characteristic)
-               bt_gatt_characteristic_destroy(characteristic);
-       if (descriptor)
-               bt_gatt_descriptor_destroy(descriptor);
-       return ret;
-}
-
-// All parameters except handle and addr are not used in BT GATT.
-int gatt_connect(vine_dp_plugin_h handle, int addr_family,
-               const char *addr, int gatt_port, const char *iface_name, vine_dp_ssl ssl)
-{
-       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
-       RET_VAL_IF(addr == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "addr is NULL");
-
-       vine_gatt_s *gatt = (vine_gatt_s *)handle;
-       bt_gatt_client_h client = NULL;
-       int ret;
-
-       ret = bt_gatt_connect(addr, false);
-       if (ret != BT_ERROR_NONE) {
-               VINE_LOGE("Failed to connect remote LE based service.");
-               return __convert_bt_error_to_data_path_error(ret);
-       }
-
-       gatt->type = VINE_GATT_ROLE_CLIENT;
-       gatt->role.client = client;
-       gatt->remote_address = STRDUP(addr);
-
-       VINE_LOGI("Succeed to request to GATT connect.");
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_read(vine_dp_plugin_h handle, unsigned char *buf, size_t len)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_write(vine_dp_plugin_h handle, unsigned char *buf, size_t len)
-{
-       RET_VAL_IF(handle == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "handle is NULL");
-       RET_VAL_IF(buf == NULL, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "buf is NULL");
-       RET_VAL_IF(len <= 0, VINE_DATA_PATH_ERROR_INVALID_PARAMETER, "len is less than 0");
-
-       // TODO
-       // vine_gatt_s *gatt = (vine_gatt_s *)handle;
-
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_close(vine_dp_plugin_h handle)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_get_local_address_info(vine_dp_plugin_h handle,
-               int *addr_family, char local_ip[], int *port)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_set_token(vine_dp_plugin_h handle, const char *token)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_get_token(vine_dp_plugin_h handle, char **token)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-int gatt_set_host_name(vine_dp_plugin_h handle, const char *name)
-{
-       return VINE_DATA_PATH_ERROR_NONE;
-}
-
-void vine_data_path_plugin_init(vine_dp_plugin_fn *fn)
-{
-       fn->init = gatt_init;
-       fn->deinit = gatt_deinit;
-       fn->register_callbacks = gatt_register_callbacks;
-       fn->process_event = gatt_process_event;
-
-       fn->create = gatt_create;
-       fn->destroy = gatt_destroy;
-       fn->open = gatt_open;
-       fn->connect = gatt_connect;
-       fn->read = gatt_read;
-       fn->write = gatt_write;
-       fn->close = gatt_close;
-
-       fn->get_local_address_info = gatt_get_local_address_info;
-
-       fn->set_token = gatt_set_token;
-       fn->get_token = gatt_get_token;
-       fn->set_host_name = gatt_set_host_name;
-}