[BTMW: Service] Add Support for GATT Server 16/124916/1
authorAnupam Roy <anupam.r@samsung.com>
Wed, 12 Apr 2017 09:26:00 +0000 (14:56 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Thu, 13 Apr 2017 04:41:43 +0000 (10:11 +0530)
This patch temporarily disables HTTP proxy
and BT Frwk Test

Change-Id: Ic69d0ecd43a118a51cb707979bac84e0e6bf75d0
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
14 files changed:
CMakeLists.txt
bt-api/CMakeLists.txt
bt-service-adaptation/services/adapter/bt-service-core-adapter-le.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-event-sender.c
bt-service-adaptation/services/gatt/bt-service-gatt.c
bt-service-adaptation/services/include/bt-service-common.h
bt-service-adaptation/services/include/bt-service-gatt.h
include/bluetooth-api.h
include/bluetooth-gatt-server-api.h [new file with mode: 0644]
include/bt-internal-types.h
packaging/bluetooth-frwk.spec

index 41d5c77..6cc28dd 100644 (file)
@@ -13,8 +13,8 @@ ADD_SUBDIRECTORY(bt-service)
 ENDIF("$ENV{BT_INCLUDE_OAL}" STREQUAL "ENABLED")
 ENDIF()
 
-ADD_SUBDIRECTORY(bt-httpproxy)
+#ADD_SUBDIRECTORY(bt-httpproxy)
 
 ADD_SUBDIRECTORY(bt-core)
 
-ADD_SUBDIRECTORY(test)
+#ADD_SUBDIRECTORY(test)
index abb47be..7f2c393 100644 (file)
@@ -35,7 +35,8 @@ bluetooth-audio-api.h
 bluetooth-telephony-api.h
 bluetooth-media-control.h
 bluetooth-scmst-api.h
-bluetooth-ipsp-api.h)
+bluetooth-ipsp-api.h
+bluetooth-gatt-server-api.h)
 
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(EXEC_PREFIX "\${prefix}")
index fc324c0..38c53df 100644 (file)
@@ -350,7 +350,7 @@ static void __bt_le_multi_advertising_set_data(event_ble_multiadv_status *event)
                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_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));
@@ -599,6 +599,10 @@ int _bt_set_advertising(const char *sender, int adv_handle, gboolean enable, gbo
                BT_ERR("OAL API adapter_ble_multi_adv_enable Fail %d", result);
                return BLUETOOTH_ERROR_INTERNAL;
        }
+
+       /* Update adv handle in table */
+        _bt_update_adv_handle(sender, adv_handle);
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -646,21 +650,29 @@ int _bt_set_custom_advertising(const char *sender, int adv_handle,
                }
        }
 
-       /* 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)
+       if (enable) {
+               /* 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 when Adv update event is received */
                result = adapter_ble_multi_adv_enable(server_instance);
-       else
+                if (result != OAL_STATUS_SUCCESS) {
+                        BT_ERR("OAL API adapter_ble_multi_adv_enable Fail %d", result);
+                       return BLUETOOTH_ERROR_INTERNAL;
+                }
+               /* Update adv handle in table */
+               _bt_update_adv_handle(sender, adv_handle);
+
+               return BLUETOOTH_ERROR_NONE;
+       } 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);
+               BT_ERR("OAL API adapter_ble_multi_adv_disable Fail %d", result);
                return BLUETOOTH_ERROR_INTERNAL;
        }
        return BLUETOOTH_ERROR_NONE;
@@ -943,6 +955,9 @@ int _bt_set_advertising_data(const char *sender, int adv_handle,
         if (adv_setup.service_uuid)
                 g_free(adv_setup.service_uuid);
 
+       /* Update adv handle in table */
+       _bt_update_adv_handle(sender, adv_handle);
+
        return BLUETOOTH_ERROR_NONE;
 }
 
@@ -1067,6 +1082,8 @@ int _bt_set_scan_response_data(const char *sender, int adv_handle,
         if (adv_setup.service_uuid)
                 g_free(adv_setup.service_uuid);
 
+       /* Update adv handle in table */
+        _bt_update_adv_handle(sender, adv_handle);
        return BLUETOOTH_ERROR_NONE;
 }
 
index c61976e..2173ba4 100644 (file)
@@ -25,6 +25,7 @@
 #include <cynara-creds-gdbus.h>
 
 #include "bluetooth-api.h"
+#include "bluetooth-gatt-server-api.h"
 #include "bt-request-handler.h"
 #include "bt-service-common.h"
 #include "bt-service-util.h"
@@ -183,6 +184,12 @@ static gboolean __bt_is_sync_function(int service_function)
                        || service_function == BT_SET_ADVERTISING
                        || service_function == BT_SET_CUSTOM_ADVERTISING
                        || service_function == BT_GATT_SERVER_REGISTER
+                       || service_function == BT_GATT_SERVER_ADD_SERVICE
+                       || service_function == BT_GATT_SERVER_ADD_CHARACTERISTIC
+                       || service_function == BT_GATT_SERVER_ADD_DESCRIPTOR
+                       || service_function == BT_GATT_SERVER_START_SERVICE
+                       || service_function == BT_GATT_SERVER_STOP_SERVICE
+                       || service_function == BT_GATT_SERVER_DELETE_SERVICE
                        || service_function == BT_START_LE_DISCOVERY
                        || service_function == BT_STOP_LE_DISCOVERY)
                return TRUE;
@@ -1713,9 +1720,274 @@ int __bt_bluez_request(int function_name,
                break;
        }
        case BT_GATT_SERVER_REGISTER: {
-               BT_DBG("GATT Server instance initialization: Unhandled!!");
+               BT_DBG("GATT Server instance initialization");
+                char *app;
+
+                app = (char *)g_dbus_method_invocation_get_sender(context);
+                BT_INFO("GATT Server Unique Name [%s]", app);
+
+               /* No ADV handle: Set 0 */
+                result = _bt_register_server_instance(app, 0);
+                BT_INFO("GATT Server: Register Server result [%d]", result);
+
+               if (result != BLUETOOTH_ERROR_NONE) {
+                        BT_ERR("GATT Server registration failed!!");
+                } else {
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, NULL);
+                }
+                break;
+       }
+       case BT_GATT_SERVER_DEREGISTER: {
+                char *app;
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+               result = _bt_unregister_server_instance(app, 0/* Adv Handle*/);
+               break;
+       }
+       case BT_GATT_SERVER_ADD_SERVICE: {
+               BT_DBG("GATT Server Add Service");
+               int service_type;
+                int num_handles;
+                char *svc_uuid;
+                int instance_id;
+                char *app;
+                int *tmp_inst_id = NULL;
+
+                app = (char *)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &service_type,
+                                sizeof(int));
+               __bt_service_get_parameters(in_param2, &num_handles,
+                                sizeof(int));
+               svc_uuid = (char *)g_variant_get_data(in_param3);
+               __bt_service_get_parameters(in_param4, &instance_id,
+                                sizeof(int));
+
+                BT_INFO("GATT Server Service UUID [%s]", svc_uuid);
+               result = _bt_gatt_server_add_service(app, service_type, num_handles, svc_uuid, instance_id);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                        BT_ERR("GATT Server Add Service failed!!");
+                } else {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                                       *tmp_inst_id, instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
+                break;
+       }
+       case BT_GATT_SERVER_ADD_CHARACTERISTIC: {
+               BT_DBG("GATT Server Add Characteristic");
+               char *char_uuid;
+                char *app;
+                int *tmp_inst_id = NULL;
+                bluetooth_gatt_server_attribute_params_t param;
+               memset(&param, 0, sizeof(bluetooth_gatt_server_attribute_params_t));
+
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &param,
+                                sizeof(bluetooth_gatt_server_attribute_params_t));
+               char_uuid = (char *)g_variant_get_data(in_param2);
+
+                BT_INFO("GATT Server Characteristic UUID [%s]", char_uuid);
+
+                result = _bt_gatt_server_add_characteristic(app, char_uuid, &param);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                        BT_ERR("GATT Server Add Service failed!!");
+                } else {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = param.instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                               *tmp_inst_id, param.instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
+                break;
+       }
+       case BT_GATT_SERVER_ADD_DESCRIPTOR: {
+               BT_DBG("GATT Server Add Descriptor");
+                char *desc_uuid;
+                int instance_id;
+                int service_handle;
+                bt_gatt_permission_t perm;
+                char *app;
+                int *tmp_inst_id = NULL;
+               memset(&perm, 0, sizeof(bt_gatt_permission_t));
+
+                app = (char *)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &service_handle,
+                                sizeof(int));
+                __bt_service_get_parameters(in_param2, &instance_id,
+                                sizeof(int));
+               desc_uuid = (char *)g_variant_get_data(in_param4);
+                __bt_service_get_parameters(in_param3, &perm,
+                                sizeof(bt_gatt_permission_t));
+
+                BT_INFO("GATT Server Descriptor UUID [%s]", desc_uuid);
+
+                result = _bt_gatt_server_add_descriptor(app, desc_uuid, &perm, service_handle, instance_id);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                        BT_ERR("GATT Server Add Service failed!!");
+                } else {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                               *tmp_inst_id, instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
                break;
        }
+       case BT_GATT_SERVER_START_SERVICE: {
+                int service_handle;
+                int instance_id;
+
+                char *app;
+                int *tmp_inst_id = NULL;
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &service_handle,
+                                sizeof(int));
+                __bt_service_get_parameters(in_param2, &instance_id,
+                                sizeof(int));
+
+                result = _bt_gatt_server_start_service(app, service_handle, instance_id);
+
+                if (BLUETOOTH_ERROR_NONE == result) {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                               *tmp_inst_id, instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
+                break;
+        }
+       case BT_GATT_SERVER_STOP_SERVICE: {
+                int service_handle;
+                int instance_id;
+                char *app;
+                int *tmp_inst_id = NULL;
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &service_handle,
+                                sizeof(int));
+                __bt_service_get_parameters(in_param2, &instance_id,
+                                sizeof(int));
+
+                result = _bt_gatt_server_stop_service(app, service_handle, instance_id);
+
+                if (BLUETOOTH_ERROR_NONE == result) {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                               *tmp_inst_id, instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
+                break;
+        }
+       case BT_GATT_SERVER_DELETE_SERVICE: {
+                int service_handle;
+                int instance_id;
+                int *tmp_inst_id = NULL;
+                char *app;
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+                __bt_service_get_parameters(in_param1, &service_handle,
+                                sizeof(int));
+                __bt_service_get_parameters(in_param2, &instance_id,
+                                sizeof(int));
+
+                result = _bt_gatt_server_delete_service(app, service_handle, instance_id);
+
+                if (BLUETOOTH_ERROR_NONE == result) {
+                       tmp_inst_id = g_malloc0(sizeof(int));
+                        *tmp_inst_id = instance_id;
+                        BT_INFO("GATT Server: Save Instance ID in request Inst id [%d] request_id [%d]",
+                               *tmp_inst_id, instance_id);
+                        _bt_save_invocation_context(context, result, app,
+                                        function_name, (gpointer)tmp_inst_id);
+                }
+                break;
+        }
+       case BT_GATT_SERVER_SEND_RESPONSE: {
+                bluetooth_gatt_server_response_params_t param;
+                bluetooth_gatt_att_data_t data;
+                char *app;
+
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_response_params_t));
+               memset(&data, 0x00, sizeof(bluetooth_gatt_att_data_t));
+
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+               __bt_service_get_parameters(in_param1, &data,
+                                sizeof(bluetooth_gatt_att_data_t));
+               __bt_service_get_parameters(in_param2, &param,
+                                sizeof(bluetooth_gatt_server_response_params_t));
+
+                result = _bt_gatt_server_send_response(app, &data, &param);
+
+                break;
+        }
+       case BT_GATT_SERVER_SEND_INDICATION: {
+                bluetooth_gatt_server_indication_params_t param;
+                bluetooth_gatt_att_data_t data;
+                bluetooth_device_address_t address;
+
+                char *app;
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_indication_params_t));
+               memset(&data, 0x00, sizeof(bluetooth_gatt_att_data_t));
+               memset(&address, 0x00, sizeof(bluetooth_device_address_t));
+
+               __bt_service_get_parameters(in_param1, &data,
+                                sizeof(bluetooth_gatt_att_data_t));
+               __bt_service_get_parameters(in_param2, &param,
+                                sizeof(bluetooth_gatt_server_indication_params_t));
+               __bt_service_get_parameters(in_param3, &param,
+                                sizeof(bluetooth_device_address_t));
+
+                result = _bt_gatt_server_send_indication(app, &address, &data, &param);
+
+                break;
+        }
+       case BT_GATT_SERVER_UPDATE_VALUE: {
+                bluetooth_gatt_server_update_value_t param;
+               int instance_id;
+                char *app;
+
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_response_params_t));
+
+                app = (char*)g_dbus_method_invocation_get_sender(context);
+
+               __bt_service_get_parameters(in_param1, &instance_id,
+                                sizeof(int));
+               __bt_service_get_parameters(in_param2, &param,
+                                sizeof(bluetooth_gatt_server_update_value_t));
+
+                result = _bt_gatt_server_update_attribute_value(app, instance_id, &param);
+       }
+       case BT_GET_ATT_MTU: {
+               bluetooth_device_address_t address = { {0} };
+               unsigned int mtu = 0;
+
+                __bt_service_get_parameters(in_param1,
+                       &address, sizeof(bluetooth_device_address_t));
+               result = _bt_get_att_mtu(&address, &mtu);
+               BT_DBG("MTU: %d", mtu);
+
+                if (result == BLUETOOTH_ERROR_NONE) {
+                        g_array_append_vals(*out_param1, &mtu,
+                                                sizeof(unsigned int));
+               }
+                break;
+       }
        case BT_START_LE_DISCOVERY: {
                sender = (char *)g_dbus_method_invocation_get_sender(context);
                result = _bt_start_le_scan(sender);
@@ -2017,7 +2289,20 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_GATT_REGISTER_APPLICATION:
        case BT_GATT_REGISTER_SERVICE:
        case BT_GATT_SEND_RESPONSE:
+#ifndef GATT_DIRECT
        case BT_GATT_SERVER_REGISTER:
+       case BT_GATT_SERVER_ADD_SERVICE:
+       case BT_GATT_SERVER_ADD_CHARACTERISTIC:
+       case BT_GATT_SERVER_ADD_DESCRIPTOR:
+       case BT_GATT_SERVER_START_SERVICE:
+       case BT_GATT_SERVER_STOP_SERVICE:
+       case BT_GATT_SERVER_DELETE_SERVICE:
+       case BT_GATT_SERVER_SEND_RESPONSE:
+       case BT_GATT_SERVER_SEND_INDICATION:
+       case BT_GATT_SERVER_UPDATE_VALUE:
+       case BT_GATT_SERVER_DEREGISTER:
+#endif
+       case BT_GET_ATT_MTU:
        case BT_PBAP_CONNECT:
        case BT_PBAP_DISCONNECT:
        case BT_PBAP_GET_PHONEBOOK_SIZE:
index 49da809..7d8b3f5 100644 (file)
@@ -43,8 +43,8 @@
 
 static GDBusConnection *system_conn;
 static GDBusConnection *session_conn;
-static GDBusProxy *manager_proxy;
-static GDBusProxy *adapter_proxy;
+static GDBusProxy *manager_proxy_g;
+static GDBusProxy *adapter_proxy_g;
 static void *net_conn;
 
 static GDBusProxy *adapter_properties_proxy;
@@ -107,7 +107,7 @@ static GDBusProxy *__bt_init_manager_proxy(void)
 
        retv_if(proxy == NULL, NULL);
 
-       manager_proxy = proxy;
+       manager_proxy_g = proxy;
 
        return proxy;
 }
@@ -137,7 +137,7 @@ static GDBusProxy *__bt_init_adapter_proxy(void)
 
        retv_if(proxy == NULL, NULL);
 
-       adapter_proxy = proxy;
+       adapter_proxy_g = proxy;
 
        return proxy;
 }
@@ -215,13 +215,13 @@ GDBusConnection *_bt_get_system_conn(void)
 
 GDBusProxy *_bt_get_manager_proxy(void)
 {
-       if (manager_proxy) {
-               const gchar *path =  g_dbus_proxy_get_object_path(manager_proxy);
+       if (manager_proxy_g) {
+               const gchar *path =  g_dbus_proxy_get_object_path(manager_proxy_g);
                if (path == NULL) {
                        BT_ERR("Already proxy released hence creating new proxy");
                        return  __bt_init_manager_proxy();
                }
-               return manager_proxy;
+               return manager_proxy_g;
        }
        return  __bt_init_manager_proxy();
 }
@@ -252,14 +252,14 @@ void *_bt_get_net_conn(void)
 
 GDBusProxy *_bt_get_adapter_proxy(void)
 {
-       if (adapter_proxy) {
-               const char *path =  g_dbus_proxy_get_object_path(adapter_proxy);
+       if (adapter_proxy_g) {
+               const char *path =  g_dbus_proxy_get_object_path(adapter_proxy_g);
                if (path == NULL) {
                        BT_ERR("Already proxy released hence creating new proxy");
                        return  __bt_init_adapter_proxy();
                }
 
-               return adapter_proxy;
+               return adapter_proxy_g;
        }
        return  __bt_init_adapter_proxy();
 
@@ -335,14 +335,14 @@ char *_bt_get_adapter_path(void)
 
 void _bt_deinit_bluez_proxy(void)
 {
-       if (manager_proxy) {
-               g_object_unref(manager_proxy);
-               manager_proxy = NULL;
+       if (manager_proxy_g) {
+               g_object_unref(manager_proxy_g);
+               manager_proxy_g = NULL;
        }
 
-       if (adapter_proxy) {
-               g_object_unref(adapter_proxy);
-               adapter_proxy = NULL;
+       if (adapter_proxy_g) {
+               g_object_unref(adapter_proxy_g);
+               adapter_proxy_g = NULL;
        }
        if (adapter_properties_proxy) {
                g_object_unref(adapter_properties_proxy);
@@ -462,7 +462,7 @@ void _bt_divide_device_class(bluetooth_device_class_t *device_class,
 
 void _bt_free_device_info(bt_remote_dev_info_t *dev_info)
 {
-       int i;
+       unsigned int i;
 
        ret_if(dev_info == NULL);
 
@@ -490,7 +490,7 @@ void _bt_free_le_device_info(bt_remote_le_dev_info_t *le_dev_info)
 
 int _bt_copy_utf8_string(char *dest, const char *src, unsigned int length)
 {
-       int i;
+       unsigned int i;
        const char *p = src;
        char *next;
        int count;
@@ -655,7 +655,7 @@ char *_bt_get_profile_uuid128(bt_profile_type_t profile_type)
        };
 }
 
-char *_bt_convert_error_to_string(int error)
+const char *_bt_convert_error_to_string(int error)
 {
        switch (error) {
        case BLUETOOTH_ERROR_CANCEL:
@@ -736,7 +736,7 @@ char *_bt_convert_error_to_string(int error)
        }
 }
 
-char * _bt_convert_disc_reason_to_string(int reason)
+const char * _bt_convert_disc_reason_to_string(int reason)
 {
        switch (reason) {
        case 1:
@@ -838,7 +838,7 @@ int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
 
 void _bt_copy_remote_dev(bt_remote_dev_info_t *dev_info, remote_device_t *oal_device)
 {
-       int i;
+       unsigned int i;
        BT_INFO("+");
 
        dev_info->address = g_new0(char, BT_ADDRESS_STRING_SIZE);
@@ -870,7 +870,7 @@ void _bt_copy_remote_dev(bt_remote_dev_info_t *dev_info, remote_device_t *oal_de
                dev_info->uuids = g_new0(char *, dev_info->uuid_count);
 
        /* Fill Remote Device Service List list */
-       for (i=0; i < dev_info->uuid_count; i++) {
+       for (i = 0; i < dev_info->uuid_count; i++) {
                dev_info->uuids[i] = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
                _bt_uuid_to_string((service_uuid_t *)&oal_device->uuid[i].uuid, dev_info->uuids[i]);
                BT_DBG("[%s]", dev_info->uuids[i]);
@@ -888,7 +888,7 @@ void _bt_copy_remote_dev(bt_remote_dev_info_t *dev_info, remote_device_t *oal_de
 
 void _bt_free_remote_dev(bt_remote_dev_info_t * dev_info)
 {
-       int c;
+       unsigned int c;
        BT_INFO("+");
 
        if (dev_info->address)
@@ -899,7 +899,7 @@ void _bt_free_remote_dev(bt_remote_dev_info_t * dev_info)
                g_free(dev_info->manufacturer_data);
 
        if (dev_info->uuid_count) {
-               for(c=0; c < dev_info->uuid_count; c++)
+               for(c = 0; c < dev_info->uuid_count; c++)
                        g_free(dev_info->uuids[c]);
        }
        BT_INFO("-");
@@ -907,7 +907,7 @@ void _bt_free_remote_dev(bt_remote_dev_info_t * dev_info)
 
 static void __bt_get_service_list(bt_remote_dev_info_t *info, bluetooth_device_info_t *dev)
 {
-       int i;
+       unsigned int i;
        char **uuids;
        char **parts;
 
@@ -1037,6 +1037,18 @@ void _bt_string_to_uuid(char *str, service_uuid_t *p_uuid)
        return;
 }
 
+void _bt_convert_byte_ordering(char *data, int data_len,
+                                          char *converted_data)
+{
+        int i, j;
+        char temp[BT_UUID_LEN];
+
+        memcpy(&temp, data, data_len);
+        for (i = 0, j = data_len - 1; i < data_len; i++, j--)
+                converted_data[i] = temp[j];
+
+}
+
 /* Trim string at first non-utf8 char */
 void _bt_truncate_non_utf8_chars(char * str)
 {
index 3192ae9..22e959b 100644 (file)
@@ -61,17 +61,17 @@ void _bt_service_register_event_handler_callback(
                adapter_cb = cb;
                break;
        case BT_DEVICE_MODULE:
-                BT_INFO("Register BT_DEVICE_MODULE Callback");
-                device_cb = cb;
-                break;
+               BT_INFO("Register BT_DEVICE_MODULE Callback");
+               device_cb = cb;
+               break;
        case BT_HID_MODULE:
-                BT_INFO("Register BT_HID_MODULE Callback");
-                hid_cb = cb;
-                break;
+               BT_INFO("Register BT_HID_MODULE Callback");
+               hid_cb = cb;
+               break;
        case BT_SOCKET_MODULE:
-                BT_INFO("Register BT_SOCKET_MODULE Callback");
-                socket_cb = cb;
-                break;
+               BT_INFO("Register BT_SOCKET_MODULE Callback");
+               socket_cb = cb;
+               break;
        case BT_AUDIO_ALL_MODULE:
                BT_INFO("Register BT_AUDIO_ALL_MODULE Callback");
                audio_event_cb = cb;
@@ -80,8 +80,8 @@ void _bt_service_register_event_handler_callback(
                BT_INFO("Register BT_A2DP_SOURCE_MODULE Callback");
                a2dp_source_cb = cb;
                break;
-        case BT_A2DP_SINK_MODULE:
-               BT_INFO("Register BT_A2DP_SINK_MODULE Callback");
+       case BT_A2DP_SINK_MODULE:
+               BT_INFO("Register BT_A2DP_SINK_MODULE Callback");
                a2dp_sink_cb = cb;
                break;
        case BT_AG_MODULE:
@@ -121,17 +121,17 @@ void _bt_service_unregister_event_handler_callback(bt_service_module_t module)
                adapter_cb = NULL;
                break;
        case BT_DEVICE_MODULE:
-                BT_INFO("Un-Register BT_DEVICE_MODULE Callback");
-                device_cb = NULL;
-                break;
+               BT_INFO("Un-Register BT_DEVICE_MODULE Callback");
+               device_cb = NULL;
+               break;
        case BT_HID_MODULE:
-                BT_INFO("Un-Register BT_HID_MODULE Callback");
-                hid_cb = NULL;
-                break;
+               BT_INFO("Un-Register BT_HID_MODULE Callback");
+               hid_cb = NULL;
+               break;
        case BT_SOCKET_MODULE:
-                BT_INFO("Un-Register BT_SOCKET_MODULE Callback");
-                socket_cb = NULL;
-                break;
+               BT_INFO("Un-Register BT_SOCKET_MODULE Callback");
+               socket_cb = NULL;
+               break;
        case BT_A2DP_SINK_MODULE:
                BT_INFO("Un-Register BT_A2DP_SINK_MODULE Callback");
                a2dp_sink_cb = NULL;
@@ -300,6 +300,21 @@ static gboolean __bt_handle_oal_events(gpointer data)
        case OAL_EVENT_BLE_MULTI_ADVERTISING_DISABLE:
        case OAL_EVENT_BLE_MULTI_ADVERTISING_SET_INST_DATA:
        case OAL_EVENT_BLE_MULTI_ADVERTISING_UPDATE:
+       /* GATT Server Events */
+       case OAL_EVENT_GATTS_SERVICE_ADDED:                     /* gatts Service Added Done */\
+       case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED:              /* gatts Characteristic Added Done */\
+       case OAL_EVENT_GATTS_DESCRIPTOR_ADDED:                  /* gatts Descriptor added done */\
+       case OAL_EVENT_GATTS_SERVICE_STARTED:                   /* gatts Service Started  */\
+       case OAL_EVENT_GATTS_SERVICE_STOPED:                    /* gatts Service Stoped */\
+       case OAL_EVENT_GATTS_SERVICE_DELETED:           /* gatts Service Deleted  */\
+       case OAL_EVENT_GATTS_CONNECTION_COMPLETED:              /* gatts Connection completed */\
+       case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED:           /* gatts Disconnection completed */\
+       case OAL_EVENT_GATTS_REQUEST_READ:                      /* gatts Request Read from client */\
+       case OAL_EVENT_GATTS_REQUEST_WRITE:                     /* gatts Request Write from client */\
+       case OAL_EVENT_GATTS_IND_CONFIRM:                       /* gatts Indicate confirmation from remote client */\
+       /* Tizen Platform Specific */
+       case OAL_EVENT_GATTS_NOTIFICATION:                      /* gatts Notification changed event */\
+       case OAL_EVENT_GATTS_MTU_CHANGED:                       /* gatts MTU changed event */\
                if (adapter_gatt_cb)
                        adapter_gatt_cb(event_type, event_data);
                if (adapter_le_cb)
index 34b073a..252603e 100644 (file)
@@ -59,8 +59,8 @@ int _bt_send_to_hps(void)
 int _bt_send_event(int event_type, int event, GVariant *param)
 {
        BT_DBG("+");
-       char *path;
-       char *signal;
+       const char *path;
+       const char *signal;
        GDBusMessage *msg1 = NULL;
 
        retv_if(event_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
@@ -110,6 +110,11 @@ int _bt_send_event(int event_type, int event, GVariant *param)
         case BT_A2DP_SOURCE_EVENT:
                 path = BT_A2DP_SOURCE_PATH;
                 break;
+#ifndef GATT_DIRECT
+        case BT_GATT_SERVER_EVENT:
+                path = BT_GATT_SERVER_PATH;
+                break;
+#endif
        default:
                BT_ERR("Unknown event");
                return BLUETOOTH_ERROR_INTERNAL;
@@ -386,6 +391,14 @@ int _bt_send_event(int event_type, int event, GVariant *param)
        case BLUETOOTH_EVENT_GATT_DISCONNECTED:
                signal = BT_GATT_DISCONNECTED;
                break;
+#ifndef GATT_DIRECT
+       case BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED:
+               signal = BT_GATT_VALUE_CHANGED;
+               break;
+       case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED:
+                signal = BT_GATT_SERVER_READ_REQ;
+                break;
+#endif
        case BLUETOOTH_EVENT_IPSP_INIT_STATE_CHANGED:
                signal = BT_IPSP_INITIALIZED;
                break;
@@ -431,8 +444,8 @@ int _bt_send_event_to_dest(const char* dest, int event_type,
                int event, GVariant *param)
 {
        BT_DBG("+");
-       char *path;
-       char *signal;
+       const char *path;
+       const char *signal;
        GError *error = NULL;
 
        retv_if(event_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
index e596c95..96ddf3f 100644 (file)
@@ -34,6 +34,9 @@
 
 #include "bt-internal-types.h"
 #include "bt-service-gatt.h"
+#include "bt-service-gatt.h"
+#include "bt-service-core-device.h"
+#include "bt-service-core-adapter-le.h"
 
 #include <oal-hardware.h>
 #include <oal-manager.h>
@@ -81,6 +84,51 @@ typedef struct {
        GSList *service_handles;
 } bt_service_app_info_t;
 
+/* GATT Server Request Info Structure */
+struct gatt_server_req_info {
+        int connection_id;                               /* This value will uniquely identify a GATT client-server connection */
+        int request_id;                                  /* This is an unique transaction ID assigned against each request by stack */
+        int attribute_handle;                            /* GATT server attribute handle */
+        int offset;                                      /* GATT server attribute offset on which request is invoked by GATT client */
+        bluetooth_gatt_att_request_type_e request_type;  /* Read or Write request */
+        char *addr;                                      /* Remote GATT client address */
+};
+
+/* GATT Client Info List Structure */
+struct gatt_client_info_t {
+        int connection_id;                               /* This value will uniquely identify a GATT client-server connection */
+        int instance_id;                                 /* This value unique identifies a GATT server instance */
+        char *addr;                                      /* Remote GATT client address */
+};
+
+/* GATT Indicate confirm result  */
+struct gatt_indicate_cfm_result_info_t {
+        int result;                                      /* Result of event */
+        char *addr;                                      /* Remote GATT client address */
+        int att_hdl;                                     /* Characteristic Attribute handle */
+        int completed;                                   /* 1 if last event, otheriwse 0 */
+};
+
+/* Request Search Utility method */
+static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
+                                        bluetooth_gatt_att_request_type_e req_type);
+
+static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
+                                bluetooth_gatt_server_indication_params_t *param);
+
+static void __bt_remove_all_service_handles(int instance_id);
+
+static int __bt_do_unregister_server_instance(int server_instance);
+
+/* Linked List of GATT requests from Remote GATT Clients */
+static GSList *gatt_server_requests = NULL;
+
+/* Linked List of connected Remote GATT clients */
+static GSList *gatt_client_info_list = NULL;
+
+/* Number of clients to be notified to */
+static int num_indicate_clients;
+
 /* List of applications */
 static bt_service_app_info_t numapps[MAX_APPS_SUPPORTED];
 
@@ -95,37 +143,97 @@ void _bt_check_adv_app_termination(const char *name)
 {
        bt_service_app_info_t *app = NULL;
        int k;
-       int result = OAL_STATUS_SUCCESS;
+       int apps[MAX_APPS_SUPPORTED];
 
        BT_DBG("Adv app name [%s]", name);
 
        ret_if(NULL == name);
 
+       memset(&apps, -1, sizeof(apps));
+
        for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
                app = &numapps[k];
 
-               /* Search for a app which has same sender */
+               /* Search for a app which has same sender and stop adv is running */
                if (!strncasecmp(app->sender, name, strlen(name)) && app->is_initialized == TRUE) {
                        BT_DBG("Match found, name: %s", name);
 
+                       /* Unregister all service handles with stack */
+                       __bt_remove_all_service_handles(app->instance_id);
+
                        /* If Advertising is enabled, stop it */
                        if (app->adv_handle > 0) {
                                BT_INFO("Stop advertising on instance ID [%d]", app->instance_id);
-                               result = adapter_ble_multi_adv_disable(app->instance_id);
-                               if (result != OAL_STATUS_SUCCESS) {
-                                       BT_ERR("OAL API adapter_ble_multi_adv_enable Fail %d", result);
-                               }
+                               /* Disable adv if running */
+                               BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
+                                               app->adv_handle, name);
+                               _bt_set_advertising(app->sender, app->adv_handle, FALSE, FALSE);
                        }
-                       /* TODO: Cleanup all Services, chars and Descriptors of the associated GATT server */
 
-                       /* Unregister the server instance */
-                       _bt_unregister_server_instance(name, app->adv_handle);
+                       /* Save instances of all apps that need to be unregistered */
+                       apps[app->instance_id] = 1;
                }
        }
 
+       /* Unregister all apps one by one */
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               if (apps[k] == 1) {
+                       BT_INFO("Unregister app[%d]", k);
+                       /* Unregister server instance */
+                       __bt_do_unregister_server_instance(k);
+               }
+       }
        BT_DBG("-");
 }
 
+static int __bt_gatt_send_indication_to_all_connected_clients(bluetooth_gatt_att_data_t *data,
+                                bluetooth_gatt_server_indication_params_t *param)
+{
+       GSList *l;
+       int ret = OAL_STATUS_SUCCESS;
+       int result = OAL_STATUS_INTERNAL_ERROR;
+
+       BT_INFO("Current total number of connected clients [%d]", g_slist_length(gatt_client_info_list));
+       for (l = gatt_client_info_list; l != NULL; l = l->next) {
+               struct gatt_client_info_t *info = l->data;
+
+               if (info) {
+                       BT_INFO("GATT Remote client address [%s] connection Id [%d]", info->addr, info->connection_id);
+
+                       ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
+                                       info->connection_id, data->length,
+                                       param->need_confirmation, (char *)(&data->data[0]));
+
+                       BT_INFO("Send Indication to GATT client [%s] result: [%d]", info->addr, ret);
+                       if (ret == OAL_STATUS_SUCCESS) {
+                               BT_INFO("Send Indication sent successfully to GATT client [%s]", info->addr);
+                               result = ret;
+                               num_indicate_clients++;
+                       }
+               }
+       }
+       BT_INFO("Indication sending done for total number of clients [%d]", num_indicate_clients);
+       return result;
+}
+
+static struct gatt_server_req_info *__bt_gatt_server_find_request_info(int request_id,
+                                        bluetooth_gatt_att_request_type_e req_type)
+{
+       GSList *l;
+
+       for (l = gatt_server_requests; l != NULL; l = l->next) {
+               struct gatt_server_req_info *req_info = l->data;
+
+               if (req_info && req_info->request_id == request_id && req_info->request_type == req_type) {
+                       BT_INFO("GATT Server request info found Req ID [%d] handle [%d] conn ID [%d]",
+                                       req_info->request_id, req_info->attribute_handle, req_info->connection_id);
+                       return req_info;
+               }
+       }
+       BT_ERR("Gatt Request not found");
+       return NULL;
+}
+
 void _bt_get_adv_handle_from_instance(int server_inst, int *adv_handle)
 {
        BT_DBG("+");
@@ -165,6 +273,21 @@ void _bt_gatt_deinit(void)
        BT_DBG("-");
 }
 
+void _bt_update_adv_handle(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 */
+               if (!g_strcmp0(info->sender, sender) && info->adv_handle == 0) {
+                       info->adv_handle = adv_handle;
+               }
+       }
+}
+
 int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
 {
        int k;
@@ -176,7 +299,7 @@ int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle)
                /* 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;
+                       //info->adv_handle = adv_handle;
                        return info->instance_id;
                }
        }
@@ -304,11 +427,14 @@ static int __bt_do_unregister_server_instance(int server_instance)
                if (numapps[k].instance_id == server_instance) {
                        numapps[k].is_initialized = 0;
                        numapps[k].instance_id = -1;
+                       numapps[k].adv_handle = 0;
                        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);
+                       numapps[k].adv_data_len = 0;
+                       numapps[k].scan_rsp_len = 0;
                        break;
                }
        }
@@ -316,13 +442,50 @@ static int __bt_do_unregister_server_instance(int server_instance)
        return BLUETOOTH_ERROR_NONE;
 }
 
+static void __bt_remove_all_service_handles(int instance_id)
+{
+        GSList *l;
+        int *handle = NULL;
+        int ret = OAL_STATUS_SUCCESS;
+        int count;
+
+        count = g_slist_length(numapps[instance_id].service_handles);
+        BT_INFO("Before handle removal: current count [%d]", count);
+
+        for (l = numapps[instance_id].service_handles; l != NULL;) {
+                handle = l->data;
+                l = g_slist_next(l);
+
+                if (handle) {
+                        BT_INFO("Server Handle to be Removed [%d] Instance ID [%d]", *handle, instance_id);
+                        if (_bt_gatt_server_stop_service(numapps[instance_id].sender, *handle, instance_id) != BLUETOOTH_ERROR_NONE)
+                                continue;
+
+                        ret = gatts_delete_service(instance_id, *handle);
+                        if (ret != OAL_STATUS_SUCCESS) {
+                                BT_ERR("ret: %d", ret);
+                                continue;
+                        } else {
+                                numapps[instance_id].service_handles = g_slist_remove(numapps[instance_id].service_handles, handle);
+                                g_free(handle);
+                                handle = NULL;
+                                count = g_slist_length(numapps[instance_id].service_handles);
+                                BT_INFO("After deleting current count [%d]", count);
+                        }
+                }
+        }
+}
+
 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 apps[MAX_APPS_SUPPORTED];
        int server_instance;
        int k;
 
+       memset(&apps, -1, sizeof(apps));
+
        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) */
@@ -334,23 +497,49 @@ int _bt_unregister_server_instance(const char *sender, int adv_handle)
                        /* 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);
+                               /* Unregister all service handles with stack */
+                               __bt_remove_all_service_handles(info->instance_id);
+
+                               /* Disable adv if running */
+                               BT_INFO("Disable Advertising Adv Handle [%d] sender [%s]",
+                                               info->adv_handle, sender);
+                               _bt_set_advertising(sender, info->adv_handle, FALSE, FALSE);
+
+                               /* Save all instances which need to be unregistered */
+                               apps[info->instance_id] = 1;
                        }
                }
        } else {
                BT_DBG("Its an Internal unregister request by adv application");
                server_instance = _bt_get_allocated_server_instance(sender, adv_handle, FALSE);
+               BT_DBG("Its an Internal unregister request by adv application: Adv disabled srv instance [%d]", server_instance);
                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);
+               if (!numapps[server_instance].service_handles) {
+                       BT_INFO("There are no Service handles with this app, safe to unregister");
+                       /* Unregister server instance only if this sender does not have any gatt services in it */
+                       result = __bt_do_unregister_server_instance(server_instance);
+               } else {
+                        numapps[server_instance].adv_handle = 0;
+                        memset(numapps[server_instance].adv_data.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
+                        numapps[server_instance].adv_data_len = 0;
+                        memset(numapps[server_instance].scan_rsp.data, 0x00, BLUETOOTH_ADVERTISING_DATA_LENGTH_MAX);
+                        numapps[server_instance].scan_rsp_len = 0;
+               }
+               return result;
        }
+
+       /* Unregister all apps one by one */
+        for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+                if (apps[k] == 1) {
+                        BT_INFO("Unregister app[%d]", k);
+                        /* Unregister server instance */
+                        __bt_do_unregister_server_instance(k);
+                }
+        }
+
        return result;
 }
 
@@ -405,7 +594,6 @@ int _bt_register_server_instance(const char *sender, int adv_handle)
        return BLUETOOTH_ERROR_NONE;
 }
 
-
 /* Event handlers */
 static void __bt_gatt_handle_pending_request_info(int result,
                 int service_function, void *data, unsigned int size)
@@ -422,19 +610,72 @@ static void __bt_gatt_handle_pending_request_info(int result,
                         continue;
 
                 switch (service_function) {
+#ifndef GATT_DIRECT
                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_service_app_info_t *param = (bt_service_app_info_t*)data;
+                       BT_INFO("Sender [%s] Request Sender [%s]", param->sender, req_info->sender);
+                       if (!g_strcmp0(req_info->sender, param->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, &param->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;
+               }
+               case BT_GATT_SERVER_START_SERVICE:
+               case BT_GATT_SERVER_DELETE_SERVICE: {
+                       bt_service_app_info_t *param = (bt_service_app_info_t*)data;
+                       BT_INFO("Sender [%s] Request Sender [%s]", param->sender, req_info->sender);
+
+                       int *saved_instance_id = (int*)req_info->user_data;
+                       if (!g_strcmp0(req_info->sender, param->sender) && param->instance_id == *saved_instance_id) {
+                               BT_DBG("GATT Server app found [%s] Instance ID [%d] Reply DBUS",
+                                               req_info->sender, *saved_instance_id);
+
                                out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
-                               g_array_append_vals(out_param, &data->instance_id, sizeof(int));
+                               g_array_append_vals(out_param, &saved_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;
                }
+               case BT_GATT_SERVER_ADD_SERVICE:
+               case BT_GATT_SERVER_ADD_DESCRIPTOR:
+               case BT_GATT_SERVER_ADD_CHARACTERISTIC: {
+                       int *handle = (int*)data;
+                       BT_INFO("Characteristic added: Handle [%d]", *handle);
+                       out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+
+                       g_array_append_vals(out_param, handle, 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;
+               }
+#endif
+               case BT_CONNECT_LE:
+               case BT_DISCONNECT_LE: {
+                       out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+
+                       g_array_append_vals(out_param, (bluetooth_device_address_t*)data,
+                                       sizeof(bluetooth_device_address_t));
+                       _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);
+               }
                default:
                        break;
                }
@@ -466,6 +707,627 @@ static void __bt_handle_server_instance_registered(event_gatts_register_t *data)
                }
        }
        g_free(uuid_string);
+       g_free(data);
+}
+
+static void __bt_handle_gatt_server_service_added(event_gatts_srvc_prm_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       int svc_handle;
+       int *handle;
+       int count;
+       bt_service_app_info_t *info = NULL;
+       int k;
+
+       char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
+       _bt_uuid_to_string(&(event->gatt_srvc_id.id.uuid), uuid_str);
+        BT_INFO("GATT Added Service  UUID: [%s] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
+                        uuid_str, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
+
+       if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
+               result = BLUETOOTH_ERROR_INTERNAL;
+               svc_handle = 0;  /* Service handle set to 0 indicates.
+                                   0 is reserved by BT SIG, cant be used by app*/
+       } else
+               svc_handle = event->gatt_srvc_stat.servic_hndl;
+
+       BT_INFO("GATT Added Service  Status [%d] Server Ins [%d] Service hdl [%d] Is Primary [%d]\n",
+                       event->gatt_srvc_stat.status, event->gatt_srvc_stat.server_inst, svc_handle, event->gatt_srvc_id.is_prmry);
+
+       /* 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 (info->instance_id == event->gatt_srvc_stat.server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_SERVICE,
+                                       (int*)&svc_handle, sizeof(int));
+
+                       /* Add Service Handle */
+                       if (svc_handle > 0) {
+                               handle = g_malloc0(sizeof(int));
+                               *handle = svc_handle;
+                               numapps[event->gatt_srvc_stat.server_inst].service_handles = g_slist_append(numapps[event->gatt_srvc_stat.server_inst].service_handles, handle);
+                               count = g_slist_length(numapps[event->gatt_srvc_stat.server_inst].service_handles);
+                               BT_INFO("Added Service handle [%d] to list..current count [%d]", svc_handle, count);
+                       }
+                       break;
+               }
+       }
+
+       g_free(event);
+       g_free(uuid_str);
+}
+
+static void __bt_handle_gatt_server_characteristic_added(event_gatts_srvc_charctr_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       int char_handle;
+       bt_service_app_info_t *info = NULL;
+       int k;
+       char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
+
+       BT_INFO("GATT Server Char added status [%d]", event->gatt_srvc_stat.status);
+       BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
+       BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
+       BT_INFO("GATT Add characteristic  Status: [%d]", event->gatt_srvc_stat.status);
+       BT_INFO("GATT Service characteristic Handle: [%d]", event->charctr_hndl);
+
+       if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
+               result = BLUETOOTH_ERROR_INTERNAL;
+               char_handle = 0;  /* characteristic handle set to 0 indicates.
+                                    0 is reserved by BT SIG, cant be used by app*/
+       } else
+               char_handle = event->charctr_hndl;
+
+
+       /* 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 (info->instance_id == event->gatt_srvc_stat.server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_CHARACTERISTIC,
+                                       (int*)&char_handle, sizeof(int));
+                       break;
+               }
+       }
+
+
+       _bt_uuid_to_string(&(event->charctr_uuid), uuid_str);
+       BT_INFO("GATT Added Characteristic:  UUID: [%s]", uuid_str);
+
+       g_free(event);
+       g_free(uuid_str);
+}
+
+static void __bt_handle_gatt_server_descriptor_added(event_gatts_srvc_descr_t* event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       int desc_handle;
+       bt_service_app_info_t *info = NULL;
+       int k;
+       char *uuid_str = g_malloc0(BT_UUID_STRING_MAX);
+
+       BT_INFO("GATT Server Descriptor added status [%d]", event->gatt_srvc_stat.status);
+       BT_INFO("GATT Server_inst: [%d]", event->gatt_srvc_stat.server_inst);
+       BT_INFO("GATT Service Handle: [%d]", event->gatt_srvc_stat.servic_hndl);
+       BT_INFO("GATT Add Descriptor  Status: [%d]", event->gatt_srvc_stat.status);
+       BT_INFO("GATT Service Descriptor Handle: [%d]", event->descrptr_hndl);
+
+       if (event->gatt_srvc_stat.status != OAL_STATUS_SUCCESS) {
+               result = BLUETOOTH_ERROR_INTERNAL;
+               desc_handle = 0;  /* Service handle set to 0 indicates.
+                                    0 is reserved by BT SIG, cant be used by app*/
+       } else
+               desc_handle = event->descrptr_hndl;
+
+       /* 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 (info->instance_id == event->gatt_srvc_stat.server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_ADD_DESCRIPTOR,
+                                       (int*)&desc_handle, sizeof(int));
+                       break;
+               }
+       }
+
+       _bt_uuid_to_string(&(event->descrptr_uuid), uuid_str);
+       BT_INFO("GATT Added Descriptor:  UUID: [%s]", uuid_str);
+
+       g_free(event);
+       g_free(uuid_str);
+}
+
+static void __bt_handle_gatt_server_service_started(event_gatts_srvc_t *event)
+{
+       bt_service_app_info_t *info = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       int k;
+       BT_INFO("GATT Server Service Started..");
+
+
+       BT_INFO("GATT Server_inst: [%d]", event->server_inst);
+       BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
+       BT_INFO("GATT Service Started Status: [%d]", event->status);
+
+       if (event->status != OAL_STATUS_SUCCESS) {
+               BT_ERR("GATT Server Service Start Failed Err: [%d]", event->status);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Check if the just registered Instance ID belongs to requester */
+       for (k=1; k <MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == event->server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_START_SERVICE,
+                                       (void*)info, sizeof(bt_service_app_info_t));
+                       break;
+               }
+       }
+
+       g_free(event);
+}
+
+static void __bt_handle_gatt_server_service_stopped(event_gatts_srvc_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_service_app_info_t *info = NULL;
+       int k;
+       BT_INFO("GATT Server Service Stopped..");
+
+       BT_INFO("GATT Server_inst: [%d]", event->server_inst);
+       BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
+       BT_INFO("GATT Service Stopped Status: [%d]", event->status);
+
+       if (event->status != OAL_STATUS_SUCCESS) {
+               BT_ERR("GATT Server Service Stop Failed Err: [%d]", event->status);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Check if the just registered Instance ID belongs to requester */
+       for (k=1; k <MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == event->server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_STOP_SERVICE,
+                                       (void*)info, sizeof(bt_service_app_info_t));
+                       break;
+               }
+       }
+
+       g_free(event);
+}
+
+static void __bt_handle_gatt_server_service_deleted(event_gatts_srvc_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_service_app_info_t *info = NULL;
+       int k;
+       BT_INFO("GATT Server Service Deleted..");
+
+       BT_INFO("GATT Server_inst: [%d]", event->server_inst);
+       BT_INFO("GATT Service Handle: [%d]", event->servic_hndl);
+       BT_INFO("GATT Service Deleted Status: [%d]", event->status);
+
+       if (event->status != OAL_STATUS_SUCCESS) {
+               BT_ERR("GATT Server Service Delete Failed Err: [%d]", event->status);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Check if the just registered Instance ID belongs to requester */
+       for (k = 1; k < MAX_APPS_SUPPORTED; k++) {
+               info = &numapps[k];
+
+               if (info->instance_id == event->server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_GATT_SERVER_DELETE_SERVICE,
+                                       (void*)info, sizeof(bt_service_app_info_t));
+                       break;
+               }
+       }
+
+       g_free(event);
+}
+
+static struct gatt_client_info_t *__bt_find_remote_gatt_client_info(char *address)
+{
+       GSList *l;
+       struct gatt_client_info_t *info = NULL;
+       for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (struct gatt_client_info_t*)l->data;
+               if (info == NULL)
+                       continue;
+
+               if (!g_strcmp0(info->addr, address)) {
+                       BT_INFO("Remote GATT client found addr[%s]", info->addr);
+                       return info;
+               }
+       }
+       return NULL;
+}
+
+static struct gatt_client_info_t *__bt_find_remote_gatt_client_info_from_conn_id(int conn_id)
+{
+       GSList *l;
+       struct gatt_client_info_t *info = NULL;
+
+       for (l = gatt_client_info_list; l != NULL; l = g_slist_next(l)) {
+               info = (struct gatt_client_info_t*)l->data;
+               if (info == NULL)
+                       continue;
+
+               if (info->connection_id == conn_id) {
+                       BT_INFO("Remote GATT client found addr[%s]", info->addr);
+                       return info;
+               }
+       }
+       return NULL;
+}
+
+static void __bt_handle_gatt_server_connection_state(event_gatts_conn_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_client_info_t *conn_info = NULL;
+       bt_service_app_info_t *info = NULL;
+       bluetooth_device_address_t dev_addr;
+       GVariant *param = NULL;
+       int k;
+
+       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+
+
+       /* 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 (info->instance_id == event->server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_CONNECT_LE,
+                                       (bluetooth_device_address_t*)&dev_addr, sizeof(bluetooth_device_address_t));
+
+                       break;
+               }
+       }
+
+       /* Send event to BT-API */
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("GATT Server Connedted: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
+                       address, event->server_inst, event->conn_id);
+
+
+       /* Check if device is already in connected list */
+       conn_info = __bt_find_remote_gatt_client_info(address);
+
+       if (!conn_info) {
+               param = g_variant_new("(is)", result, address);
+               /* Send event to application */
+               _bt_send_event(BT_GATT_SERVER_EVENT,
+                               BLUETOOTH_EVENT_GATT_CONNECTED,
+                               param);
+
+               /* Save Connection info */
+               conn_info = g_new0(struct gatt_client_info_t, 1);
+               conn_info->addr = g_strdup(address);
+               BT_INFO("Added GATT client addr[%s]", conn_info->addr);
+               conn_info->connection_id = event->conn_id;
+               conn_info->instance_id = event->server_inst;
+               gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info);
+               BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
+       }
+
+       g_free(address);
+}
+
+/* GATT Server Dis connected */
+static void __bt_handle_gatt_server_disconnection_state(event_gatts_conn_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_client_info_t *conn_info = NULL;
+       bluetooth_device_address_t dev_addr;
+       bt_service_app_info_t *info = NULL;
+       GVariant *param = NULL;
+       int k;
+
+       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+
+       /* 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 (info->instance_id == event->server_inst) {
+                       BT_INFO("Found GATT Server.. UUID [%s], sender [%s]", info->uuid, info->sender);
+                       __bt_gatt_handle_pending_request_info(result, BT_DISCONNECT_LE,
+                                       (bluetooth_device_address_t*)&dev_addr, sizeof(bluetooth_device_address_t));
+
+                       break;
+               }
+       }
+
+       /* Send event to BT-API */
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("GATT Server DisConnected: Remote Client addr[%s] Server Instance [%d] Connection ID [%d]",
+                       address, event->server_inst, event->conn_id);
+
+       param = g_variant_new("(is)", result, address);
+       /* Send event to application */
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_DISCONNECTED,
+                       param);
+
+       /* Remove Connection info */
+       conn_info = __bt_find_remote_gatt_client_info(address);
+       if (conn_info) {
+               BT_INFO("Remove GATT client info from List..");
+               /* Remove info from List */
+               gatt_client_info_list = g_slist_remove(gatt_client_info_list, conn_info);
+               BT_INFO("Total num of connected GATT clients [%d]", g_slist_length(gatt_client_info_list));
+               g_free(conn_info->addr);
+               g_free(conn_info);
+       }
+
+       g_free(address);
+}
+
+static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
+{
+       char *address;
+       bluetooth_device_address_t dev_addr;
+       GVariant *param = NULL;
+       int result = BLUETOOTH_ERROR_NONE;
+       gboolean need_resp;
+       gboolean is_prepare_write;
+       char *write_val;
+       GVariant *data = NULL;
+       int i;
+       struct gatt_server_req_info *req_info = NULL;
+       BT_INFO("GATT Server Write Requested");
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+
+       BT_INFO("GATT Server Write Req Connection ID: [%d]", event->attr_trans.conn_id);
+       BT_INFO("GATT Server Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
+       BT_INFO("GATT Server Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
+       BT_INFO("GATT Server Write Req Attribute Offset: [%d]", event->attr_trans.offset);
+       BT_INFO("GATT Server Write Req value length [%d]", event->length);
+       BT_INFO("GATT Server Write Req needs response: [%d]", event->need_rsp);
+       BT_INFO("GATT Server Write Req Is Prep: [%d]", event->is_prep);
+
+       if (event->length <= 0) {
+               BT_INFO("GATT Server write requested, but length of attr value is 0");
+               g_free(event);
+               return;
+       }
+
+       need_resp = event->need_rsp;
+       is_prepare_write = event->is_prep;
+
+       write_val = g_memdup(&event->value[0], event->length);
+
+       address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("GATT Server Write Request from remote client [%s]",address);
+       /* DEBUG */
+       if (event->length > 0) {
+               for(i=0; i < event->length; i++)
+                       BT_DBG("Data[%d] = [0x%x]",i, event->value[i]);
+       }
+       /* Save Write Request Info */
+       req_info = g_new0(struct gatt_server_req_info, 1);
+       req_info->request_id = event->attr_trans.trans_id;
+       req_info->attribute_handle = event->attr_trans.attr_handle;
+       req_info->connection_id = event->attr_trans.conn_id;
+       req_info->addr = address;
+       req_info->offset = event->attr_trans.offset;
+       req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_WRITE;
+       gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
+
+       data = g_variant_new_from_data(
+                                G_VARIANT_TYPE_BYTESTRING,
+                                write_val,
+                                event->length,
+                                TRUE, NULL, NULL);
+
+       param = g_variant_new("(iiiiiibbsn@ay)", result,
+                       event->attr_trans.conn_id,
+                       event->attr_trans.trans_id,
+                       event->attr_trans.attr_handle,
+                       event->attr_trans.offset,
+                       event->length,
+                       need_resp,
+                       is_prepare_write,
+                       address,
+                       event->length,
+                       data);
+
+        _bt_send_event(BT_GATT_SERVER_EVENT,
+                        BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED,
+                       param);
+
+       g_free(event);
+       g_free(write_val);
+}
+
+static void __bt_handle_gatt_server_read_requested(event_gatts_srvc_read_attr_t *event)
+{
+       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       bluetooth_device_address_t dev_addr;
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_server_req_info *req_info = NULL;
+       GVariant *param = NULL;
+       gboolean is_long;
+       BT_INFO("GATT Server Read Requested");
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+
+       BT_INFO("GATT Server-Client Connection ID: [%d]", event->attr_trans.conn_id);
+       BT_INFO("GATT Server-Client Transaction ID: [%d]", event->attr_trans.trans_id);
+       BT_INFO("GATT Server Attribute Handle: [%d]", event->attr_trans.attr_handle);
+       BT_INFO("GATT Server Attribute Offset for read: [%d]", event->attr_trans.offset);
+       BT_INFO("GATT Server Attribute is long: [%d]", event->is_long);
+
+       is_long = event->is_long;
+
+       /* Save Read Request Info */
+       req_info = g_new0(struct gatt_server_req_info, 1);
+       req_info->request_id = event->attr_trans.trans_id;
+       req_info->attribute_handle = event->attr_trans.attr_handle;
+       req_info->connection_id = event->attr_trans.conn_id;
+       req_info->addr = address;
+       req_info->offset = event->attr_trans.offset;
+       req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_READ;
+       gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
+
+       /* Send event to BT-API */
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("GATT Server Read Request from remote client [%s]",address);
+
+       param = g_variant_new("(iiiiibs)", result,
+                       event->attr_trans.conn_id,
+                       event->attr_trans.trans_id,
+                       event->attr_trans.attr_handle,
+                       event->attr_trans.offset,
+                       is_long,
+                       address);
+
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED,
+                       param);
+
+       g_free(event);
+}
+
+static void __bt_handle_gatt_server_indicate_confirmed(event_gatts_ind_cnfrm_t *event)
+{
+       bluetooth_device_address_t dev_addr;
+       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       int cur_connected_clients;
+       static int recvd = 0;
+       gboolean completed = 0;
+       GVariant *param = NULL;
+
+       /* OAL event does provide error, so MW assumes event will never contain wrong data,
+          incase of any issues, check with OAL */
+       int result = BLUETOOTH_ERROR_NONE;
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("Indication sent to GATT client [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d]",
+                       address, event->conn_id, event->trans_id, event->attr_handle);
+
+
+       cur_connected_clients = g_slist_length(gatt_client_info_list);
+       BT_INFO("Number of connected clients during sending Indication [%d] & current connected count [%d]",
+                       num_indicate_clients, cur_connected_clients);
+
+       recvd++;
+       if (recvd == num_indicate_clients) {
+               BT_INFO("Gatt indication confirm event for last GATT client.. [%s]", address);
+               completed = 1; /* Last event */
+               recvd = 0; /* Reset */
+               num_indicate_clients = 0;
+       }
+
+       param = g_variant_new("(isib)",
+                       result,
+                        address,
+                        event->attr_handle,
+                        completed);
+
+       /* Send event to BT-API */
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED,
+                       param);
+
+       BT_INFO("Received Indication confirm for client number [%d]", recvd);
+       g_free(event);
+       g_free(address);
+}
+
+/* Tizen Platform Specific */
+static void __bt_handle_gatt_server_notification_changed(event_gatts_notif_t *event)
+{
+       bluetooth_device_address_t dev_addr;
+       char *address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       GVariant *param = NULL;
+       gboolean notify;
+
+       /* OAL event does provide error, so MW assumes event will never contain wrong data,
+          incase of any issues, check with OAL */
+       int result = BLUETOOTH_ERROR_NONE;
+
+       memcpy(dev_addr.addr, event->address.addr, 6);
+       _bt_convert_addr_type_to_string(address,
+                       (unsigned char *)dev_addr.addr);
+
+       BT_INFO("notification_changed [%s] conn_ ID [%d] transaction ID [%d] Att handle [%d] Notify[%d]",
+                       address, event->conn_id, event->trans_id, event->attr_handle, event->notify);
+
+       /* Set Notifcation status */
+       notify = event->notify;
+
+       param = g_variant_new("(isib)",
+                       result,
+                       address,
+                       event->attr_handle,
+                       notify);
+
+       /* Send event to BT-API */
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
+                       param);
+
+       g_free(event);
+       g_free(address);
+}
+
+static void __bt_handle_gatt_mtu_changed_event(event_gatts_mtu_changed_t *event)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       struct gatt_client_info_t *conn_info = NULL;
+       GVariant *param = NULL;
+       guint8 status = 0;
+       BT_INFO("GATT Server MTU changed event");
+
+       conn_info = __bt_find_remote_gatt_client_info_from_conn_id(event->conn_id);
+       if (conn_info == NULL) {
+               BT_ERR("Cant find connection Information");
+               g_free(event);
+               return;
+       }
+       BT_INFO("Got connection Info GATT client [%s] MTU Size [%d]",
+                       conn_info->addr, event->mtu_size);
+
+       param = g_variant_new("(isqy)",
+                       result,
+                       conn_info->addr,
+                       event->mtu_size,
+                       status);
+
+       /* Send event to BT-API */
+       _bt_send_event(BT_GATT_SERVER_EVENT,
+                       BLUETOOTH_EVENT_GATT_ATT_MTU_CHANGED,
+                       param);
+       g_free(event);
 }
 
 static void __bt_gatt_event_handler(int event_type, gpointer event_data)
@@ -479,8 +1341,396 @@ static void __bt_gatt_event_handler(int event_type, gpointer event_data)
                 __bt_handle_server_instance_registered(event);
                 break;
         }
+       case OAL_EVENT_GATTS_SERVICE_ADDED: {
+               BT_INFO("OAL Event: GATT Service added");
+               event_gatts_srvc_prm_t *service_parm = g_memdup(event_data, sizeof(event_gatts_srvc_prm_t));
+                __bt_handle_gatt_server_service_added(service_parm);
+               break;
+       }
+       case OAL_EVENT_GATTS_CHARACTERISTIC_ADDED: {
+               BT_INFO("OAL Event: GATT characteristic added");
+                event_gatts_srvc_charctr_t *char_parm = g_memdup(event_data, sizeof(event_gatts_srvc_charctr_t));
+               __bt_handle_gatt_server_characteristic_added(char_parm);
+               break;
+       }
+        case OAL_EVENT_GATTS_DESCRIPTOR_ADDED: {
+               BT_INFO("OAL Event: GATT descriptor added");
+                event_gatts_srvc_descr_t *desc_parm = g_memdup(event_data, sizeof(event_gatts_srvc_descr_t));
+               __bt_handle_gatt_server_descriptor_added(desc_parm);
+               break;
+       }
+        case OAL_EVENT_GATTS_SERVICE_STARTED: {
+               BT_INFO("OAL Event: GATT Service started");
+                event_gatts_srvc_t *svc_started = g_memdup(event_data, sizeof(event_gatts_srvc_t));
+               __bt_handle_gatt_server_service_started(svc_started);
+               break;
+       }
+       case OAL_EVENT_GATTS_SERVICE_STOPED: {
+                BT_INFO("OAL Event: GATT Service stopped");
+                event_gatts_srvc_t *svc_stopped = g_memdup(event_data, sizeof(event_gatts_srvc_t));
+                __bt_handle_gatt_server_service_stopped(svc_stopped);
+                break;
+        }
+        case OAL_EVENT_GATTS_SERVICE_DELETED: {
+                BT_INFO("OAL Event: GATT Service deleted");
+                event_gatts_srvc_t *svc_deleted = g_memdup(event_data, sizeof(event_gatts_srvc_t));
+                __bt_handle_gatt_server_service_deleted(svc_deleted);
+                break;
+        }
+       case OAL_EVENT_GATTS_CONNECTION_COMPLETED: {
+               BT_INFO("OAL Event: GATT Server Connected");
+               event_gatts_conn_t* event = g_memdup(event_data, sizeof(event_gatts_conn_t));
+               __bt_handle_gatt_server_connection_state(event);
+               break;
+       }
+       case OAL_EVENT_GATTS_DISCONNECTION_COMPLETED: {
+               BT_INFO("OAL Event: GATT Server Disconnected");
+               event_gatts_conn_t* event = g_memdup(event_data, sizeof(event_gatts_conn_t));
+               __bt_handle_gatt_server_disconnection_state(event);
+               break;
+       }
+       case OAL_EVENT_GATTS_REQUEST_READ: {
+               BT_INFO("OAL Event: GATT Server Read Request");
+                event_gatts_srvc_read_attr_t *read_req = g_memdup(event_data, sizeof(event_gatts_srvc_read_attr_t));
+                __bt_handle_gatt_server_read_requested(read_req);
+               break;
+       }
+       case OAL_EVENT_GATTS_REQUEST_WRITE: {
+               BT_INFO("OAL Event: GATT Server Write Request");
+                event_gatts_srvc_write_attr_t *write_req = g_memdup(event_data, sizeof(event_gatts_srvc_write_attr_t));
+                __bt_handle_gatt_server_write_requested(write_req);
+               break;
+       }
+       case OAL_EVENT_GATTS_IND_CONFIRM: {
+               BT_INFO("OAL Event: GATT Server Indication confirmed");
+                event_gatts_ind_cnfrm_t *parm = g_memdup(event_data, sizeof(event_gatts_ind_cnfrm_t));
+                __bt_handle_gatt_server_indicate_confirmed(parm);
+               break;
+       }
+       case OAL_EVENT_GATTS_NOTIFICATION: { /* Tizen Platform Specific */
+               BT_INFO("OAL Event: GATT Server DisConnected");
+               event_gatts_notif_t* notif = g_memdup(event_data, sizeof(event_gatts_notif_t));
+               __bt_handle_gatt_server_notification_changed(notif);
+               break;
+       }
+       case OAL_EVENT_GATTS_MTU_CHANGED: {
+                BT_INFO("OAL Event: GATT Server MTU changed event callback");
+                event_gatts_mtu_changed_t *mtu_changed = g_memdup(event_data, sizeof(event_gatts_mtu_changed_t));
+                __bt_handle_gatt_mtu_changed_event(mtu_changed);
+                break;
+        }
         default:
                 break;
         }
        BT_DBG("-");
 }
+
+int _bt_gatt_server_add_service(char *sender, int service_type,
+                int num_handles, char *svc_uuid, int instance_id)
+{
+       BT_CHECK_PARAMETER(svc_uuid, return);
+       BT_CHECK_PARAMETER(sender, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       oal_gatt_srvc_id_t svc_data;
+
+       svc_data.is_prmry = service_type;
+       svc_data.id.inst_id = instance_id;
+
+       BT_INFO("Service UUID [%s] Num handles [%d] Instance ID [%d]", svc_uuid, num_handles, instance_id);
+       _bt_string_to_uuid(svc_uuid, (service_uuid_t*)&svc_data.id.uuid);
+
+       ret = gatts_add_service(instance_id, &svc_data, num_handles);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+
+int _bt_gatt_server_add_included_service(char *sender, int instance_id,
+                int service_handle, int included_svc_handle)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       ret = gatts_add_included_services(instance_id, service_handle, included_svc_handle);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_add_characteristic(char *sender, char *char_uuid,
+                bluetooth_gatt_server_attribute_params_t *param)
+{
+       BT_CHECK_PARAMETER(char_uuid, return);
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(param, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       oal_uuid_t uuid = {{0}};
+
+       BT_INFO("Char UUID [%s] Instance ID [%d]", char_uuid, param->instance_id);
+       _bt_string_to_uuid(char_uuid, (service_uuid_t*)&uuid);
+
+       BT_INFO("Char permission From API [0x%x]", param->permissions);
+
+       ret = gatts_add_characteristics(param->instance_id, param->service_handle, &uuid,
+                       param->properties, (int)param->permissions);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_add_descriptor(char *sender, char *desc_uuid,
+                bt_gatt_permission_t *param, int service_handle, int instance_id)
+{
+       BT_CHECK_PARAMETER(desc_uuid, return);
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(param, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       oal_uuid_t uuid = {{0}};
+
+       BT_INFO("Descriptor UUID [%s] Instance ID [%d] Service handle [%d]",
+                       desc_uuid, service_handle, instance_id);
+
+       _bt_string_to_uuid(desc_uuid, (service_uuid_t*)&uuid);
+
+       BT_INFO("Descriptor permission From API [0x%x]", *param);
+       ret = gatts_add_descriptor(instance_id, service_handle, &uuid, (int)*param);
+
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_start_service(char *sender, int service_handle, int instance_id)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       ret = gatts_start_service(instance_id, service_handle, BT_GATT_TRANSPORT_LE);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_stop_service(char *sender, int service_handle, int instance_id)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       ret = gatts_stop_service(instance_id, service_handle);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_delete_service(char *sender, int service_handle, int instance_id)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       int ret = OAL_STATUS_SUCCESS;
+       GSList *l;
+       int *handle = NULL;
+
+       ret = gatts_delete_service(instance_id, service_handle);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Remove the Service Handle */
+       for (l = numapps[instance_id].service_handles; l != NULL;) {
+               handle = l->data;
+               l = g_slist_next(l);
+               if (handle && *handle == service_handle) {
+                       BT_INFO("Remove Service handle [%d]", *handle);
+                       numapps[instance_id].service_handles = g_slist_remove(numapps[instance_id].service_handles, handle);
+                       g_free(handle);
+                       handle = NULL;
+               }
+       }
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_send_response(char *sender, bluetooth_gatt_att_data_t *data,
+                bluetooth_gatt_server_response_params_t *param)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(data, return);
+       BT_CHECK_PARAMETER(param, return);
+       struct gatt_server_req_info *req_info = NULL;
+       int ret = OAL_STATUS_SUCCESS;
+
+       oal_gatt_response_t response;
+
+       BT_INFO("GATT Server Response: Req Type [%d] req_id [%d] status [%d] auth_req [%d] offset[%d] data len[%d]",
+                       param->req_type, param->request_id,
+                       param->response_status, param->auth_req,
+                       data->offset, data->length);
+
+       /* Search for matching Request in List */
+       req_info = __bt_gatt_server_find_request_info(param->request_id, param->req_type);
+       if (!req_info) {
+               BT_ERR("GATT Server Req Info not found for current response..return Error");
+               return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+       }
+
+       memset(&response, 0x00, sizeof(oal_gatt_response_t));
+
+       response.handle = req_info->attribute_handle;
+       response.attr_value.auth_req = param->auth_req;
+       response.attr_value.handle = req_info->attribute_handle;
+       response.attr_value.offset = data->offset;
+       response.attr_value.len = data->length;
+       memcpy(&response.attr_value.value, &data->data, data->length);
+
+
+       ret = gatts_send_response(req_info->connection_id, param->request_id,
+                       param->response_status, &response);
+
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_INFO("GATT Server Response successfully sent");
+       /* Remove GATT server request from list */
+       gatt_server_requests = g_slist_remove(gatt_server_requests, req_info);
+       g_free(req_info->addr);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_send_indication(char *sender, bluetooth_device_address_t *dev_addr,
+                                bluetooth_gatt_att_data_t *data,
+                                bluetooth_gatt_server_indication_params_t *param)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(data, return);
+       BT_CHECK_PARAMETER(param, return);
+       char *address;
+       gboolean all_send = FALSE;
+       int ret = OAL_STATUS_SUCCESS;
+       struct gatt_client_info_t *conn;
+
+       address = g_malloc0(BT_ADDRESS_STRING_SIZE);
+       _bt_convert_addr_type_to_string(address, dev_addr->addr);
+
+       if (memcmp(dev_addr->addr, BDADDR_ANY, 6) == 0) {
+               BT_INFO("GATT Server: Send Indication to all connected GATT clients..");
+               all_send = TRUE;
+       } else {
+               BT_INFO("GATT Server: Send Indication to connected GATT client addr [%s]", address);
+       }
+
+       /* Attempt to send Notification/Indication to all Connected GATT clients */
+       if (all_send) {
+               ret = __bt_gatt_send_indication_to_all_connected_clients(data, param);
+               if (ret != OAL_STATUS_SUCCESS) {
+                       BT_ERR("ret: %d", ret);
+                       g_free(address);
+                       return BLUETOOTH_ERROR_INTERNAL;
+               }
+
+       } else {
+               conn = __bt_find_remote_gatt_client_info(address);
+               if (conn) {
+                       ret = gatts_send_indication(param->instance_id, param->atrribute_handle,
+                                       conn->connection_id, data->length,
+                                       param->need_confirmation, (char *)(&data->data[0]));
+
+                       if (ret != OAL_STATUS_SUCCESS) {
+                               BT_ERR("ret: %d", ret);
+                               BT_INFO("Indication failed to send to Remote GATT Client [%s]", address);
+                               g_free(address);
+                               return BLUETOOTH_ERROR_INTERNAL;
+                       }
+                       BT_INFO("Indication sent to Remote GATT Client [%s] wait for Notification completed event from OAL",address);
+                       g_free(address);
+                       num_indicate_clients = 1;
+                       return BLUETOOTH_ERROR_NONE;
+               }
+               BT_ERR("Remote GATT client [%s] is not connected..Cant send Indication!!", address);
+               g_free(address);
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
+       g_free(address);
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_gatt_server_update_attribute_value(char *sender, int instance_id,
+                bluetooth_gatt_server_update_value_t *param)
+{
+       BT_CHECK_PARAMETER(sender, return);
+       BT_CHECK_PARAMETER(param, return);
+       int ret = OAL_STATUS_SUCCESS;
+
+       oal_gatt_value_t value;
+       BT_INFO("GATT Server Update value: Instance ID [%d] attr handle [%d] Value len [%d]",
+                       instance_id, param->attribute_handle, param->length);
+
+
+       memset(&value, 0x00, sizeof(oal_gatt_value_t));
+
+       value.handle = param->attribute_handle;
+       value.len = param->length;
+       memcpy(&value.value, &param->data.data, param->length);
+
+       ret = gatts_update_att_value(instance_id, &value);
+
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_INFO("GATT Server Update Attribute Value successfully");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_get_att_mtu(bluetooth_device_address_t *address,
+                unsigned int *mtu)
+{
+       BT_CHECK_PARAMETER(address, return);
+       BT_CHECK_PARAMETER(mtu, return);
+       struct gatt_client_info_t *conn_info = NULL;
+       char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
+       int ret = OAL_STATUS_SUCCESS;
+       int stack_mtu;
+
+       _bt_convert_addr_type_to_string(addr, address->addr);
+
+       BT_INFO("Get current MTU size for the remote client:DevAddress:[%s]",addr);
+
+       conn_info = __bt_find_remote_gatt_client_info(addr);
+       if (conn_info) {
+               BT_INFO("GATT Client [%s] is connected, conn Id [%d] Instance ID [%d]",
+                               conn_info->addr, conn_info->connection_id, conn_info->instance_id);
+       } else {
+               BT_ERR("GATT Client [%s] is not yet connected..");
+               return BLUETOOTH_ERROR_NOT_CONNECTED;
+       }
+
+       ret = gatts_get_att_mtu(conn_info->connection_id, &stack_mtu);
+       if (ret != OAL_STATUS_SUCCESS) {
+               BT_ERR("ret: %d", ret);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+       BT_INFO("ATT MTU received from OAL [%d]", stack_mtu);
+       *mtu = (unsigned int)stack_mtu;
+       return BLUETOOTH_ERROR_NONE;
+}
index 20d8f2a..2d9a8d5 100755 (executable)
@@ -94,6 +94,7 @@ extern "C" {
 #define BT_ADDRESS_STRING_SIZE 18
 #define BT_RFCOMM_BUFFER_MAX 1024
 #define BT_LOWER_ADDRESS_LENGTH 9
+#define BT_UUID_LEN 16
 
 #define BT_AGENT_AUTO_PAIR_BLACKLIST_FILE (APP_SYSCONFDIR"/auto-pair-blacklist")
 #define BT_AGENT_NEW_LINE "\r\n"
@@ -338,9 +339,9 @@ char *_bt_get_device_object_path(char *address);
 
 char *_bt_get_profile_uuid128(bt_profile_type_t profile_type);
 
-char *_bt_convert_error_to_string(int error);
+const char *_bt_convert_error_to_string(int error);
 
-char * _bt_convert_disc_reason_to_string(int reason);
+const char * _bt_convert_disc_reason_to_string(int reason);
 
 void _bt_logging_connection(gboolean connect, int addr_type);
 
index b3db770..b349130 100644 (file)
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <sys/types.h>
 #include "bluetooth-api.h"
+#include "bluetooth-gatt-server-api.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -50,6 +51,8 @@ void _bt_set_new_scan_rsp_data(bluetooth_scan_resp_data_t *scan, int len, int in
 
 void _bt_set_new_adv_data(bluetooth_advertising_data_t *adv, int len, int instance);
 
+void _bt_update_adv_handle(const char *sender, int adv_handle);
+
 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);
@@ -58,6 +61,37 @@ int _bt_is_sender_gatt_server_with_no_adv(const char *sender, int adv_handle);
 
 void _bt_check_adv_app_termination(const char *name);
 
+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_response(char *sender, bluetooth_gatt_att_data_t *data,
+                bluetooth_gatt_server_response_params_t *param);
+
+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_update_attribute_value(char *sender, int instance_id,
+                bluetooth_gatt_server_update_value_t *param);
+
+int _bt_get_att_mtu(bluetooth_device_address_t *address,
+                unsigned int *mtu);
+
+//int _bt_gatt_server_enable_application(int instance_id);
 #if 0
 int _bt_gatt_server_register(char *sender);
 
index 8c94c80..3c5d782 100644 (file)
@@ -1415,7 +1415,7 @@ typedef struct {
        char *service_handle;
        char *address;
        guint16 offset;
-       guint8 req_id;
+       guint req_id;
 } bt_gatt_read_req_t;
 
 /**
@@ -1426,6 +1426,7 @@ typedef struct {
        char *service_handle;
        char *address;
        guint8 req_id;
+       gboolean response_needed;
        guint16 offset;
        guint8 *att_value;
        guint32 val_len;
diff --git a/include/bluetooth-gatt-server-api.h b/include/bluetooth-gatt-server-api.h
new file mode 100644 (file)
index 0000000..50e36ca
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Bluetooth-frwk
+ *
+ * Contact: Anupam Roy (anupam.r@samsung.com)
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __BLUETOOTH_GATT_SERVER_API_H
+#define __BLUETOOTH_GATT_SERVER_API_H
+
+#include <stdint.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dlog.h>
+
+#include <bluetooth-api.h>
+
+#define BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX      610 /**< GATT ATT value max len */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * GATT Server Request type
+ */
+typedef enum {
+        BLUETOOTH_GATT_REQUEST_TYPE_READ = 0x00,       /* Read Requested */
+        BLUETOOTH_GATT_REQUEST_TYPE_WRITE = 0x01,      /* Write Requested */
+        BLUETOOTH_GATT_REQUEST_TYPE_EXEC_WRITE = 0x02, /* Exec Write Requested */
+} bluetooth_gatt_att_request_type_e;
+
+/**
+ * GATT Server Response/Indication data
+ */
+typedef struct {
+        guint8 data[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX];
+        int length;
+        int offset;
+} bluetooth_gatt_att_data_t;
+
+/**
+ * GATT Server service add data
+ */
+typedef struct {
+        int service_type;
+        int num_handles;
+        int instance_id;
+} bluetooth_gatt_server_service_params_t;
+
+/**
+ * GATT Server attributes(characteristic/descriptors) add data
+ */
+typedef struct {
+        bt_gatt_permission_t permissions;
+        bt_gatt_characteristic_property_t properties;
+        int service_handle;
+        int instance_id;
+} bluetooth_gatt_server_attribute_params_t;
+
+/**
+ * GATT Server Indication data
+ */
+typedef struct {
+        int atrribute_handle;
+       bluetooth_device_address_t device_address;      /**< device address */
+        gboolean need_confirmation;
+        int instance_id;
+} bluetooth_gatt_server_indication_params_t;
+
+/**
+ * GATT Server connection/disconnection info
+ */
+typedef struct {
+        bluetooth_device_address_t device_address;      /** < Device address */
+        int server_instance;                           /** < GATT Server Instance Id */
+} bluetooth_gatt_server_connection_info_t;
+
+/**
+* GATT Server Service Added info
+*/
+typedef struct {
+        int server_instance;       /** < GATT Server Instance Id */
+        int service_handle;        /** < GATT Server Service handle */
+        int is_primary;            /** < GATT Server Is Primary Service */
+        char uuid[BLUETOOTH_UUID_STRING_MAX];
+} bluetooth_gatt_server_service_added_info_t;
+
+/**
+* GATT Server Included Service Added info
+*/
+typedef struct {
+        int server_instance;               /** < GATT Server Instance Id */
+        int service_handle;                /** < GATT Server Service handle */
+        int included_service_handle;       /** < GATT Server Included service handle */
+} bluetooth_gatt_server_included_service_added_info_t;
+
+
+/**
+ * GATT Server write attribute data received from Remote GATT client: Max Size is 600 bytes
+ */
+typedef struct {
+        char data[BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX + 1];
+} bluetooth_gatt_server_write_data_t;
+
+
+/**
+* GATT Server Attribute Added Info
+*/
+typedef struct {
+        int server_instance;                           /** < GATT Server Instance Id */
+        int service_handle;                            /** < GATT Server Service handle */
+        int attr_handle;                               /** < GATT Server Attribute Handle (Characteristic or Descriptor) */
+        char uuid[BLUETOOTH_UUID_STRING_MAX];           /** < GATT Server Atribute UUID */
+} bluetooth_gatt_server_attribute_added_info_t;
+
+/**
+* GATT Server Service Info
+*/
+typedef struct {
+        int server_instance;                           /** < GATT Server Instance Id */
+        int service_handle;                            /** < GATT Server Service handle */
+} bluetooth_gatt_server_service_status_t;
+
+/**
+* GATT Server Read Requested Info
+*/
+typedef struct {
+        int connection_id;                             /** < GATT Server Connection ID */
+        int request_id;                                /** < GATT Server Read Request ID */
+        int attribute_handle;                          /** < GATT Server att handle */
+        int offset;                                    /** < GATT Server attribute offset */
+        gboolean is_long;                              /** < GATT Server Is Long attribute  */
+        bluetooth_device_address_t device_address;      /**< Remote GATT client device address */
+} bluetooth_gatt_server_read_requested_info_t;
+
+/**
+* GATT Server Write Requested Info
+*/
+typedef struct {
+        int connection_id;                              /** < GATT Server Connection ID */
+        int request_id;                                 /** < GATT Server Write Request ID */
+        int attribute_handle;                           /** < GATT Server Write att handle */
+        int offset;                                    /** < GATT Server attribute offset */
+        gboolean need_resp;                                 /** < GATT Server Write req needs response  */
+        gboolean is_prep_write;                             /** < GATT Server Is Prepared write  */
+        int length;                                    /** < GATT Server Write attribute length  */
+       bluetooth_gatt_server_write_data_t data;        /** < Write attribute data */
+        bluetooth_device_address_t device_address;      /** < Remote GATT client device address */
+} bluetooth_gatt_server_write_requested_info_t;
+
+/**
+* GATT Server Update Characteristic Value
+*/
+typedef struct {
+        int attribute_handle;                           /** < GATT Server Write att handle */
+        int length;                                    /** < GATT Server Write attribute length  */
+       bluetooth_gatt_server_write_data_t data;        /** < Write attribute data */
+} bluetooth_gatt_server_update_value_t;
+
+/**
+* GATT Server Exec write Requested Info
+*/
+typedef struct {
+        int connection_id;                             /** < GATT Server Connection ID */
+        int request_id;                                /** < GATT Server Exec Write Request ID */
+        int exec_write;                                /** < GATT Server Exec Write */
+        bluetooth_device_address_t device_address;     /** < Remote GATT client device address */
+} bluetooth_gatt_server_exec_write_requested_info_t;
+
+/**
+* GATT Server Indicate confirmed Info
+*/
+typedef struct {
+        int handle;                                    /** < GATT Attribute handle */
+        gboolean completed;                             /** < GATT Server Exec Write Request ID */
+        bluetooth_device_address_t device_address;     /** < Remote GATT client device address */
+} bluetooth_gatt_server_indicate_confirmed_info_t;
+
+/**
+* GATT Server Indicate confirmed Info
+*/
+typedef struct {
+        int handle;                                    /** < GATT Attribute handle */
+        gboolean notification;                          /** < GATT CCCD Notification changed */
+        bluetooth_device_address_t device_address;     /** < Remote GATT client device address */
+} bluetooth_gatt_server_notification_changed_t;
+
+/**
+ * GATT Server response data
+ */
+typedef struct {
+       bluetooth_gatt_att_request_type_e req_type;
+        int request_id;
+        int response_status;
+        gboolean auth_req;
+} bluetooth_gatt_server_response_params_t;
+
+/**
+ * GATT Server Bluedroid Specific Permission Mask
+ */
+typedef enum {
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_READ = 0x01,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_ENCRYPT_READ = 0x02,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_ENCRYPT_READ_MITM = 0x04,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_WRITE = 0x10,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_ENCRYPT_WRITE = 0x20,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_ENCRYPT_WRITE_MITM = 0x40,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_WRITE_SIGNED = 0x80,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_WRITE_SIGNED_MITM = 0x100,
+        BLUETOOTH_PRODUCT_GATT_PERMISSION_INVALID = 0xffff,
+} bt_product_gatt_permission_t;
+
+typedef struct {
+       int event;
+       int result;
+       void *param_data;
+       void *user_data;
+} gatt_server_event_param_t;
+
+typedef void (*gatt_server_cb_func_ptr)(int, gatt_server_event_param_t *, void *);
+
+/**
+ * @fn int bluetooth_gatt_server_init(gatt_server_cb_func_ptr callback_ptr, void *user_data)
+ * @brief Initialize GATT Server and register the callback
+ *
+ * This function is a synchronous call.
+ *
+ * @remark      None
+ *
+ */
+int bluetooth_gatt_server_init(int *instance_id, gatt_server_cb_func_ptr callback_ptr,
+                                                void *user_data);
+
+//int bluetooth_gatt_register_application(int instance_id);
+//int bluetooth_gatt_server_init(gatt_server_cb_func_ptr callback_ptr, void *user_data);
+
+int bluetooth_gatt_deinit(void);
+
+int bluetooth_gatt_server_register(const gchar *name, int *instance_id);
+
+int bluetooth_gatt_server_unregister(int instance_id);
+
+int bluetooth_gatt_server_connect(bluetooth_device_address_t *addr_hex, int instance_id);
+
+int bluetooth_gatt_server_disconnect(bluetooth_device_address_t *addr_hex, int instance_id);
+
+int bluetooth_gatt_server_add_service(const char *svc_uuid, int type, int numhandles, int instance_id, int *service_handle);
+
+int bluetooth_gatt_server_add_included_service(int instance_id, int service_handle, int included_handle);
+
+int bluetooth_gatt_server_add_new_characteristic(const char *char_uuid, const bluetooth_gatt_server_attribute_params_t *param, int *char_handle);
+
+
+int bluetooth_gatt_server_add_descriptor(const char *desc_uuid, bt_gatt_permission_t permissions, int service_handle,
+                                       int instance_id, int *descriptor_handle);
+
+int bluetooth_gatt_server_start_service(int service_handle, int instance_id);
+
+int bluetooth_gatt_server_stop_service(int service_handle, int instance_id);
+
+int bluetooth_gatt_server_delete_service(int service_handle, int instance_id);
+
+int bluetooth_gatt_server_send_indication(bluetooth_device_address_t *addr_hex,
+                                                       const bluetooth_gatt_server_indication_params_t *param,
+                                                        const bluetooth_gatt_att_data_t *att_value);
+
+int bluetooth_gatt_server_send_response(const bluetooth_gatt_server_response_params_t *param,
+                                                       const bluetooth_gatt_att_data_t *value);
+
+int bluetooth_gatt_server_update_multi_adv_instance(const gchar *unique_name, int instance_id);
+
+int bluetooth_gatt_server_update_characteristic(int instance_id, const bluetooth_gatt_server_update_value_t *value);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __BLUETOOTH_GATT_SERVER_API_H */
index 64bda12..0f0ad91 100644 (file)
@@ -68,6 +68,9 @@ typedef enum {
 #endif
        BT_HDP_EVENT,
        /* Will be added */
+//#ifndef GATT_DIRECT
+       BT_GATT_SERVER_EVENT,
+//#endif
 } bt_event_type_t;
 
 typedef enum {
@@ -317,7 +320,19 @@ typedef enum {
        BT_GATT_REGISTER_APPLICATION,
        BT_GATT_REGISTER_SERVICE,
        BT_GATT_SEND_RESPONSE,
+//#ifndef GATT_DIRECT
        BT_GATT_SERVER_REGISTER,
+       BT_GATT_SERVER_ADD_SERVICE,
+        BT_GATT_SERVER_ADD_CHARACTERISTIC,
+       BT_GATT_SERVER_ADD_DESCRIPTOR,
+       BT_GATT_SERVER_START_SERVICE,
+       BT_GATT_SERVER_STOP_SERVICE,
+        BT_GATT_SERVER_DELETE_SERVICE,
+       BT_GATT_SERVER_SEND_RESPONSE,
+       BT_GATT_SERVER_SEND_INDICATION,
+       BT_GATT_SERVER_UPDATE_VALUE,
+       BT_GATT_SERVER_DEREGISTER,
+//#endif
        BT_LE_IPSP_INIT = BT_FUNC_IPSP_BASE,
        BT_LE_IPSP_DEINIT,
        BT_LE_IPSP_CONNECT,
@@ -422,6 +437,10 @@ typedef struct {
 #define BT_HID_DEVICE_PATH "/org/projectx/bt/hid_device"
 #define BT_HDP_DEVICE_PATH "/org/projectx/bt/hdp_device"
 
+#ifndef GATT_DIRECT
+#define BT_GATT_SERVER_PATH "/org/projectx/bt/gatt_server"
+#endif
+
 #define BT_ENABLED "Enabled"
 #define BT_DISABLED "Disabled"
 #define BT_LE_ENABLED "LeEnabled"
@@ -513,6 +532,14 @@ typedef struct {
 #define BT_NAME_OWNER_CHANGED "NameOwnerChanged"
 #define BT_GATT_CONNECTED "GattConnected"
 #define BT_GATT_DISCONNECTED "GattDisconnected"
+
+#ifndef GATT_DIRECT
+#define BT_GATT_VALUE_CHANGED "GattValueChanged"
+#define BT_GATT_SERVER_READ_REQ "GattServerReadReq"
+#define BT_GATT_SERVER_NOTIFICATION_COMPLETED "GattServerNotification"
+#define BT_GATT_SERVER_NOTIFICATION_CHANGED "GattServerNotifChanged"
+#endif
+
 #define BT_GATT_REQ_ATT_MTU_CHANGED "GattReqAttMtuChanged"
 #define BT_GATT_CHAR_VAL_CHANGED "GattCharValueChanged"
 #ifdef GATT_NO_RELAY
index ee02f97..f3241d9 100644 (file)
@@ -74,13 +74,13 @@ Requires:   %{name} = %{version}-%{release}
 %description service
 This package is Bluetooth Service daemon to manage BT services.
 
-%package httpproxy
-Summary:    Bluetooth HTTP Proxy Service daemon
-Group:      Network & Connectivity/Bluetooth
-Requires:   %{name} = %{version}-%{release}
+#%package httpproxy
+#Summary:    Bluetooth HTTP Proxy Service daemon
+#Group:      Network & Connectivity/Bluetooth
+#Requires:   %{name} = %{version}-%{release}
 
-%description httpproxy
-This package is Bluetooth HTTP Proxy Service daemon
+#%description httpproxy
+#This package is Bluetooth HTTP Proxy Service daemon
 
 %package core
 Summary:    Bluetooth Core daemon
@@ -90,13 +90,13 @@ Requires:   %{name} = %{version}-%{release}
 %description core
 This package is Bluetooth core daemon to manage activation / deactivation.
 
-%package test
-Summary:    Bluetooth test application
-Group:      Network & Connectivity/Bluetooth
-Requires:   %{name} = %{version}-%{release}
+#%package test
+#Summary:    Bluetooth test application
+#Group:      Network & Connectivity/Bluetooth
+#Requires:   %{name} = %{version}-%{release}
 
-%description test
-This package is Bluetooth test application.
+#%description test
+#This package is Bluetooth test application.
 
 %if %{bt_hal} == ENABLED
 %package oal
@@ -212,7 +212,7 @@ rm -rf %{buildroot}
 
 install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk
 install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-service
-install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-httpproxy
+#install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-httpproxy
 install -D -m 0644 LICENSE %{buildroot}%{_datadir}/license/bluetooth-frwk-devel
 
 #mkdir -p %{buildroot}%{_libdir}/systemd/user
@@ -273,6 +273,7 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi
 %{_includedir}/bt-service/bluetooth-media-control.h
 %{_includedir}/bt-service/bluetooth-scmst-api.h
 %{_includedir}/bt-service/bluetooth-ipsp-api.h
+%{_includedir}/bt-service/bluetooth-gatt-server-api.h
 %{_libdir}/pkgconfig/bluetooth-api.pc
 %{_libdir}/libbluetooth-api.so
 %{_datadir}/license/bluetooth-frwk-devel
@@ -285,7 +286,7 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi
 #%{_libdir}/systemd/user/bluetooth-frwk-tv.service
 %{_unitdir}/%{_servicedir}/bluetooth-frwk.service
 %{_sysconfdir}/dbus-1/system.d/bluetooth-frwk-service.conf
-%{_bindir}/bluetooth-frwk-test
+#%{_bindir}/bluetooth-frwk-test
 #%{_bindir}/bluetooth-gatt-test
 #%{_bindir}/bluetooth-advertising-test
 %{_varlibdir}/bluetooth
@@ -295,13 +296,13 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi
 #%{_dumpdir}/bluetooth_log_dump.sh
 %{_datadir}/license/bluetooth-frwk-service
 
-%files httpproxy
-%manifest %{name}.manifest
-%defattr(-, root, root)
-%{_bindir}/bt-httpproxy
-%{_datadir}/license/bluetooth-frwk-httpproxy
-%{_datadir}/dbus-1/system-services/org.projectx.httpproxy.service
-%{_sysconfdir}/dbus-1/system.d/bluetooth-frwk-httpproxy.conf
+#%files httpproxy
+#%manifest %{name}.manifest
+#%defattr(-, root, root)
+#%{_bindir}/bt-httpproxy
+#%{_datadir}/license/bluetooth-frwk-httpproxy
+#%{_datadir}/dbus-1/system-services/org.projectx.httpproxy.service
+#%{_sysconfdir}/dbus-1/system.d/bluetooth-frwk-httpproxy.conf
 
 %files core
 %manifest %{name}.manifest
@@ -310,12 +311,12 @@ sed -i 's/%TZ_SYS_DEFAULT_USER/app/' %{buildroot}%{_datadir}/dbus-1/system-servi
 %{_bindir}/bt-core
 %{_sysconfdir}/dbus-1/system.d/bluetooth-frwk-core.conf
 
-%files test
-%manifest %{name}.manifest
-%defattr(-, root, root)
-%{_bindir}/bluetooth-frwk-test
-%{_bindir}/bluetooth-gatt-test
-%{_bindir}/bluetooth-advertising-test
+#%files test
+#%manifest %{name}.manifest
+#%defattr(-, root, root)
+#%{_bindir}/bluetooth-frwk-test
+#%{_bindir}/bluetooth-gatt-test
+#%{_bindir}/bluetooth-advertising-test
 
 %if %{bt_hal} == ENABLED
 %files oal