--- /dev/null
+# 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_PLUGIN "vine-plugin-ble")
+
+SET(BLE_PLUGIN_VERSION_MAJOR "1")
+SET(BLE_PLUGIN_VERSION_MINOR "0")
+SET(BLE_PLUGIN_VERSION_PATCH "0")
+SET(BLE_PLUGIN_VERSION ${BLE_PLUGIN_VERSION_MAJOR}.${BLE_PLUGIN_VERSION_MINOR}.${BLE_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_PLUGIN_SOURCES *.cpp)
+
+ADD_DEFINITIONS("-fvisibility=default")
+ADD_LIBRARY(${BLE_PLUGIN} SHARED ${VINE_BLE_PLUGIN_SOURCES})
+
+SET_TARGET_PROPERTIES(
+ ${BLE_PLUGIN}
+ PROPERTIES
+ SOVERSION ${BLE_PLUGIN_VERSION_MAJOR}
+)
+
+TARGET_LINK_LIBRARIES(${BLE_PLUGIN}
+ ${VINE_LOGGER}
+ ${BLE_DEPS_LIBRARIES}
+ ${fw_name_deps_LIBRARIES}
+ dl
+)
+
+INSTALL(TARGETS ${BLE_PLUGIN} DESTINATION "${LIB_DIR}")
--- /dev/null
+/*
+ * 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 <string>
+
+#include <bluetooth.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <errno.h>
+
+#include "vine-constants.h"
+#include "vine-disc-plugin.h"
+#include "vine-log.h"
+#include "vine-utils.h"
+#include "ble-plugin.h"
+
+#define VINE_UUID "29AD"
+
+typedef struct {
+ void *disc_handle;
+ bt_advertiser_h adv;
+} vine_ble_s;
+
+static vine_disc_plugin_callbacks event_callbacks;
+
+static vine_disc_error __convert_ble_error_to_vine_disc_error(int error)
+{
+ switch (error) {
+ case BT_ERROR_NONE:
+ return VINE_DISC_ERROR_NONE;
+ default:
+ VINE_LOGE("Unknown error %d", error);
+ return VINE_DISC_ERROR_OPERATION_FAILED;
+ }
+}
+
+
+vine_disc_error ble_resolve_ip(void *plugin_handle,
+ const char *service_type, const char *service_name,
+ const char *host_name, const char *iface_name, int family)
+{
+ VINE_LOGE("Not supported function");
+ return VINE_DISC_ERROR_NOT_SUPPORTED;
+}
+
+vine_disc_error ble_cancel_resolve_ip(void *plugin_handle)
+{
+ VINE_LOGE("Not supported function");
+ return VINE_DISC_ERROR_NOT_SUPPORTED;
+}
+
+
+vine_disc_error ble_init(void **plugin_handle, void *disc_handle)
+{
+ int ret = bt_initialize();
+ RET_VAL_IF(ret != BT_ERROR_NONE, __convert_ble_error_to_vine_disc_error(ret),
+ "bt_initialize() fails");
+
+ vine_ble_s *handle = new vine_ble_s;
+
+ handle->disc_handle = disc_handle;
+ handle->adv = NULL;
+ *plugin_handle = handle;
+
+ return VINE_DISC_ERROR_NONE;
+}
+
+void ble_deinit(void *plugin_handle)
+{
+ RET_IF(plugin_handle == NULL, "Plugin handle is null");
+ vine_ble_s *ble_handle = (vine_ble_s *)plugin_handle;
+
+ delete ble_handle;
+
+ int ret = bt_deinitialize();
+ RET_IF(ret != BT_ERROR_NONE, "bt_deinitialize() fails");
+}
+
+static void __ble_advertising_state_changed_cb(int result, bt_advertiser_h advertiser,
+ bt_adapter_le_advertising_state_e adv_state, void *user_data)
+{
+ VINE_LOGD("BLE advertising state is changed. result: %d, state: %d", result, adv_state);
+}
+
+vine_disc_error ble_publish(void *plugin_handle, const char *service_type,
+ const char *service_name, int port, const map<string, string> &attributes,
+ const char *iface_name)
+{
+ RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL");
+ RET_VAL_IF(!service_type, VINE_DISC_ERROR_INVALID_PARAMETER, "service_type is NULL");
+ RET_VAL_IF(!service_name, VINE_DISC_ERROR_INVALID_PARAMETER, "service_name is NULL");
+
+ vine_ble_s *ble_handle = (vine_ble_s *)plugin_handle;
+ RET_VAL_IF(ble_handle->adv != NULL, VINE_DISC_ERROR_INVALID_PARAMETER, "Already published");
+
+ // TODO: Determine which data should be set for service_data
+ char service_data[3] = {0x01, 0x02, 0x03};
+
+ int ret = bt_adapter_le_create_advertiser(&ble_handle->adv);
+ RET_VAL_IF(ret != BT_ERROR_NONE, __convert_ble_error_to_vine_disc_error(ret),
+ "bt_adapter_le_create_advertiser() fails");
+
+ ret = bt_adapter_le_add_advertising_service_uuid(ble_handle->adv,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, VINE_UUID);
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_add_advertising_service_uuid() fails %d", ret);
+ goto error;
+ }
+
+ // TODO: ALso set for BT_ADAPTER_LE_PACKET_ADVERTISING?
+ ret = bt_adapter_le_add_advertising_service_data(ble_handle->adv,
+ BT_ADAPTER_LE_PACKET_SCAN_RESPONSE,
+ VINE_UUID, service_data, sizeof(service_data));
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_add_advertising_service_data() fails %d", ret);
+ goto error;
+ }
+
+ // TODO: Also set for BT_ADAPTER_LE_PACKET_SCAN_RESPONSE?
+ ret = bt_adapter_le_set_advertising_device_name(ble_handle->adv,
+ BT_ADAPTER_LE_PACKET_ADVERTISING, true);
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_set_advertising_device_name() fails %d", ret);
+ goto error;
+ }
+
+ ret = bt_adapter_le_set_advertising_connectable(ble_handle->adv, true);
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_set_advertising_connectable() fails %d", ret);
+ goto error;
+ }
+
+ ret = bt_adapter_le_set_advertising_mode(ble_handle->adv,
+ BT_ADAPTER_LE_ADVERTISING_MODE_BALANCED);
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_set_advertising_mode() fails %d", ret);
+ goto error;
+ }
+
+ ret = bt_adapter_le_start_advertising_new(ble_handle->adv,
+ __ble_advertising_state_changed_cb, ble_handle);
+ if (ret != BT_ERROR_NONE) {
+ VINE_LOGE("bt_adapter_le_start_advertising_new() fails %d", ret);
+ goto error;
+ }
+
+error:
+ if (ble_handle->adv) {
+ bt_adapter_le_destroy_advertiser(ble_handle->adv);
+ ble_handle->adv = NULL;
+ }
+
+ return __convert_ble_error_to_vine_disc_error(ret);
+}
+
+vine_disc_error ble_stop_publish(void *plugin_handle)
+{
+ RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL");
+
+ return VINE_DISC_ERROR_NONE;
+}
+
+vine_disc_error ble_subscribe(void *plugin_handle,
+ const char *service_type, const char *iface_name)
+{
+ RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL");
+ RET_VAL_IF(!service_type, VINE_DISC_ERROR_INVALID_PARAMETER, "service_type is NULL");
+
+ vine_ble_s *ble_handle = (vine_ble_s *)plugin_handle;
+
+ return VINE_DISC_ERROR_NONE;
+}
+
+vine_disc_error ble_stop_subscribe(void *plugin_handle)
+{
+ RET_VAL_IF(!plugin_handle, VINE_DISC_ERROR_INVALID_PARAMETER, "plugin_handle is NULL");
+
+ return VINE_DISC_ERROR_NONE;
+}
+
+vine_disc_error ble_process_event(void *plugin_handle, int fd)
+{
+ VINE_LOGE("Not supported function");
+ return VINE_DISC_ERROR_NOT_SUPPORTED;
+}
+
+void ble_register_callbacks(vine_disc_plugin_callbacks callbacks)
+{
+ event_callbacks.published_cb = callbacks.published_cb;
+ event_callbacks.discovered_cb = callbacks.discovered_cb;
+ event_callbacks.ip_resolved_cb = callbacks.ip_resolved_cb;
+ event_callbacks.fd_added_cb = callbacks.fd_added_cb;
+ event_callbacks.fd_removed_cb = callbacks.fd_removed_cb;
+}
+
+void vine_disc_plugin_init(vine_disc_plugin_fn *fn)
+{
+ fn->init = ble_init;
+ fn->deinit = ble_deinit;
+ fn->publish = ble_publish;
+ fn->stop_publish = ble_stop_publish;
+ fn->subscribe = ble_subscribe;
+ fn->stop_subscribe = ble_stop_subscribe;
+ fn->resolve_ip = ble_resolve_ip;
+ fn->cancel_resolve_ip = ble_cancel_resolve_ip;
+ fn->register_callbacks = ble_register_callbacks;
+ fn->process_event = ble_process_event;
+}
#include <sys/socket.h>
#define DNS_SD_PLUGIN_PATH "libvine-plugin-dns-sd.so"
+#define BLE_PLUGIN_PATH "libvine-plugin-ble.so"
using namespace std;
VINE_DISC_ERROR_NAME_CONFLICT,
VINE_DISC_ERROR_SERVICE_NOT_RUNNING,
VINE_DISC_ERROR_SERVICE_DEREGISTERED,
+ VINE_DISC_ERROR_NOT_SUPPORTED,
} vine_disc_error;
typedef enum {
void (*discovered_cb)(void *plugin_handle, bool available,
const char *service_type, const char *service_name,
const char *host_name, int port, const map<string, string> &attr,
- const char *iface_name, int more_coming, void *user_data);
+ const char *iface_name, int more_coming, void *disc_handle);
void (*ip_resolved_cb)(void *plugin_handle, bool add,
- const char *ip, sa_family_t address_family, void *user_data);
- void (*fd_added_cb)(int fd, void *user_data);
- void (*fd_removed_cb)(int fd, void *user_data);
+ const char *ip, sa_family_t address_family, void *disc_handle);
+ void (*fd_added_cb)(int fd, void *disc_handle);
+ void (*fd_removed_cb)(int fd, void *disc_handle);
} vine_disc_plugin_callbacks;
typedef struct {
const char *path;
} __vine_disc_plugins_info[] = {
[VINE_DISCOVERY_METHOD_DNS_SD] = {"DNS-SD", DNS_SD_PLUGIN_PATH},
+ [VINE_DISCOVERY_METHOD_BLE] = {"BLE", BLE_PLUGIN_PATH},
{NULL, NULL},
};
{NULL, NULL, NULL, NULL, NULL}, NULL},
{{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}, NULL},
+ {{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL}, NULL},
};
typedef struct {
switch (error) {
case VINE_DISC_ERROR_NONE:
return VINE_ERROR_NONE;
+ case VINE_DISC_ERROR_OUT_OF_MEMORY:
+ return VINE_ERROR_OUT_OF_MEMORY;
case VINE_DISC_ERROR_NAME_CONFLICT: // DNS-SD changed the service name
return VINE_ERROR_NAME_CONFLICT;
// TODO: To be determined if which vine error will be returned
case VINE_DISC_ERROR_SERVICE_DEREGISTERED:
return VINE_ERROR_SERVICE_DEREGISTERED;
+ case VINE_DISC_ERROR_NOT_SUPPORTED:
+ return VINE_ERROR_NOT_SUPPORTED;
case VINE_DISC_ERROR_SERVICE_NOT_RUNNING:
default:
return VINE_ERROR_OPERATION_FAILED;