[Adapt: FRWK] Adapt LE Advertising API's for Android HAL 37/119837/1
authorAnupam Roy <anupam.r@samsung.com>
Mon, 20 Mar 2017 08:39:51 +0000 (14:09 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Mon, 20 Mar 2017 08:39:51 +0000 (14:09 +0530)
Change-Id: I640716aa462e0c14c5592fedf41d1c2ac1131980
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
13 files changed:
bt-service-adaptation/CMakeLists.txt
bt-service-adaptation/services/adapter/bt-service-core-adapter-le.c [new file with mode: 0644]
bt-service-adaptation/services/adapter/bt-service-core-adapter.c
bt-service-adaptation/services/bt-request-handler.c
bt-service-adaptation/services/bt-service-common.c
bt-service-adaptation/services/bt-service-event-receiver.c
bt-service-adaptation/services/bt-service-gatt.h [new file with mode: 0644]
bt-service-adaptation/services/gatt/bt-service-gatt.c [new file with mode: 0644]
bt-service-adaptation/services/include/bt-service-common.h
bt-service-adaptation/services/include/bt-service-core-adapter-le.h [new file with mode: 0644]
bt-service-adaptation/services/include/bt-service-event-receiver.h
bt-service-adaptation/services/include/bt-service-gatt.h [new file with mode: 0644]
include/bt-internal-types.h

index 5799aa4..c91996d 100644 (file)
@@ -10,6 +10,7 @@ marshal.c
 ./services/bt-service-util.c
 ./services/bt-request-handler.c
 ./services/adapter/bt-service-core-adapter.c
+./services/adapter/bt-service-core-adapter-le.c
 ./services/device/bt-service-core-device.c
 ./services/bt-service-event-receiver.c
 ./services/bt-service-dpm.c
@@ -24,6 +25,7 @@ marshal.c
 ./services/health/bt-service-hdp.c
 ./services/audio/avrcp/bt-service-avrcp-tg.c
 ./services/audio/avrcp/bt-service-avrcp-ctrl.c
+./services/gatt/bt-service-gatt.c
 )
 
 IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
diff --git a/bt-service-adaptation/services/adapter/bt-service-core-adapter-le.c b/bt-service-adaptation/services/adapter/bt-service-core-adapter-le.c
new file mode 100644 (file)
index 0000000..7065e3d
--- /dev/null
@@ -0,0 +1,901 @@
+/*
+ * Copyright (c) 2016 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <vconf.h>
+#include <syspopup_caller.h>
+#include <aul.h>
+
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+#include "bt-service-core-adapter.h"
+#include "bt-service-core-adapter-le.h"
+#include "bt-service-event-receiver.h"
+#include "bt-service-gatt.h"
+#include "bt-service-util.h"
+
+#include <oal-hardware.h>
+#include <oal-manager.h>
+#include <oal-event.h>
+#include <oal-adapter-mgr.h>
+#include <oal-device-mgr.h>
+#include <oal-gatt.h>
+
+#define BT_UUID_128 16
+#define BT_ADV_DEFAULT_TIMEOUT 0
+#define BT_ADV_DEFAULT_TX_POWER 4
+#define BT_ADV_DEFAULT_CHANNEL_MAP 0
+
+static const char BASE_UUID_CONVERTED[BT_UUID_128] = {
+    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
+    0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+typedef struct {
+       int adv_handle;
+       char *sender;
+       int data_len;
+       unsigned char data[31];
+       gboolean is_adv;/* Adv or Scan Response: Only applicable if is_data_set_pending is TRUE */
+       gboolean is_data_set_pending; /* Data Set pending or Adv enable request at one time */
+       gboolean is_custom_adv; /* If Adv enable is custom adv enable request */
+       bluetooth_advertising_params_t params; /* Adv Parameters */
+} bt_pending_adv_data_set_t;
+
+static GSList *adv_data_pending_list = NULL;
+
+static void __bt_adapter_le_handle_pending_request_info(int result,
+                int service_function, void *data, unsigned int size);
+
+/* Event handlers */
+static void __bt_adapter_le_handle_pending_request_info(int result,
+                int service_function, void *param, unsigned int size)
+{
+        GSList *l;
+        GArray *out_param;
+        invocation_info_t *req_info = NULL;
+        ret_if (param == NULL);
+        BT_DBG("+");
+
+        for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
+                req_info = l->data;
+                if (req_info == NULL || req_info->service_function != service_function)
+                        continue;
+
+                switch (service_function) {
+                case BT_SET_ADVERTISING:
+                case BT_SET_CUSTOM_ADVERTISING:
+                case BT_SET_ADVERTISING_DATA:
+                case BT_SET_SCAN_RESPONSE_DATA: {
+                       BT_DBG("Service function: [%d]",service_function);
+                       int *saved_handle;
+                        bt_pending_adv_data_set_t *data = (bt_pending_adv_data_set_t*)param;
+                       saved_handle = (int*)req_info->user_data;
+                       BT_DBG("Current Sender [%s] Current Handle [%d]", data->sender, data->adv_handle);
+
+                        if (!g_strcmp0(req_info->sender, data->sender) && (*saved_handle == data->adv_handle)) {
+                                BT_DBG("Requester found [%s] ADV Handle [%d]", req_info->sender, *saved_handle);
+                                out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+                                g_array_append_vals(out_param, &data->adv_handle, sizeof(int));
+                                _bt_service_method_return(req_info->context, out_param, result);
+
+                               /* Free data */
+                                g_free(req_info->user_data);
+                                _bt_free_info_from_invocation_list(req_info);
+                                g_array_free(out_param, TRUE);
+                        }
+                       break;
+                }
+                default:
+                        break;
+                }
+        }
+        BT_DBG("-");
+}
+
+static void __bt_le_handle_server_instance_registered(event_gatts_register_t *data)
+{
+       int adv_handle;
+       GSList *l;
+       char *uuid_string = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
+       bluetooth_advertising_data_t adv;
+       bluetooth_scan_resp_data_t scan_rsp;
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_pending_adv_data_set_t *info = NULL;
+
+       memset(adv.data, 0, sizeof(adv.data));
+       memset(scan_rsp.data, 0, sizeof(scan_rsp.data));
+
+       _bt_uuid_to_string(&(data->server_uuid), uuid_string);
+       BT_INFO("Instance ID is Intialized [%d] UUID initialized [%s]", data->server_inst, uuid_string);
+
+       /* Get sender and adv handle for the server instance */
+       _bt_get_adv_handle_from_instance(data->server_inst, &adv_handle);
+
+       if (adv_handle > 0) {
+               /* Check if pending Adv Data set or Scan response data set request is pending*/
+               for (l = adv_data_pending_list; l != NULL; l = l->next) {
+                       info = l->data;
+
+                       if (info && (adv_handle == info->adv_handle)) {
+                               if (info->is_data_set_pending) {
+                                       BT_INFO("LE Data set request is pending");
+                                       if (info->is_adv) {
+                                               memcpy(&adv.data, info->data, info->data_len);
+                                               result = _bt_set_advertising_data(info->sender,
+                                                       info->adv_handle, &adv, info->data_len, FALSE);
+                                               if (result != BLUETOOTH_ERROR_NONE) {
+                                                       __bt_adapter_le_handle_pending_request_info(result,
+                                                               BT_SET_ADVERTISING_DATA,
+                                                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+                                               }
+                                               goto data_free;
+                                       } else {
+                                               memcpy(&scan_rsp.data, info->data, info->data_len);
+                                               result = _bt_set_scan_response_data(info->sender,
+                                                               info->adv_handle, &scan_rsp, info->data_len, FALSE);
+                                               if (result != BLUETOOTH_ERROR_NONE) {
+                                                       __bt_adapter_le_handle_pending_request_info(result,
+                                                               BT_SET_SCAN_RESPONSE_DATA, (void*)info,
+                                                               sizeof(bt_pending_adv_data_set_t));
+                                               }
+                                               goto data_free;
+                                       }
+                               } else {
+                                       BT_INFO("LE Enable Adv request is pending");
+                                       if (info->is_custom_adv) {
+                                               result = _bt_set_custom_advertising(info->sender, info->adv_handle,
+                                                                       TRUE, &info->params, FALSE/*Reserved Slot*/);
+                                               if (result != BLUETOOTH_ERROR_NONE) {
+                                                       __bt_adapter_le_handle_pending_request_info(result,
+                                                               BT_SET_CUSTOM_ADVERTISING,
+                                                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+                                               }
+                                               goto data_free;
+                                       } else {
+                                               result = _bt_set_advertising(info->sender, info->adv_handle,
+                                                               TRUE, FALSE/*Reserved Slot*/);
+                                               if (result != BLUETOOTH_ERROR_NONE) {
+                                                       __bt_adapter_le_handle_pending_request_info(result,
+                                                               BT_SET_ADVERTISING,
+                                                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+                                               }
+                                               goto data_free;
+                                       }
+                               }
+                       }
+               }
+       }
+       BT_DBG("-");
+       return;
+
+data_free:
+       adv_data_pending_list = g_slist_remove(adv_data_pending_list, info);
+       g_free(info->sender);
+       g_free(info);
+}
+
+static void __bt_le_multi_advertising_enabled(event_ble_multiadv_status *event)
+{
+       char *sender;
+       int adv_handle;
+       bt_pending_adv_data_set_t *info = NULL;
+       GVariant *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+
+       sender = _bt_get_sender_and_handle(event->server_inst, &adv_handle);
+       if (sender == NULL) {
+               BT_ERR("Abnormal!!");
+       } else {
+               if (event->status != OAL_STATUS_SUCCESS)
+                       result = BLUETOOTH_ERROR_INTERNAL;
+               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+               info->sender = sender;
+               info->adv_handle = adv_handle;
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_CUSTOM_ADVERTISING,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_ADVERTISING,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+
+               /* Send event */
+               param = g_variant_new("(ii)", result, info->adv_handle);
+               _bt_send_event_to_dest(info->sender, BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ADVERTISING_STARTED, param);
+
+               /* Free data */
+               g_free(info->sender);
+               g_free(info);
+       }
+}
+
+static void __bt_le_multi_advertising_disabled(event_ble_multiadv_status *event)
+{
+       char *sender;
+       int adv_handle;
+       bt_pending_adv_data_set_t *info = NULL;
+       GVariant *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       sender = _bt_get_sender_and_handle(event->server_inst, &adv_handle);
+
+       if (sender == NULL) {
+               BT_INFO("Means application containing the adv info is already freed!!");
+       } else {
+               if (event->status != OAL_STATUS_SUCCESS)
+                       result = BLUETOOTH_ERROR_INTERNAL;
+               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+               info->sender = sender;
+               info->adv_handle = adv_handle;
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_CUSTOM_ADVERTISING,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_ADVERTISING,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+               /* Send event */
+               param = g_variant_new("(ii)", result, info->adv_handle);
+               _bt_send_event_to_dest(info->sender, BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ADVERTISING_STOPPED, param);
+
+               /* Free allocated slot or server instance from stack to be used for other advertisng */
+               result = _bt_unregister_server_instance(sender, adv_handle);
+
+               /* Free data */
+               g_free(info->sender);
+               g_free(info);
+       }
+}
+
+static void __bt_le_multi_advertising_set_data(event_ble_multiadv_status *event)
+{
+       char *sender = NULL;
+       int adv_handle;
+       bt_pending_adv_data_set_t *info = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       sender = _bt_get_sender_and_handle(event->server_inst, &adv_handle);
+
+       if (sender == NULL) {
+               BT_ERR("Abnormal!!");
+       } else {
+               BT_DBG("Sender [%s], adv handle [%d]",  sender, adv_handle);
+               if (event->status != OAL_STATUS_SUCCESS)
+                       result = BLUETOOTH_ERROR_INTERNAL;
+
+               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+               info->sender = sender;
+               info->adv_handle = adv_handle;
+               BT_DBG("@@@@###Sender [%s], adv handle [%d]",  info->sender, info->adv_handle);
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_SCAN_RESPONSE_DATA,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+               __bt_adapter_le_handle_pending_request_info(result,
+                               BT_SET_ADVERTISING_DATA,
+                               (void*)info, sizeof(bt_pending_adv_data_set_t));
+               g_free(info->sender);
+               g_free(info);
+       }
+}
+
+static void __bt_le_event_handler(int event_type, gpointer event_data)
+{
+        BT_INFO("OAL event = 0x%x, \n", event_type);
+
+        switch (event_type) {
+       case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
+                BT_INFO("OAL Event: Server Instance Registered");
+                event_gatts_register_t* event = g_memdup(event_data, sizeof(event_gatts_register_t));
+                /* GATT Server Registered event is handled in MAIN thread context */
+                __bt_le_handle_server_instance_registered(event);
+               break;
+       }
+       case OAL_EVENT_BLE_ADVERTISING_STARTED: {
+                BT_INFO("OAL Event: Legacy Advertising Enabled: Not Supported!!");
+               break;
+       }
+       case OAL_EVENT_BLE_ADVERTISING_STOPPED: {
+                BT_INFO("OAL Event: Legacy Advertising Disabled: Not Supported!!");
+               break;
+       }
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_ENABLE: {
+                BT_INFO("OAL Event: Advertising Enabled");
+                event_ble_multiadv_status* event = (event_ble_multiadv_status*)g_memdup(event_data,
+                                                               sizeof(event_ble_multiadv_status));
+               __bt_le_multi_advertising_enabled(event);
+               break;
+       }
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_DISABLE: {
+                BT_INFO("OAL Event: Advertising Disabled");
+                event_ble_multiadv_status* event = (event_ble_multiadv_status*)g_memdup(event_data,
+                                                               sizeof(event_ble_multiadv_status));
+               __bt_le_multi_advertising_disabled(event);
+               break;
+       }
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_SET_INST_DATA: {
+                BT_INFO("OAL Event: Advertising Data set successfully");
+                event_ble_multiadv_status* event = (event_ble_multiadv_status*)g_memdup(event_data,
+                                                               sizeof(event_ble_multiadv_status));
+               __bt_le_multi_advertising_set_data(event);
+               break;
+       }
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_UPDATE: {
+                BT_INFO("OAL Event: Advertising Params updated");
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+int _bt_le_init(void)
+{
+       BT_DBG("+");
+       /* Register LE event handler */
+       _bt_service_register_event_handler_callback(BT_ADAPTER_LE_MODULE, __bt_le_event_handler);
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_le_deinit(void)
+{
+       BT_DBG("+");
+       /* Un-register LE event handler */
+       _bt_service_unregister_event_handler_callback(BT_ADAPTER_LE_MODULE);
+       BT_DBG("-");
+}
+
+static gboolean __bt_is_factory_test_mode(void)
+{
+       int mode = 0;
+
+       if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
+               BT_ERR("Get the DUT Mode fail");
+               return TRUE;
+       }
+
+       if (mode != FALSE) {
+               BT_INFO("DUT Test Mode !!");
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int server_instance;
+       bt_pending_adv_data_set_t *info = NULL;
+       int result = OAL_STATUS_SUCCESS;
+       BT_DBG("+");
+
+       if (__bt_is_factory_test_mode()) {
+               BT_ERR("Unable to start advertising in factory binary !!");
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
+       }
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, use_reserved_slot);
+
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+
+               if (enable == FALSE) {
+                       BT_ERR("Advertising not even enabled on adv handle [%d] sender [%s]", adv_handle, sender);
+                       return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+               }
+
+               server_instance = _bt_is_sender_gatt_server_with_no_adv(sender, adv_handle);
+
+               if (server_instance == -1) {
+                       /* Internal Logic to register server instance if not initialized, store adv handle for future use */
+                       if (_bt_register_server_instance(sender, adv_handle) != BLUETOOTH_ERROR_NONE)
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       else {
+                               /* Allocate a pending structure and mark Adv data set pending */
+                               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+                               info->adv_handle = adv_handle;
+                               info->sender = g_strdup(sender);
+                               info->is_data_set_pending = FALSE;
+                               adv_data_pending_list = g_slist_append(adv_data_pending_list, info);
+                               return BLUETOOTH_ERROR_NONE;
+                       }
+               }
+       }
+
+       if (enable)
+               result = adapter_ble_multi_adv_enable(server_instance);
+       else
+               result = adapter_ble_multi_adv_disable(server_instance);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("OAL API adapter_ble_multi_adv_enable Fail %d", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_set_custom_advertising(const char *sender, int adv_handle,
+                                gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int server_instance;
+       bt_pending_adv_data_set_t *info = NULL;
+       int result = OAL_STATUS_SUCCESS;
+       BT_DBG("+");
+
+       if (__bt_is_factory_test_mode()) {
+               BT_ERR("Unable to start advertising in factory binary !!");
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
+       }
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, use_reserved_slot);
+
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+
+               if (enable == FALSE) {
+                       BT_ERR("Advertising not even enabled on adv handle [%d] sender [%s]", adv_handle, sender);
+                       return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+               }
+               /* Below logic is only valid only when enabling advertising */
+               server_instance = _bt_is_sender_gatt_server_with_no_adv(sender, adv_handle);
+
+               if (server_instance == -1) {
+                       /* Internal Logic to register server instance if not initialized, store adv handle for future use */
+                       if (_bt_register_server_instance(sender, adv_handle) != BLUETOOTH_ERROR_NONE)
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       else {
+                               /* Allocate a pending structure and mark Adv data set pending */
+                               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+                               info->adv_handle = adv_handle;
+                               info->sender = g_strdup(sender);
+                               info->is_custom_adv = TRUE;
+                               info->is_data_set_pending = FALSE;
+                               memcpy(&info->params, params, sizeof(bluetooth_advertising_params_t));
+                               adv_data_pending_list = g_slist_append(adv_data_pending_list, info);
+                               return BLUETOOTH_ERROR_NONE;
+                       }
+               }
+       }
+
+       /* Set Advertising parameters to Stack */
+       result = adapter_ble_multi_adv_update(server_instance, params->interval_min, params->interval_max,
+                        params->type, BT_ADV_DEFAULT_CHANNEL_MAP, BT_ADV_DEFAULT_TX_POWER, BT_ADV_DEFAULT_TIMEOUT);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("OAL API adapter_ble_multi_adv_update Fail %d", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Start Advertising */
+       if (enable)
+               result = adapter_ble_multi_adv_enable(server_instance);
+       else
+               result = adapter_ble_multi_adv_disable(server_instance);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("OAL API adapter_ble_multi_adv_enable Fail %d", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_get_advertising_data(char *sender, int adv_handle, bluetooth_advertising_data_t *adv, int *length)
+{
+       BT_CHECK_PARAMETER(adv, return);
+       BT_CHECK_PARAMETER(length, return);
+       BT_CHECK_PARAMETER(sender, return);
+
+       int server_instance;
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
+
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       _bt_get_previous_adv_data(adv, length, server_instance);
+       BT_DBG("ADV Data length [%d] Server Instance [%d] Adv handle [%d]", length, server_instance, adv_handle);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_get_scan_response_data(char *sender, int adv_handle, bluetooth_scan_resp_data_t *response, int *length)
+{
+       BT_CHECK_PARAMETER(response, return);
+       BT_CHECK_PARAMETER(length, return);
+       BT_CHECK_PARAMETER(sender, return);
+
+       int server_instance;
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
+
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       _bt_get_previous_scan_rsp_data(response, length, server_instance);
+       BT_DBG("SCAN RSP Data length [%d] Server Instance [%d] Adv handle [%d]", length, server_instance, adv_handle);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_set_multi_adv_param(oal_ble_multi_adv_param_setup_t *adv_setup,
+                bluetooth_advertising_data_t *adv_data, int length)
+{
+        unsigned char *ptr;
+       int num_uuids;
+
+        BT_INFO("+");
+        retv_if (NULL == adv_data, BLUETOOTH_ERROR_INVALID_PARAM);
+        retv_if (NULL == adv_setup, BLUETOOTH_ERROR_INVALID_PARAM);
+
+        for(ptr = adv_data->data; NULL != ptr && length > 0;) {
+                int len = ptr[0];
+                int type = ptr[1];
+
+                BT_INFO("len: %d, type: %x", len, type);
+
+                switch (type) {
+                case 0xFF: /* Manufacturer Data */
+                        adv_setup->manufacturer_data = g_malloc0(sizeof(char) * (len - 1));
+                        memcpy(adv_setup->manufacturer_data, (ptr + 2), (len - 1));
+                        adv_setup->manufacturer_data_len = len - 1;
+                        break;
+               case 0x15: /* 128 bit Solicit UUID */
+                        adv_setup->solicit_uuid = g_malloc0(sizeof(char) * (len - 1));
+                        memcpy((adv_setup->solicit_uuid), (ptr + 2), (len - 1));
+                        adv_setup->solicit_uuid_len = len;
+                        break;
+                case 0x06: /* 128 bit Service UUID */
+                        adv_setup->service_uuid = g_malloc0(sizeof(char) * (len - 1));
+                        memcpy((adv_setup->service_uuid), (ptr + 2), (len - 1));
+                        adv_setup->service_uuid_len = len;
+                        break;
+               case 0x14: {  /* 16 bit Solicit UUID */
+                       int c;
+                       int k;
+                       num_uuids = (len -1)/ 2;
+                       adv_setup->solicit_uuid = g_malloc0(sizeof(char) * 16 * num_uuids);
+                       char *tmp = adv_setup->solicit_uuid;
+                       adv_setup->solicit_uuid_len = 0;
+
+                       for(c=1; c <= num_uuids; c++) {
+                               adv_setup->solicit_uuid_len += 16;;
+                               memcpy(tmp, BASE_UUID_CONVERTED, BT_UUID_128);
+                               memcpy(tmp+12, &ptr[c*2/* Byte Length*/], 2/* Byte Length */);
+
+                               if (c < num_uuids)
+                                       tmp += 16;
+                       }
+                       /* DEBUG: Test*/
+                       for(k=0; k < 16 * num_uuids; k++) {
+                               BT_DBG("%x", adv_setup->solicit_uuid[k]);
+                       }
+                       break;
+               }
+               case 0x02: { /* 16 bit Service UUID */
+                       int c;
+                       int k;
+                       num_uuids = (len -1)/ 2;
+                       adv_setup->service_uuid = g_malloc0(sizeof(char) * 16 * num_uuids);
+                       char *tmp = adv_setup->service_uuid;
+                       adv_setup->service_uuid_len = 0;
+
+                       for(c=1; c <= num_uuids; c++) {
+                               adv_setup->service_uuid_len += 16;;
+                               memcpy(tmp, BASE_UUID_CONVERTED, BT_UUID_128);
+                               memcpy(tmp+12, &ptr[c*2/* Byte Length */], 2/* Byte Length */);
+
+                               if (c < num_uuids)
+                                       tmp += 16;
+                       }
+                       /* DEBUG: Test*/
+                       for(k=0; k < 16 * num_uuids; k++) {
+                               BT_DBG("%x", adv_setup->service_uuid[k]);
+                       }
+                       break;
+               }
+               case 0x16: { /* Service Data */
+                        adv_setup->service_data = g_malloc0(sizeof(char) * (len - 1));
+                        memcpy(adv_setup->service_data, (ptr + 2), (len - 1));
+                        adv_setup->service_data_len = len - 1;
+                       break;
+               }
+               case 0x21: {
+                       BT_INFO("128 Bit Service Data Not Supported!!");
+                       break;
+               }
+               case 0x0A: {
+                        adv_setup->include_txpower = 1;
+                       break;
+               }
+               case 0x09:
+               case 0x08: {
+                        adv_setup->include_name = 1;
+                       break;
+               }
+               case 0x19: {
+                        memcpy(&adv_setup->appearance, (ptr + 2), (len - 1));
+                        break;
+               }
+                default:
+                        BT_ERR("Unknown type: %x", type);
+                        break;
+                }
+
+                length -= len + 1;
+                ptr += len + 1;
+        }
+
+        BT_INFO("-");
+        return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_set_advertising_data(const char *sender, int adv_handle,
+                                bluetooth_advertising_data_t *adv, int length, gboolean use_reserved_slot)
+{
+       BT_CHECK_PARAMETER(adv, return);
+       BT_CHECK_PARAMETER(sender, return);
+       bt_pending_adv_data_set_t *info = NULL;
+       int server_instance;
+       bluetooth_advertising_data_t adv_old;
+       int adv_data_len;
+       char *old_mdata = NULL;
+        int old_len = 0;
+       GVariant *ad_data, *param = NULL;
+       oal_ble_multi_adv_param_setup_t adv_setup;
+       int result = OAL_STATUS_SUCCESS;
+       BT_DBG("+");
+
+       if (length > BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
+       if (__bt_is_factory_test_mode()) {
+               BT_ERR("Unable to set advertising data in factory binary !!");
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
+       }
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, use_reserved_slot);
+
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+
+               server_instance = _bt_is_sender_gatt_server_with_no_adv(sender, adv_handle);
+
+               if (server_instance == -1) {
+                       /* Internal Logic to register server instance if not initialized, store adv handle for future use */
+                       if (_bt_register_server_instance(sender, adv_handle) != BLUETOOTH_ERROR_NONE)
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       else {
+                               /* Allocate a pending structure and mark Adv data set pending */
+                               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+                               info->adv_handle = adv_handle;
+                               info->sender = g_strdup(sender);
+                               info->data_len = length;
+                               info->is_adv = TRUE;
+                               info->is_data_set_pending = TRUE;
+                               memcpy(&info->data, &(adv->data[0]), length);
+                               adv_data_pending_list = g_slist_append(adv_data_pending_list, info);
+                               return BLUETOOTH_ERROR_NONE;
+                       }
+               }
+       }
+
+       /* Server Instance is already allocated, set Adv data to stack */
+       /* First check if adv data is already present for slot server_instance*/
+       memset(&adv_old.data, 0, sizeof(adv_old.data));
+       _bt_get_previous_adv_data(&adv_old, &adv_data_len, server_instance);
+
+       /* Send Data to stack */
+       memset(&adv_setup, 0, sizeof(oal_ble_multi_adv_param_setup_t));
+
+       if (BLUETOOTH_ERROR_NONE !=
+                       __bt_set_multi_adv_param(&adv_setup, adv, length)) {
+               if (adv_setup.manufacturer_data)
+                       g_free(adv_setup.manufacturer_data);
+               if (adv_setup.service_uuid)
+                       g_free(adv_setup.service_uuid);
+               if (adv_setup.service_data)
+                       g_free(adv_setup.service_data);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       /* Set Scan response false */
+       adv_setup.set_scan_rsp = FALSE;
+
+       /* Set Server instance */
+       adv_setup.server_if = server_instance;
+
+       /* Set Server instance[Product Requirement] */
+       adv_setup.tx_power = 4;
+
+       BT_DBG("####Service UUID len [%d], service data len [%d] Solicit UUID len [%d]",
+                               adv_setup.solicit_uuid_len, adv_setup.service_uuid_len, adv_setup.service_data_len);
+       result = adapter_ble_multi_adv_set_inst_data(server_instance, &adv_setup);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("OAL API adapter_ble_multi_adv_set_inst_data Fail %d", result);
+               /* Free the data */
+               if (adv_setup.manufacturer_data)
+                       g_free(adv_setup.manufacturer_data);
+               if (adv_setup.service_data)
+                       g_free(adv_setup.service_data);
+               if (adv_setup.service_uuid)
+                       g_free(adv_setup.service_uuid);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Data sent to Stack successfully, send manuf data changed event if applicable */
+       if (adv_setup.manufacturer_data_len != 0) {
+               if (adv_data_len > 0 ) {
+                       _bt_get_ad_data_by_type((char *)adv_old.data, adv_data_len, 0xff,
+                                       &old_mdata, &old_len);
+               }
+
+               if (old_len != adv_setup.manufacturer_data_len ||
+                               (old_mdata && adv_setup.manufacturer_data &&
+                                memcmp(old_mdata, adv_setup.manufacturer_data, adv_setup.manufacturer_data_len))) {
+
+                       ad_data = g_variant_new_from_data((const GVariantType *)"ay",
+                                       adv_setup.manufacturer_data, adv_setup.manufacturer_data_len, TRUE, NULL, NULL);
+                       param = g_variant_new("(@ay)", ad_data);
+                       _bt_send_event(BT_ADAPTER_EVENT,
+                                       BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
+                                       param);
+               }
+       }
+
+       /* Time to update new ADV data completely in Table */
+       _bt_set_new_adv_data(adv, length, server_instance);
+
+       /* Free the data */
+       if (adv_setup.manufacturer_data)
+                g_free(adv_setup.manufacturer_data);
+        if (adv_setup.service_data)
+                g_free(adv_setup.service_data);
+        if (adv_setup.service_uuid)
+                g_free(adv_setup.service_uuid);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_set_scan_response_data(const char *sender, int adv_handle,
+                               bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot)
+{
+       BT_CHECK_PARAMETER(response, return);
+       BT_CHECK_PARAMETER(sender, return);
+       bt_pending_adv_data_set_t *info = NULL;
+       bluetooth_scan_resp_data_t scan_rsp_old;
+       int scan_rsp_data_len;
+       GVariant *ad_data, *param = NULL;
+       oal_ble_multi_adv_param_setup_t adv_setup;
+       char *old_mdata = NULL;
+        int old_len = 0;
+       int server_instance;
+       int result = OAL_STATUS_SUCCESS;
+       BT_DBG("+");
+
+       if (length > BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
+       if (__bt_is_factory_test_mode()) {
+               BT_ERR("Unable to set Scan Response data in factory binary !!");
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
+       }
+
+       server_instance = _bt_get_allocated_server_instance(sender, adv_handle, use_reserved_slot);
+       if (server_instance == -1) {
+               BT_DBG("No available slot for the current sender and handle combination");
+
+               server_instance = _bt_is_sender_gatt_server_with_no_adv(sender, adv_handle);
+
+               if (server_instance == -1) {
+                       /* Internal Logic to register server instance if not initialized */
+                       if (_bt_register_server_instance(sender, adv_handle) != BLUETOOTH_ERROR_NONE)
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       else {
+                               /* Allocate a pending structure and mark Adv data set pending */
+                               info = g_malloc0(sizeof(bt_pending_adv_data_set_t));
+                               info->adv_handle = adv_handle;
+                               info->sender = g_strdup(sender);
+                               info->data_len = length;
+                               info->is_adv = FALSE;
+                               info->is_data_set_pending = TRUE;
+                               memcpy(&info->data, &(response->data[0]), length);
+                               adv_data_pending_list = g_slist_append(adv_data_pending_list, info);
+                               return BLUETOOTH_ERROR_NONE;
+                       }
+               }
+       }
+
+       /* Server Instance is already allocated, set Adv data to stack */
+       /* First check if adv data is already present for slot server_instance*/
+       memset(&scan_rsp_old.data, 0, sizeof(scan_rsp_old.data));
+       _bt_get_previous_scan_rsp_data(&scan_rsp_old, &scan_rsp_data_len, server_instance);
+
+       /* Send Data to stack */
+       memset(&adv_setup, 0, sizeof(oal_ble_multi_adv_param_setup_t));
+
+       if (BLUETOOTH_ERROR_NONE !=
+                       __bt_set_multi_adv_param(&adv_setup, (bluetooth_advertising_data_t*)response, length)) {
+               if (adv_setup.manufacturer_data)
+                       g_free(adv_setup.manufacturer_data);
+               if (adv_setup.service_uuid)
+                       g_free(adv_setup.service_uuid);
+               if (adv_setup.service_data)
+                       g_free(adv_setup.service_data);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Set Scan response to TRUE */
+       adv_setup.set_scan_rsp = TRUE;
+
+       /* Set Server instance */
+       adv_setup.server_if = server_instance;
+
+       /* Set Server instance[Product Requirement] */
+       adv_setup.tx_power = 4;
+
+       result = adapter_ble_multi_adv_set_inst_data(server_instance, &adv_setup);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("OAL API adapter_ble_multi_adv_set_inst_data Fail %d", result);
+               /* Free the data */
+               if (adv_setup.manufacturer_data)
+                       g_free(adv_setup.manufacturer_data);
+               if (adv_setup.service_data)
+                       g_free(adv_setup.service_data);
+               if (adv_setup.service_uuid)
+                       g_free(adv_setup.service_uuid);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Data sent to Stack successfully, send manuf data changed event if applicable */
+       if (adv_setup.manufacturer_data_len != 0) {
+               if (scan_rsp_data_len > 0) {
+                       _bt_get_ad_data_by_type((char *)scan_rsp_old.data, scan_rsp_data_len, 0xff,
+                                       &old_mdata, &old_len);
+               }
+
+               if (old_len != adv_setup.manufacturer_data_len ||
+                               (old_mdata && adv_setup.manufacturer_data &&
+                                memcmp(old_mdata, adv_setup.manufacturer_data, adv_setup.manufacturer_data_len))) {
+
+                       ad_data = g_variant_new_from_data((const GVariantType *)"ay",
+                                       adv_setup.manufacturer_data, adv_setup.manufacturer_data_len, TRUE, NULL, NULL);
+                       param = g_variant_new("(@ay)", ad_data);
+                       _bt_send_event(BT_ADAPTER_EVENT,
+                                       BLUETOOTH_EVENT_ADVERTISING_MANUFACTURER_DATA_CHANGED,
+                                       param);
+               }
+       }
+
+       /* Time to update new Scan Response data completely in Table */
+       _bt_set_new_scan_rsp_data(response, length, server_instance);
+
+       /* Free the data */
+       if (adv_setup.manufacturer_data)
+                g_free(adv_setup.manufacturer_data);
+        if (adv_setup.service_data)
+                g_free(adv_setup.service_data);
+        if (adv_setup.service_uuid)
+                g_free(adv_setup.service_uuid);
+
+       return BLUETOOTH_ERROR_NONE;
+}
index 920a1b7..1cc39c7 100644 (file)
@@ -42,6 +42,9 @@
 #include "bt-request-handler.h"
 #include "bt-service-event.h"
 #include "bt-service-audio-common.h"
+#include "bt-service-core-adapter-le.h"
+#include "bt-service-gatt.h"
+
 #ifdef TIZEN_DPM_ENABLE
 #include "bt-service-dpm.h"
 #endif
@@ -748,6 +751,18 @@ static int __bt_init_profiles()
                return ret;
        }
 
+       ret = _bt_le_init();
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("_bt_le_init Failed");
+               return ret;
+       }
+
+       ret = _bt_gatt_init();
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("_bt_gatt_init Failed");
+               return ret;
+       }
+
        return BLUETOOTH_ERROR_NONE;
 }
 
index c0d91d1..37a1fd2 100644 (file)
@@ -30,6 +30,7 @@
 #include "bt-service-util.h"
 
 #include "bt-service-core-adapter.h"
+#include "bt-service-core-adapter-le.h"
 #include "bt-service-core-device.h"
 #include "bt-service-audio-common.h"
 #include "bt-service-avrcp-tg.h"
@@ -175,7 +176,12 @@ static gboolean __bt_is_sync_function(int service_function)
                        || service_function == BT_HDP_CREATE_APPLICATION
                        || service_function == BT_HDP_DESTROY_APPLICATION
                        || service_function == BT_HDP_GET_FD
-                       || service_function == BT_AVRCP_GET_TRACK_INFO)
+                       || service_function == BT_AVRCP_GET_TRACK_INFO
+                       || service_function == BT_SET_ADVERTISING_DATA
+                       || service_function == BT_SET_SCAN_RESPONSE_DATA
+                       || service_function == BT_SET_ADVERTISING
+                       || service_function == BT_SET_CUSTOM_ADVERTISING
+                       || service_function == BT_GATT_SERVER_REGISTER)
                return TRUE;
        else
                return FALSE;
@@ -1548,6 +1554,170 @@ int __bt_bluez_request(int function_name,
 
                break;
        }
+       case BT_SET_ADVERTISING_DATA: {
+               char *sender = NULL;
+               int *adv_handle;
+               bluetooth_advertising_data_t adv = { {0} };
+               int length;
+               gboolean use_reserved_slot = FALSE;
+
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               adv_handle = g_malloc0(sizeof(int));
+
+                __bt_service_get_parameters(in_param1,
+                       adv_handle, sizeof(int));
+               __bt_service_get_parameters(in_param2,
+                       &adv, sizeof(bluetooth_advertising_data_t));
+               __bt_service_get_parameters(in_param3,
+                       &length, sizeof(int));
+                __bt_service_get_parameters(in_param4,
+                       &use_reserved_slot, sizeof(gboolean));
+               result = _bt_set_advertising_data(sender, *adv_handle,
+                       &adv, length, use_reserved_slot);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Set Advertising data failed!!");
+                       g_free(adv_handle);
+               } else {
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)adv_handle);
+               }
+               break;
+       }
+       case BT_SET_SCAN_RESPONSE_DATA: {
+                char *sender = NULL;
+                int *adv_handle;
+                bluetooth_scan_resp_data_t rsp = { {0} };
+                int length;
+                gboolean use_reserved_slot = FALSE;
+
+                sender = (char *)g_dbus_method_invocation_get_sender(context);
+               adv_handle = g_malloc0(sizeof(int));
+
+                __bt_service_get_parameters(in_param1,
+                                adv_handle, sizeof(int));
+                __bt_service_get_parameters(in_param2,
+                                &rsp, sizeof(bluetooth_scan_resp_data_t));
+                __bt_service_get_parameters(in_param3,
+                                &length, sizeof(int));
+                __bt_service_get_parameters(in_param4,
+                                &use_reserved_slot, sizeof(gboolean));
+
+                result = _bt_set_scan_response_data(sender, *adv_handle,
+                                &rsp, length, use_reserved_slot);
+
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Set Scan Response Data failed!!");
+                       g_free(adv_handle);
+               } else {
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)adv_handle);
+               }
+                break;
+        }
+       case BT_SET_ADVERTISING: {
+                char *sender = NULL;
+                int *adv_handle;
+                gboolean enable = FALSE;
+                gboolean use_reserved_slot = FALSE;
+
+               adv_handle = g_malloc0(sizeof(int));
+                __bt_service_get_parameters(in_param1,
+                                adv_handle, sizeof(int));
+                __bt_service_get_parameters(in_param2,
+                                &enable, sizeof(gboolean));
+                __bt_service_get_parameters(in_param3,
+                                &use_reserved_slot, sizeof(gboolean));
+
+                sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+                result = _bt_set_advertising(sender, *adv_handle,
+                                enable, use_reserved_slot);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Start Advertising failed!!");
+                       g_free(adv_handle);
+               } else {
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)adv_handle);
+               }
+                break;
+        }
+        case BT_SET_CUSTOM_ADVERTISING: {
+                char *sender = NULL;
+                int *adv_handle;
+                gboolean enable = FALSE;
+                bluetooth_advertising_params_t adv_params;
+                gboolean use_reserved_slot = FALSE;
+
+                sender = (char *)g_dbus_method_invocation_get_sender(context);
+               adv_handle = g_malloc0(sizeof(int));
+
+                __bt_service_get_parameters(in_param1, adv_handle,
+                                sizeof(int));
+                __bt_service_get_parameters(in_param2, &enable,
+                                sizeof(gboolean));
+                __bt_service_get_parameters(in_param3, &adv_params,
+                                sizeof(bluetooth_advertising_params_t));
+                __bt_service_get_parameters(in_param4, &use_reserved_slot,
+                                sizeof(gboolean));
+
+                BT_DBG("bluetooth_advertising_params_t [%f %f %d %d]",
+                                adv_params.interval_min, adv_params.interval_max,
+                                adv_params.filter_policy, adv_params.type);
+                result = _bt_set_custom_advertising(sender, *adv_handle,
+                                enable, &adv_params, use_reserved_slot);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Start Custom Advertising failed!!");
+                       g_free(adv_handle);
+               } else {
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)adv_handle);
+               }
+                break;
+        }
+       case BT_GET_SCAN_RESPONSE_DATA: {
+                bluetooth_scan_resp_data_t rsp = { {0} };
+                char *sender = NULL;
+                int length = 0;
+               int adv_handle;
+                sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &adv_handle,
+                                sizeof(int));
+
+                result = _bt_get_scan_response_data(sender, adv_handle, &rsp, &length);
+                if (result == BLUETOOTH_ERROR_NONE)
+                        g_array_append_vals(*out_param1, rsp.data, length);
+
+                break;
+        }
+       case BT_GET_ADVERTISING_DATA: {
+                bluetooth_advertising_data_t adv = { {0} };
+                char *sender = NULL;
+                int length = 0;
+               int adv_handle;
+                sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &adv_handle,
+                                sizeof(int));
+
+                result = _bt_get_advertising_data(sender, adv_handle, &adv, &length);
+                if (result == BLUETOOTH_ERROR_NONE)
+                        g_array_append_vals(*out_param1, adv.data, length);
+
+                break;
+        }
+       case BT_GATT_REGISTER_APPLICATION: {
+               BT_DBG("Register GATT application:Unhandled!!");
+               break;
+       }
+       case BT_GATT_SERVER_REGISTER: {
+               BT_DBG("GATT Server instance initialization: Unhandled!!");
+               break;
+       }
        default:
                BT_INFO("UnSupported function [%d]", function_name);
                result = BLUETOOTH_ERROR_NOT_SUPPORT;
@@ -1812,6 +1982,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_GATT_REGISTER_APPLICATION:
        case BT_GATT_REGISTER_SERVICE:
        case BT_GATT_SEND_RESPONSE:
+       case BT_GATT_SERVER_REGISTER:
        case BT_PBAP_CONNECT:
        case BT_PBAP_DISCONNECT:
        case BT_PBAP_GET_PHONEBOOK_SIZE:
index 7cb4f1d..49da809 100644 (file)
@@ -1012,6 +1012,31 @@ void _bt_uuid_to_string(service_uuid_t *p_uuid, char *str)
     return;
 }
 
+void _bt_string_to_uuid(char *str, service_uuid_t *p_uuid)
+{
+       uint32_t uuid0, uuid4;
+       uint16_t uuid1, uuid2, uuid3, uuid5;
+
+       sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+                       &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
+
+       uuid0 = htonl(uuid0);
+       uuid1 = htons(uuid1);
+       uuid2 = htons(uuid2);
+       uuid3 = htons(uuid3);
+       uuid4 = htonl(uuid4);
+       uuid5 = htons(uuid5);
+
+       memcpy(&(p_uuid->uuid[0]), &uuid0, 4);
+       memcpy(&(p_uuid->uuid[4]), &uuid1, 2);
+       memcpy(&(p_uuid->uuid[6]), &uuid2, 2);
+       memcpy(&(p_uuid->uuid[8]), &uuid3, 2);
+       memcpy(&(p_uuid->uuid[10]), &uuid4, 4);
+       memcpy(&(p_uuid->uuid[14]), &uuid5, 2);
+
+       return;
+}
+
 /* Trim string at first non-utf8 char */
 void _bt_truncate_non_utf8_chars(char * str)
 {
@@ -1067,3 +1092,52 @@ void _bt_set_device_values(gboolean connected, int state)
                BT_ERR("vconf_set_int failed");
        }
 }
+
+int _bt_get_ad_data_by_type(char *in_data, int in_len,
+                char in_type, char **data, int *data_len)
+{
+       if (in_data == NULL || data == NULL || data_len == NULL)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
+       if (in_len < 0)
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+
+       int i;
+       int len = 0;
+       int type = 0;
+
+       for (i = 0; i < in_len; i++) {
+               len = in_data[i];
+               if (len <= 0 || i + 1 >= in_len) {
+                       BT_ERR("Invalid advertising data");
+                       return BLUETOOTH_ERROR_INVALID_PARAM;
+               }
+
+               type = in_data[i + 1];
+               if (type == in_type) {
+                       i = i + 2;
+                       len--;
+                       break;
+               }
+
+               i += len;
+               len = 0;
+       }
+
+       if (i + len > in_len) {
+               BT_ERR("Invalid advertising data");
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       } else if (len == 0) {
+               BT_INFO("AD Type 0x%02x data is not set", in_type);
+               *data = NULL;
+               *data_len = 0;
+               return BLUETOOTH_ERROR_NONE;
+       }
+
+       *data = g_memdup(&in_data[i], len);
+       if (*data == NULL)
+               return BLUETOOTH_ERROR_OUT_OF_MEMORY;
+       *data_len = len;
+
+       return BLUETOOTH_ERROR_NONE;
+}
index b59191a..5ca1322 100644 (file)
@@ -49,6 +49,8 @@ _bt_service_event_handler_callback ag_cb;
 _bt_service_event_handler_callback hdp_cb;
 _bt_service_event_handler_callback avrcp_ctrl_cb;
 _bt_service_event_handler_callback avrcp_cb;
+_bt_service_event_handler_callback adapter_le_cb;
+_bt_service_event_handler_callback gatt_cb;
 
 void _bt_service_register_event_handler_callback(
                bt_service_module_t module, _bt_service_event_handler_callback cb)
@@ -98,6 +100,14 @@ void _bt_service_register_event_handler_callback(
                BT_INFO("Register BT_AVRCP_CTRL_MODULE callback");
                avrcp_ctrl_cb = cb;
                break;
+       case BT_ADAPTER_LE_MODULE:
+               BT_INFO("Register BT_ADAPTER_LE_MODULE callback");
+               adapter_le_cb = cb;
+               break;
+       case BT_GATT_MODULE:
+               BT_INFO("Register BT_GATT_MODULE callback");
+               gatt_cb = cb;
+               break;
        default:
                BT_INFO("Unknown module");
        }
@@ -138,6 +148,14 @@ void _bt_service_unregister_event_handler_callback(bt_service_module_t module)
                BT_INFO("Un-Register BT_AVRCP_CTRL_MODULE callback");
                avrcp_ctrl_cb = NULL;
                break;
+       case BT_ADAPTER_LE_MODULE:
+               BT_INFO("Un-Register BT_ADAPTER_MODULE callback");
+               adapter_le_cb = NULL;
+               break;
+       case BT_GATT_MODULE:
+               BT_INFO("Un-Register BT_GATT_MODULE callback");
+               gatt_cb = NULL;
+               break;
        default:
                BT_INFO("Unknown module");
        }
@@ -275,6 +293,18 @@ static gboolean __bt_handle_oal_events(gpointer data)
                if(avrcp_ctrl_cb)
                        avrcp_ctrl_cb(event_type, event_data);
                break;
+       case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED:
+       case OAL_EVENT_BLE_ADVERTISING_STARTED:
+       case OAL_EVENT_BLE_ADVERTISING_STOPPED:
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_ENABLE:
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_DISABLE:
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_SET_INST_DATA:
+       case OAL_EVENT_BLE_MULTI_ADVERTISING_UPDATE:
+               if (gatt_cb)
+                       gatt_cb(event_type, event_data);
+               if (adapter_le_cb)
+                       adapter_le_cb(event_type, event_data);
+               break;
        default:
                BT_ERR("Unhandled Event: %d", event_type);
                break;
diff --git a/bt-service-adaptation/services/bt-service-gatt.h b/bt-service-adaptation/services/bt-service-gatt.h
new file mode 100644 (file)
index 0000000..7f7eab4
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Anupam Roy (anupam.r@samsung.com)
+ *
+ * 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.
+ *
+ */
+
+#ifndef BT_SERVICE_GATT_H_
+#define BT_SERVICE_GATT_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_gatt_init(void);
+
+void _bt_gatt_deinit(void);
+
+int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot);
+
+int _bt_register_server_instance(const char *sender, int adv_handle);
+
+int _bt_unregister_server_instance(const char *sender, int adv_handle);
+
+char* _bt_get_sender_and_handle(int server_instance, int *adv_handle);
+
+int _bt_register_server_instance(const char *sender, int adv_handle);
+
+void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle);
+
+void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance);
+
+void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance);
+
+void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance);
+
+void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance);
+
+int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle);
+
+#if 0
+int _bt_gatt_server_register(char *sender);
+
+int _bt_gatt_server_unregister(char *sender);
+
+int _bt_gatt_server_update_multi_adv_info(char *name, int instance_id);
+
+int _bt_gatt_server_connect_remote_client(char *sender,
+                               bluetooth_device_address_t *address, int instance_id);
+
+int _bt_gatt_server_disconnect_remote_client(char *sender,
+                               bluetooth_device_address_t *address,
+                               int instance_id);
+
+int _bt_gatt_server_add_service(char *sender, int service_type,
+                               int num_handles, char *svc_uuid, int instance_id);
+
+int _bt_gatt_server_add_included_service(char *sender, int instance_id,
+                                int service_handle, int included_svc_handle);
+
+int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
+                               bluetooth_gatt_server_attribute_params_t *param);
+
+int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
+                               bt_gatt_permission_t *perm, int service_handle, int instance_id);
+
+int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *addr, bluetooth_gatt_att_data_t *data,
+                                       bluetooth_gatt_server_indication_params_t *param);
+
+int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
+                                       bluetooth_gatt_server_response_params_t *param);
+
+void _bt_gatt_server_clear_req_info(void);
+
+void _bt_gatt_server_clear_connection_info(void);
+
+bt_product_gatt_permission_t _bt_gatt_convert_attr_permission_to_stack_specific(
+                                        bt_gatt_permission_t perm);
+
+void _bt_check_gatt_server_app_termination(const char *name);
+
+int _bt_gatt_server_get_att_mtu(bluetooth_device_address_t *address, unsigned int *mtu);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* BT_SERVICE_GATT_H_ */
diff --git a/bt-service-adaptation/services/gatt/bt-service-gatt.c b/bt-service-adaptation/services/gatt/bt-service-gatt.c
new file mode 100644 (file)
index 0000000..51a1870
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Anupam Roy (anupam.r@samsung.com)
+ *
+ * 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 <glib.h>
+#include <dlog.h>
+#include "bt-service-common.h"
+#include "bt-service-core-adapter.h"
+#include "bt-service-event-receiver.h"
+#include "bt-request-handler.h"
+#include "bluetooth-api.h"
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+#include "bt-service-util.h"
+#include "bt-service-common.h"
+#include "bt-service-event.h"
+
+#include "bt-internal-types.h"
+#include "bt-service-gatt.h"
+
+#include <oal-hardware.h>
+#include <oal-manager.h>
+#include <oal-event.h>
+#include <oal-adapter-mgr.h>
+#include <oal-device-mgr.h>
+#include <oal-gatt.h>
+
+#define BT_GATT_TRANSPORT_LE 0
+#define BT_GATT_TRANSPORT_BR_EDR 1
+#define BT_GATT_TRANSPORT_LE_BR_EDR 2
+#define BT_UUID_STRING_MAX 64
+#define BT_SENDER_MAX_LENGTH 50
+#define MAX_APPS_SUPPORTED 11 /* Slot 0 is not used */
+#define NUM_UUID 10
+#define UUID_MAX_LEN 50
+
+
+#define BDADDR_ANY   (&(bluetooth_device_address_t) {{0, 0, 0, 0, 0, 0}})
+
+char uuid_list[NUM_UUID][BT_UUID_STRING_MAX] = {"0000b00b-0000-0000-f065-080080fa49b5", /* Used by BLEAPP */
+                                               "0000b00b-1111-1111-0123-456789ab0cd2", /* Used by BLEAPP */
+                                               "0000b00b-2222-1111-0123-456789ab0cd2",
+                                               "0000b00b-3333-1111-0123-456789ab0cd2",
+                                               "0000b00b-4444-1111-0123-456789ab0cd2",
+                                               "0000b00b-5555-1111-0123-456789ab0cd2",
+                                               "0000b00b-6666-1111-0123-456789ab0cd2",
+                                               "0000b00b-7777-1111-0123-456789ab0cd2",
+                                               "0000b00b-8888-1111-0123-456789ab0cd2",
+                                               "0000b00b-9999-1111-0123-456789ab0cd2"};
+
+
+/* App Information structure */
+typedef struct {
+       int adv_handle;
+       char sender[BT_SENDER_MAX_LENGTH];
+       char uuid[BT_UUID_STRING_MAX];
+       int instance_id;
+       int adv_instance;
+       bluetooth_advertising_data_t adv_data; /* Will store adv data for specific slot */
+       int adv_data_len;
+       bluetooth_scan_resp_data_t scan_rsp;   /* Will store scan rsp data for specific slot */
+       int scan_rsp_len;
+       gboolean is_initialized;
+       GSList *service_handles;
+} bt_service_app_info_t;
+
+/* List of applications */
+static bt_service_app_info_t numapps[MAX_APPS_SUPPORTED];
+
+static void __bt_gatt_handle_pending_request_info(int result,
+                int service_function, void *data, unsigned int size);
+
+static void __bt_handle_server_instance_registered(event_gatts_register_t *data);
+
+static void __bt_gatt_event_handler(int event_type, gpointer event_data);
+
+void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle)
+{
+       BT_DBG("+");
+       int k;
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               if (numapps[k].is_initialized == 1 && numapps[k].instance_id == server_inst) {
+                       *adv_handle = numapps[k].adv_handle;
+                       break;
+               }
+       }
+}
+
+int _bt_gatt_init(void)
+{
+       BT_DBG("+");
+
+       if (OAL_STATUS_SUCCESS != gatt_enable()) {
+               BT_ERR("gatt Init failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Register gatt event handler */
+       _bt_service_register_event_handler_callback(BT_GATT_MODULE, __bt_gatt_event_handler);
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+void _bt_gatt_deinit(void)
+{
+       BT_DBG("+");
+
+       if (OAL_STATUS_SUCCESS != gatt_disable())
+               BT_ERR("gatt deinit failed");
+
+       /* Un-register gatt event handler */
+       _bt_service_unregister_event_handler_callback(BT_GATT_MODULE);
+       BT_DBG("-");
+}
+
+int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
+{
+       int k;
+       BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
+       bt_service_app_info_t *info = NULL;
+
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+               /* Search for a app which has same sender and adv handle as 0
+                  It is possible that same sender but different adv handle */
+               if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0) {
+                       info->adv_handle = adv_handle;
+                       return info->instance_id;
+               }
+       }
+       return -1;
+}
+
+int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot)
+{
+       int k;
+       BT_DBG("Sender [%s] Adv handle [%d]", sender, adv_handle);
+       bt_service_app_info_t *info = NULL;
+
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               /* Exact matching of Adv handle + sender combination */
+               if (!g_strcmp0(info->sender, sender) && info->adv_handle == adv_handle)
+                       return info->instance_id;
+#if 0
+               if (!g_strcmp0(info->sender, sender) && info->adv_handle == -1)
+                       return info->instance_id;
+#endif
+       }
+       return -1;
+}
+
+char * _bt_get_sender_and_handle(int server_instance, int *adv_handle)
+{
+       int k;
+       bt_service_app_info_t *info = NULL;
+
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == server_instance && info->adv_handle != -1) {
+                       *adv_handle = info->adv_handle;
+                       BT_DBG("Server instance [%d] Adv handle [%d] Sender [%s]", server_instance, *adv_handle, info->sender);
+                       return g_strdup(info->sender);
+               }
+       }
+       return NULL;
+}
+
+void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance)
+{
+       int k;
+       BT_DBG("+");
+       bt_service_app_info_t *info = NULL;
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == instance) {
+                       memcpy(info->adv_data.data, &adv->data, len);
+                       break;
+               }
+       }
+       BT_DBG("-");
+}
+
+void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance)
+{
+       int k;
+       BT_DBG("+");
+       bt_service_app_info_t *info = NULL;
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == instance) {
+                       memcpy(info->scan_rsp.data, &scan->data, len);
+                       break;
+               }
+       }
+       BT_DBG("-");
+}
+
+void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance)
+{
+       int k;
+       BT_DBG("+");
+       bt_service_app_info_t *info = NULL;
+
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == instance) {
+                       memcpy(&adv->data, info->adv_data.data, info->adv_data_len);
+                       *len = info->adv_data_len;
+                       break;
+               }
+       }
+}
+
+void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance)
+{
+       int k;
+       BT_DBG("+");
+       bt_service_app_info_t *info = NULL;
+
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == instance) {
+                       memcpy(&scan->data, info->scan_rsp.data, info->scan_rsp_len);
+                       *len = info->scan_rsp_len;
+                       break;
+               }
+       }
+}
+
+static int __bt_do_unregister_server_instance(int server_instance)
+{
+       int ret = OAL_STATUS_SUCCESS;
+       int k;
+
+       /* Unregister the server instance */
+       ret = gatts_unregister(server_instance);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("DeAllocate server instance with stack Fail ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       BT_INFO("DeAllocated server instance with stack successful..");
+
+       /* Reset data */
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               if (numapps[k].instance_id == server_instance) {
+                       numapps[k].is_initialized = 0;
+                       numapps[k].instance_id = -1;
+                       numapps[k].adv_instance = -1;
+                       memset(numapps[k].sender, 0x00, sizeof(numapps[k].sender));
+                       memset(numapps[k].uuid, 0x00, sizeof(numapps[k].uuid));
+                       memset(numapps[k].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
+                       memset(numapps[k].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
+                       break;
+               }
+       }
+       BT_DBG("Going8 to reset numapp block num [%d]", k);
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_unregister_server_instance(const char *sender, int adv_handle)
+{
+       BT_INFO("Unregister Allocated server instance request Sender [%s] Adv handle [%d]", sender, adv_handle);
+       int result = BLUETOOTH_ERROR_NONE;
+       int server_instance;
+       int k;
+
+       if (adv_handle == 0) {
+               BT_DBG("Its a direct GATT Server app request to unregister");
+               /* Unregister server instance for each app with same sender (case: GATT Server with multiple adv handle) */
+               bt_service_app_info_t *info = NULL;
+
+               for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+                       info = &numapps[k];
+
+                       /* Exact matching of sender */
+                       if (!g_strcmp0(info->sender, sender)) {
+                               BT_INFO("Unregister GATT server instance [%d]", info->instance_id);
+                               /*TODO Unregister all service handles with stack */
+                               /*TODO Disable adv if running */
+                               /* Unregister server instance */
+                               result = __bt_do_unregister_server_instance(info->instance_id);
+                       }
+               }
+       } else {
+               BT_DBG("Its an Internal unregister request by adv application");
+               server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
+               if (server_instance == -1) {
+                       BT_ERR("No allocated server instance to be removed");
+                       return BLUETOOTH_ERROR_INVALID_PARAM;
+               }
+               BT_INFO("Unregister Adv app server instance [%d]", server_instance);
+               /* Unregister server instance */
+               result = __bt_do_unregister_server_instance(server_instance);
+       }
+       return result;
+}
+
+int _bt_register_server_instance(const char *sender, int adv_handle)
+{
+       int ret = OAL_STATUS_SUCCESS;
+       char *uuid_string = NULL;
+       int slot = -1;
+       int k;
+       oal_uuid_t uuid;
+
+       BT_INFO("###Check on which instance Server instance can be initialized....");
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               if (numapps[k].is_initialized == 1) {
+                       BT_INFO("Instance ID [%d] is already in use..Check next slot", numapps[k].instance_id);
+               } else {
+                       slot = k;
+                       BT_INFO("Time to register GATT Server..UUID to be used is [%s] slot [%d]", uuid_list[slot-1], slot);
+                       break;
+               }
+       }
+
+       if (slot == -1) {
+               BT_ERR("No Slot if free for GATT Server registration..");
+               return BLUETOOTH_ERROR_REGISTRATION_FAILED;
+       }
+
+       uuid_string = g_malloc0(BT_UUID_STRING_MAX);
+       _bt_string_to_uuid(uuid_list[slot-1], (service_uuid_t*)&uuid);
+       g_strlcpy(uuid_string, uuid_list[slot-1], BT_UUID_STRING_MAX);
+       BT_INFO("Copied UUID string [%s]", uuid_string);
+
+       /* Register GATT Server */
+       ret = gatts_register(&uuid);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               g_free(uuid_string);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       BT_INFO("GATT Server registration call successfully accepted by OAL..wait for Instance Initialized event from OAL..");
+       /* Return & wait for GATT Server Instance Initialization event */
+       memset(numapps[slot].sender, 0x00, sizeof(numapps[slot].sender));
+       memset(numapps[slot].uuid, 0x00, sizeof(numapps[slot].uuid));
+
+       g_strlcpy(numapps[slot].sender, sender, sizeof(numapps[slot].sender));
+       g_strlcpy(numapps[slot].uuid, uuid_string, sizeof(numapps[slot].uuid));
+
+       numapps[slot].is_initialized = 0; /* Set initialization from app registered callback */
+       numapps[slot].adv_handle = adv_handle;
+
+       g_free(uuid_string);
+       return BLUETOOTH_ERROR_NONE;
+}
+
+
+/* Event handlers */
+static void __bt_gatt_handle_pending_request_info(int result,
+                int service_function, void *data, unsigned int size)
+{
+        GSList *l;
+        GArray *out_param;
+        invocation_info_t *req_info = NULL;
+        ret_if (data == NULL);
+        BT_DBG("+");
+
+        for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
+                req_info = l->data;
+                if (req_info == NULL || req_info->service_function != service_function)
+                        continue;
+
+                switch (service_function) {
+               case BT_GATT_SERVER_REGISTER: {
+                       bt_service_app_info_t *data = (bt_service_app_info_t*)data;
+                       if (!g_strcmp0(req_info->sender, data->sender)) {
+                               BT_DBG("GATT Server app found [%s]", req_info->sender);
+                               out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+                               g_array_append_vals(out_param, &data->instance_id, sizeof(int));
+                               _bt_service_method_return(req_info->context, out_param, result);
+                               g_free(req_info->user_data);
+                               _bt_free_info_from_invocation_list(req_info);
+                               g_array_free(out_param, TRUE);
+                       }
+                       break;
+               }
+               default:
+                       break;
+               }
+       }
+        BT_DBG("-");
+}
+
+static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
+{
+       bt_service_app_info_t *info = NULL;
+       int k;
+       char *uuid_string = g_malloc0(BT_UUID_STRING_MAX);
+
+       _bt_uuid_to_string(&(data->server_uuid), uuid_string);
+       BT_INFO("Instance ID is Intialized [%d] UUID initialized [%s]", data->server_inst, uuid_string);
+
+       /* Check if the just registered Instance ID belongs to BLEAPP or GATT Server */
+       for (k=1; k <MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (g_strcmp0(info->uuid, uuid_string) == 0) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       info->is_initialized = TRUE;
+                       info->instance_id = data->server_inst;
+                       info->adv_instance = data->server_inst;
+                       __bt_gatt_handle_pending_request_info(BLUETOOTH_ERROR_NONE, BT_GATT_SERVER_REGISTER,
+                                       (void*)info, sizeof(bt_service_app_info_t));
+                       break;
+               }
+       }
+       g_free(uuid_string);
+}
+
+static void __bt_gatt_event_handler(int event_type, gpointer event_data)
+{
+        BT_INFO("OAL event = 0x%x, \n", event_type);
+        switch (event_type) {
+        case OAL_EVENT_BLE_SERVER_INSTANCE_INITIALISED: {
+               BT_INFO("OAL Event: Server Instance Registered");
+                event_gatts_register_t* event = g_memdup(event_data, sizeof(event_gatts_register_t));
+                /* GATT Server Registered event is handled in MAIN thread context */
+                __bt_handle_server_instance_registered(event);
+                break;
+        }
+        default:
+                break;
+        }
+       BT_DBG("-");
+}
index 9fe27e3..20d8f2a 100755 (executable)
@@ -408,6 +408,11 @@ invocation_info_t* _bt_get_request_info_data(int service_function, char *address
 
 void _bt_set_device_values(gboolean connected, int state);
 
+void _bt_string_to_uuid(char *str, service_uuid_t *p_uuid);
+
+int _bt_get_ad_data_by_type(char *in_data, int in_len,
+                char in_type, char **data, int *data_len);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/bt-service-adaptation/services/include/bt-service-core-adapter-le.h b/bt-service-adaptation/services/include/bt-service-core-adapter-le.h
new file mode 100644 (file)
index 0000000..37a01a8
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:  Anupam Roy <anupam.r@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_CORE_ADAPTER_LE_H_
+#define _BT_SERVICE_CORE_ADAPTER_LE_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_le_init(void);
+
+void _bt_le_deinit(void);
+
+int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gboolean use_reserved_slot);
+
+int _bt_set_custom_advertising(const char *sender, int adv_handle, gboolean enable, bluetooth_advertising_params_t *params, gboolean use_reserved_slot);
+
+int _bt_set_advertising_data(const char *sender, int adv_handle, bluetooth_advertising_data_t *data, int length, gboolean use_reserved_slot);
+
+int _bt_set_scan_response_data(const char *sender, int adv_handle, bluetooth_scan_resp_data_t *response, int length, gboolean use_reserved_slot);
+
+int _bt_get_advertising_data(char *sender, int adv_handle, bluetooth_advertising_data_t *adv, int *length);
+
+int _bt_get_scan_response_data(char *sender, int adv_handle, bluetooth_scan_resp_data_t *adv, int *length);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_CORE_ADAPTER_LE_H_*/
index 8906220..ffbdfe4 100644 (file)
@@ -43,6 +43,8 @@ typedef enum {
        BT_AUDIO_ALL_MODULE,
        BT_AVRCP_MODULE,
        BT_AVRCP_CTRL_MODULE,
+       BT_ADAPTER_LE_MODULE,
+       BT_GATT_MODULE,
 } bt_service_module_t;
 
 void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize len);
diff --git a/bt-service-adaptation/services/include/bt-service-gatt.h b/bt-service-adaptation/services/include/bt-service-gatt.h
new file mode 100644 (file)
index 0000000..7f7eab4
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd.
+ *
+ * Contact: Anupam Roy (anupam.r@samsung.com)
+ *
+ * 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.
+ *
+ */
+
+#ifndef BT_SERVICE_GATT_H_
+#define BT_SERVICE_GATT_H_
+
+#include <glib.h>
+#include <sys/types.h>
+#include "bluetooth-api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _bt_gatt_init(void);
+
+void _bt_gatt_deinit(void);
+
+int _bt_get_allocated_server_instance(const char *sender, int adv_handle, gboolean use_reserved_slot);
+
+int _bt_register_server_instance(const char *sender, int adv_handle);
+
+int _bt_unregister_server_instance(const char *sender, int adv_handle);
+
+char* _bt_get_sender_and_handle(int server_instance, int *adv_handle);
+
+int _bt_register_server_instance(const char *sender, int adv_handle);
+
+void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle);
+
+void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int instance);
+
+void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance);
+
+void _bt_get_previous_adv_data(bluetooth_advertising_data_t *adv, int *len, int instance);
+
+void _bt_get_previous_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int *len, int instance);
+
+int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle);
+
+#if 0
+int _bt_gatt_server_register(char *sender);
+
+int _bt_gatt_server_unregister(char *sender);
+
+int _bt_gatt_server_update_multi_adv_info(char *name, int instance_id);
+
+int _bt_gatt_server_connect_remote_client(char *sender,
+                               bluetooth_device_address_t *address, int instance_id);
+
+int _bt_gatt_server_disconnect_remote_client(char *sender,
+                               bluetooth_device_address_t *address,
+                               int instance_id);
+
+int _bt_gatt_server_add_service(char *sender, int service_type,
+                               int num_handles, char *svc_uuid, int instance_id);
+
+int _bt_gatt_server_add_included_service(char *sender, int instance_id,
+                                int service_handle, int included_svc_handle);
+
+int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
+                               bluetooth_gatt_server_attribute_params_t *param);
+
+int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
+                               bt_gatt_permission_t *perm, int service_handle, int instance_id);
+
+int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id);
+
+int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *addr, bluetooth_gatt_att_data_t *data,
+                                       bluetooth_gatt_server_indication_params_t *param);
+
+int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
+                                       bluetooth_gatt_server_response_params_t *param);
+
+void _bt_gatt_server_clear_req_info(void);
+
+void _bt_gatt_server_clear_connection_info(void);
+
+bt_product_gatt_permission_t _bt_gatt_convert_attr_permission_to_stack_specific(
+                                        bt_gatt_permission_t perm);
+
+void _bt_check_gatt_server_app_termination(const char *name);
+
+int _bt_gatt_server_get_att_mtu(bluetooth_device_address_t *address, unsigned int *mtu);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* BT_SERVICE_GATT_H_ */
index 2527ec4..64bda12 100644 (file)
@@ -317,6 +317,7 @@ typedef enum {
        BT_GATT_REGISTER_APPLICATION,
        BT_GATT_REGISTER_SERVICE,
        BT_GATT_SEND_RESPONSE,
+       BT_GATT_SERVER_REGISTER,
        BT_LE_IPSP_INIT = BT_FUNC_IPSP_BASE,
        BT_LE_IPSP_DEINIT,
        BT_LE_IPSP_CONNECT,