[CAPI Internal] Support for GATT Server 25/124925/1
authorAnupam Roy <anupam.r@samsung.com>
Wed, 12 Apr 2017 10:37:35 +0000 (16:07 +0530)
committerAnupam Roy <anupam.r@samsung.com>
Thu, 13 Apr 2017 05:05:19 +0000 (10:35 +0530)
This patch adds support for GATT Server API's
which are non GATT_DIRECT.
All API's calls are handled by BT service and further
by OAL and Bluez HAL library layers.

All codes are implemented inside #ifndef GATT_DIRECT

Change-Id: I6e14eee0c4d7a3d1fa437e73cbc8cfd7d1a7c5e4
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
include/bluetooth_private.h
include/mobile/bluetooth_type.h
include/tv/bluetooth_type.h
include/wearable/bluetooth_type.h
src/bluetooth-common.c
src/bluetooth-device.c
src/bluetooth-gatt.c
test/bt_unit_test.c

index 3cbeb2076566fafc20ac77aa7e5aaa421d0b2baf..c233bdb3d2c32264e922ec22c10ef77c81915f2f 100644 (file)
 #include <bluetooth-hid-api.h>
 #include <bluetooth-ipsp-api.h>
 
+#ifndef GATT_DIRECT
+#include <bluetooth-gatt-server-api.h>
+#endif
+
 #include "bluetooth.h"
 #include "bluetooth_internal.h"
 
@@ -337,6 +341,9 @@ typedef struct {
        void *parent;
        char *path;
        char *uuid;
+#ifndef GATT_DIRECT
+       int handle;
+#endif
 } bt_gatt_common_s;
 
 typedef struct {
@@ -345,7 +352,10 @@ typedef struct {
        void *parent;
        char *path;
        char *uuid;
-
+#ifndef GATT_DIRECT
+       int handle;
+        int numhandles;
+#endif
        bool is_included_service;
 
        bt_gatt_service_type_e service_type;
@@ -363,7 +373,10 @@ typedef struct {
        void *parent;
        char *path;
        char *uuid;
-
+#ifndef GATT_DIRECT
+       int handle;
+        bluetooth_device_address_t address;
+#endif
        int permissions;
        int properties;
        bt_gatt_write_type_e write_type;
@@ -397,7 +410,9 @@ typedef struct {
        void *parent;
        char *path;
        char *uuid;
-
+#ifndef GATT_DIRECT
+       int handle;
+#endif
        int permissions;
 
        bt_gatt_server_write_value_requested_cb write_value_requested_cb;
@@ -827,6 +842,15 @@ int _bt_gatt_client_update_characteristics(bt_gatt_h service);
 
 int _bt_gatt_client_update_descriptors(bt_gatt_h characteristic);
 
+#ifndef GATT_DIRECT
+/**
+ * @internal
+ * @brief Since the GATT Server call back and event proxy call backs have different prototype it is wrapper function.
+ */
+void _bt_gatt_server_event_proxy(int event, gatt_server_event_param_t *param, void *user_data);
+#endif
+
+
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_LE_MODULE
  * @brief Reads the maximum data length of LE packets supported by the controller.
index c49bc704c026a7bee1bfdff9fca900393e91076e..aa81ff5bd4b4828078a029f1902ee12364830022 100644 (file)
@@ -1818,6 +1818,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  * @param[in] request_id The identification of this request. It will be used to send a response.
  * @param[in] server The GATT server handle
  * @param[in] gatt_handle The characteristic or descriptor's GATT handle which has an old value
+ * @param[in] response_needed Indicates whether a response is required by the remote device - @c true if required, @c false if not
  * @param[in] offset The requested offset from where the @a gatt_handle value will be updated
  * @param[in] value The new value
  * @param[in] len The length of @a value
@@ -1828,7 +1829,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  */
 typedef void (*bt_gatt_server_write_value_requested_cb) (const char *remote_address,
                                int request_id, bt_gatt_server_h server,
-                               bt_gatt_h gatt_handle, int offset,
+                               bt_gatt_h gatt_handle, bool response_needed, int offset,
                                const char *value, int len, void *user_data);
 
 /**
index d4af7a916573a0ff484f1411c310939af6770ff4..53600a6d75f16aeab93abe057a892805576877dc 100644 (file)
@@ -1819,6 +1819,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  * @param[in] request_id The identification of this request. It will be used to send a response.
  * @param[in] server The GATT server handle
  * @param[in] gatt_handle The characteristic or descriptor's GATT handle which has an old value
+ * @param[in] response_needed Indicates whether a response is required by the remote device - @c true if required, @c false if not
  * @param[in] offset The requested offset from where the @a gatt_handle value will be updated
  * @param[in] value The new value
  * @param[in] len The length of @a value
@@ -1828,9 +1829,9 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  * @see bt_gatt_server_send_response()
  */
 typedef void (*bt_gatt_server_write_value_requested_cb) (const char *remote_address,
-                               int request_id, bt_gatt_server_h server,
-                               bt_gatt_h gatt_handle, int offset,
-                               const char *value, int len, void *user_data);
+                                int request_id, bt_gatt_server_h server,
+                                bt_gatt_h gatt_handle, bool response_needed, int offset,
+                                const char *value, int len, void *user_data);
 
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
index aa675e7e2d04d102470c33ccc7f87f01c004c6b7..8560cd429226597fb13de4422dff3927cdccaace 100644 (file)
@@ -1694,6 +1694,7 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  * @param[in] request_id The identification of this request. It will be used to send a response.
  * @param[in] server The GATT server handle
  * @param[in] gatt_handle The characteristic or descriptor's GATT handle which has an old value
+ * @param[in] response_needed Indicates whether a response is required by the remote device - @c true if required, @c false if not
  * @param[in] offset The requested offset from where the @a gatt_handle value will be updated
  * @param[in] value The new value
  * @param[in] len The length of @a value
@@ -1703,9 +1704,9 @@ typedef void (*bt_gatt_connection_state_changed_cb)(int result, bool connected,
  * @see bt_gatt_server_send_response()
  */
 typedef void (*bt_gatt_server_write_value_requested_cb) (const char *remote_address,
-                               int request_id, bt_gatt_server_h server,
-                               bt_gatt_h gatt_handle, int offset,
-                               const char *value, int len, void *user_data);
+                                int request_id, bt_gatt_server_h server,
+                                bt_gatt_h gatt_handle, bool response_needed, int offset,
+                                const char *value, int len, void *user_data);
 
 /**
  * @ingroup CAPI_NETWORK_BLUETOOTH_GATT_SERVER_MODULE
index 9681b6e7c41fb9ead32455f30a3a37559c29e5af..954c5490def5fd52da1adf9dabb2b6d0889e2229 100755 (executable)
@@ -724,6 +724,7 @@ static int __bt_get_bt_device_connection_info_s(bt_device_connection_info_s **de
        return BT_ERROR_NONE;
 }
 
+#ifdef GATT_DIRECT
 static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
                                        bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
 {
@@ -776,7 +777,62 @@ static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(
        }
        return NULL;
 }
+#else
+/* Search for handle */
+static bt_gatt_server_read_value_requested_cb __bt_gatt_attribute_get_read_cb(int att_handle, bt_gatt_server_h *server,
+                                                                bt_gatt_h *gatt_handle, void **user_data)
+{
+       const GSList *gatt_server_list = NULL;
+       const GSList *l1, *l2, *l3, *l4;
+
+       gatt_server_list = _bt_gatt_get_server_list();
+
+       for (l1 = gatt_server_list; l1 != NULL; l1 = l1->next) {
+               bt_gatt_server_s *serv = l1->data;
+
+               if (!serv)
+                       return NULL;
+
+               for (l2 = serv->services; l2 != NULL; l2 = l2->next) {
+                       bt_gatt_service_s *svc = l2->data;
+                       for (l3 = svc->characteristics; l3 != NULL; l3 = l3->next) {
+                               bt_gatt_characteristic_s *chr = l3->data;
+
+                               if (chr) {
+                                       if (chr->handle == att_handle) {
+                                               if (chr->read_requested_cb) {
+                                                       BT_INFO("GATT Server: Handle search match found! Its a characteristic: UUID [%s]", chr->uuid);
+                                                       *user_data = chr->read_requested_user_data;
+                                                       *gatt_handle = chr;
+                                                       *server = serv;
+                                                       return chr->read_requested_cb;
+                                               } else
+                                                       return NULL;
+                                       } else {
+                                               for (l4 = chr->descriptors; l4 != NULL; l4 = l4->next) {
+                                                       bt_gatt_descriptor_s *desc = l4->data;
+
+                                                       if (desc && desc->handle == att_handle) {
+                                                               if (desc->read_requested_cb) {
+                                                                       *user_data = desc->read_requested_user_data;
+                                                                       *gatt_handle = desc;
+                                                                       *server = serv;
+                                                                       BT_INFO("GATT Server: Handle search match found! Its a Desc UUID [%s]", desc->uuid);
+                                                                       return desc->read_requested_cb;
+                                                               } else
+                                                                       return NULL;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+#endif
 
+#ifdef GATT_DIRECT
 static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_change_cb(
                                        bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
 {
@@ -829,7 +885,61 @@ static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_cha
        }
        return NULL;
 }
+#else
+static bt_gatt_server_write_value_requested_cb __bt_gatt_attribute_get_value_change_cb(int att_handle, bt_gatt_h *server,
+                                                                bt_gatt_h *gatt_handle, void **user_data)
+{
+       const GSList *gatt_server_list = NULL;
+       const GSList *l1, *l2, *l3, *l4;
 
+       gatt_server_list = _bt_gatt_get_server_list();
+
+       for (l1 = gatt_server_list; l1 != NULL; l1 = l1->next) {
+               bt_gatt_server_s *serv = l1->data;
+
+               if (!serv)
+                       return NULL;
+
+               for (l2 = serv->services; l2 != NULL; l2 = l2->next) {
+                       bt_gatt_service_s *svc = l2->data;
+                       for (l3 = svc->characteristics; l3 != NULL; l3 = l3->next) {
+                               bt_gatt_characteristic_s *chr = l3->data;
+
+                               if (chr) {
+                                       if (chr->handle == att_handle) {
+                                               if (chr->write_value_requested_cb) {
+                                                       BT_INFO("GATT Server: Handle search match found! Its a characteristic: UUID [%s]", chr->uuid);
+                                                       *user_data = chr->write_value_requested_user_data;
+                                                       *gatt_handle = chr;
+                                                       *server = svc;
+                                                       return chr->write_value_requested_cb;
+                                               } else
+                                                       return NULL;
+                                       } else {
+                                               for (l4 = chr->descriptors; l4 != NULL; l4 = l4->next) {
+                                                       bt_gatt_descriptor_s *desc = l4->data;
+
+                                                       if (desc && desc->handle == att_handle) {
+                                                               if (desc->write_value_requested_cb) {
+                                                                       *user_data = desc->write_value_requested_user_data;
+                                                                       *gatt_handle = desc;
+                                                                       *server = svc;
+                                                                       BT_INFO("GATT Server: Handle search match found! Its a Desc UUID [%s]", desc->uuid);
+                                                                       return desc->write_value_requested_cb;
+                                                               } else
+                                                                       return NULL;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+#endif
+
+#ifdef GATT_DIRECT
 static bt_gatt_server_characteristic_notification_state_changed_cb
                __bt_gatt_attribute_get_notification_change_cb(
                                        bt_gatt_h service, bt_gatt_h attribute, bt_gatt_h *gatt_handle, void **user_data)
@@ -868,7 +978,47 @@ static bt_gatt_server_characteristic_notification_state_changed_cb
        }
        return NULL;
 }
+#else
+static bt_gatt_server_characteristic_notification_state_changed_cb
+               __bt_gatt_attribute_get_notification_change_cb(
+                                        bt_gatt_server_h *server, int handle, bt_gatt_h *char_handle, void **user_data)
+{
+       const GSList *gatt_server_list = NULL;
+       const GSList *l1, *l2, *l3;
+
+       gatt_server_list = _bt_gatt_get_server_list();
+
+       for (l1 = gatt_server_list; l1 != NULL; l1 = l1->next) {
+               bt_gatt_server_s *serv = l1->data;
+
+               if (!serv)
+                       return NULL;
+
+               for (l2 = serv->services; l2 != NULL; l2 = l2->next) {
+                       bt_gatt_service_s *svc = l2->data;
+
+                       for (l3 = svc->characteristics; l3 != NULL; l3 = l3->next) {
+                               bt_gatt_characteristic_s *chr = l3->data;
+
+                               if (chr && chr->handle == handle) {
+                                       if (chr->notified_cb) {
+                                               *user_data = chr->notified_user_data;
+                                               *char_handle =  (bt_gatt_h*) chr;
+                                               *server = serv;
+                                               return chr->notification_changed_cb;
+                                       } else
+                                               return NULL;
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
 
+
+#endif
+
+#ifdef GATT_DIRECT
 static bt_gatt_server_notification_sent_cb __bt_gatt_attribute_get_notification_completed_cb(
                                        bt_gatt_h service, bt_gatt_h attribute, void **user_data)
 {
@@ -905,6 +1055,42 @@ static bt_gatt_server_notification_sent_cb __bt_gatt_attribute_get_notification_
        }
        return NULL;
 }
+#else
+static bt_gatt_server_notification_sent_cb __bt_gatt_attribute_get_notification_completed_cb(
+                                        bt_gatt_server_h *server, int handle, bt_gatt_h *char_handle, void **user_data)
+{
+       const GSList *gatt_server_list = NULL;
+       const GSList *l1, *l2, *l3;
+
+       gatt_server_list = _bt_gatt_get_server_list();
+
+       for (l1 = gatt_server_list; l1 != NULL; l1 = l1->next) {
+               bt_gatt_server_s *serv = l1->data;
+
+               if (!serv)
+                       return NULL;
+
+               for (l2 = serv->services; l2 != NULL; l2 = l2->next) {
+                       bt_gatt_service_s *svc = l2->data;
+
+                       for (l3 = svc->characteristics; l3 != NULL; l3 = l3->next) {
+                               bt_gatt_characteristic_s *chr = l3->data;
+
+                               if (chr && chr->handle == handle) {
+                                       if (chr->notified_cb) {
+                                               *user_data = chr->notified_user_data;
+                                               *char_handle =  (bt_gatt_h*) chr;
+                                               *server = serv;
+                                               return chr->notified_cb;
+                                       } else
+                                               return NULL;
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+#endif
 
 static void __bt_free_bt_device_connection_info_s(bt_device_connection_info_s *conn_info)
 {
@@ -969,6 +1155,19 @@ void _bt_hid_event_proxy(int event, hid_event_param_t *param, void *user_data)
        new_param.user_data = param->user_data;
        __bt_event_proxy(event, &new_param, user_data);
 }
+
+#ifndef GATT_DIRECT
+void _bt_gatt_server_event_proxy(int event, gatt_server_event_param_t *param, void *user_data)
+{
+       bluetooth_event_param_t new_param;
+       new_param.event = param->event;
+       new_param.param_data = param->param_data;
+       new_param.result = param->result;
+       new_param.user_data = NULL;
+       __bt_event_proxy(event, &new_param, user_data);
+}
+#endif
+
 /* LCOV_EXCL_STOP */
 
 static bool __bt_need_to_handle(int event)
@@ -1992,6 +2191,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                break;
        }
        case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED: {
+#ifdef GATT_DIRECT
                bt_gatt_read_req_t *read_req = param->param_data;
                bt_gatt_server_read_value_requested_cb cb;
                void *user_data = NULL;
@@ -2010,9 +2210,43 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                cb(read_req->address, read_req->req_id, read_req->service_handle,
                                        gatt_handle, read_req->offset,
                                        user_data);
+#else
+               BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED");
+                bluetooth_gatt_server_read_requested_info_t *read_req = (bluetooth_gatt_server_read_requested_info_t *)(param->param_data);
+
+                bt_gatt_server_read_value_requested_cb cb_read;
+                void *user_data_read = NULL;
+                bt_gatt_h gatt_handle = NULL;
+                bt_gatt_server_h serv = NULL;
+                cb_read = __bt_gatt_attribute_get_read_cb(read_req->attribute_handle,
+                                              &serv, &gatt_handle, &user_data_read);
+
+                /* Copy data */
+                _bt_convert_address_to_string(&device_addr, &read_req->device_address);
+
+                BT_INFO("GATT Server Read Req: Addr      [%s]", device_addr);
+                BT_INFO("GATT Server Read Req: Att handle[%d]", read_req->attribute_handle);
+                BT_INFO("GATT Server Read Req: Conn ID   [%d]", read_req->connection_id);
+                BT_INFO("GATT Server Read Req: Trans ID  [%d]", read_req->request_id);
+                BT_INFO("GATT Server Read Req: Offset    [%d]", read_req->offset);
+                BT_INFO("GATT Server Read Req: Is Long   [%d]", read_req->is_long);
+
+                if (cb_read == NULL) {
+                        BT_INFO("GATT Server: App has not set the Read requested callback..for the current handle");
+                        bt_gatt_server_send_response(read_req->request_id, BT_GATT_REQUEST_TYPE_READ, 0, BLUETOOTH_ERROR_INTERNAL, NULL, 0);
+                        BT_INFO("GATT Server: Internal response sent for Read Request");
+                        return;
+                }
+
+                cb_read(device_addr, read_req->request_id, serv, gatt_handle, read_req->offset, user_data_read);
+
+                if (device_addr != NULL)
+                        free(device_addr);
+#endif
                break;
        }
        case BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED: {
+#ifdef GATT_DIRECT
                bt_gatt_value_change_t *value_change = param->param_data;
                bt_gatt_server_write_value_requested_cb cb;
                void *user_data = NULL;
@@ -2022,6 +2256,8 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
 
                BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGE");
                if (cb == NULL) {
+                       if (value_change->response_needed == FALSE)
+                               return;
                        bluetooth_gatt_send_response(value_change->req_id,
                                                                BLUETOOTH_GATT_ATT_REQUEST_TYPE_WRITE,
                                                                BLUETOOTH_ERROR_INTERNAL, 0, NULL, 0);
@@ -2029,11 +2265,57 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                }
 
                cb(value_change->address, value_change->req_id, value_change->service_handle,
-                                       gatt_handle, value_change->offset,
+                                       gatt_handle, value_change->offset, value_change->response_needed,
                                        (char *)value_change->att_value, value_change->val_len, user_data);
+#else
+               BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_WRITE_REQUESTED");
+                bluetooth_gatt_server_write_requested_info_t *write_req = (bluetooth_gatt_server_write_requested_info_t *)(param->param_data);
+                char *val = g_malloc0(write_req->length);
+                memcpy(val, write_req->data.data, write_req->length);
+
+                bt_gatt_server_write_value_requested_cb cb_wr;
+                void *user_data_write = NULL;
+                bt_gatt_h gatt_handle = NULL;
+                bt_gatt_h server = NULL;
+                cb_wr = __bt_gatt_attribute_get_value_change_cb(write_req->attribute_handle,
+                                              &server, &gatt_handle, &user_data_write);
+                /* Copy data */
+                _bt_convert_address_to_string(&device_addr, &write_req->device_address);
+
+                BT_INFO("GATT Server Write Req: Address    [%s]", device_addr);
+                BT_INFO("GATT Server Write Req: Att handle [%d]", write_req->attribute_handle);
+                BT_INFO("GATT Server Write Req: Conn ID    [%d]", write_req->connection_id);
+                BT_INFO("GATT Server Write Req: Trans ID   [%d]", write_req->request_id);
+                BT_INFO("GATT Server Write Req: Offset     [%d]", write_req->offset);
+                BT_INFO("GATT Server Write Req: Length     [%d]", write_req->length);
+                BT_INFO("GATT Server Write Req: Need Resp  [%d]", write_req->need_resp);
+
+                if (cb_wr == NULL) {
+                        BT_INFO("GATT Server: App has not set the Write requested callback..for the current handle");
+                        if (write_req->need_resp) {
+                                BT_INFO("GATT Server: Send Response to Remote GATT client");
+                                bt_gatt_server_send_response(write_req->request_id, BT_GATT_REQUEST_TYPE_WRITE, 0, BLUETOOTH_ERROR_INTERNAL, NULL, 0);
+                                BT_INFO("GATT Server: Internal response sent for Write Request");
+                        }
+                        return;
+                }
+
+                cb_wr(device_addr, write_req->request_id, server, gatt_handle,
+                               write_req->need_resp, write_req->offset,
+                               val, write_req->length, user_data_write);
+
+                /* Free Data */
+                if (val != NULL) {
+                        g_free(val);
+                }
+
+                if (device_addr != NULL)
+                        free(device_addr);
+#endif
                break;
        }
        case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED: {
+#ifdef GATT_DIRECT
                bt_gatt_char_notify_change_t *value_change = param->param_data;
                bt_gatt_server_characteristic_notification_state_changed_cb cb;
                void *user_data = NULL;
@@ -2047,9 +2329,28 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
 
                cb(value_change->att_notify, value_change->service_handle,
                                gatt_handle, user_data);
+#else
+               BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED");
+                bluetooth_gatt_server_notification_changed_t *notif_info = (bluetooth_gatt_server_notification_changed_t*)(param->param_data);
+               bt_gatt_server_characteristic_notification_state_changed_cb cb;
+
+                bt_gatt_server_h server_handle = NULL;
+                bt_gatt_h char_handle = NULL;
+
+                void *user_data_cfm = NULL;
+
+                cb = __bt_gatt_attribute_get_notification_change_cb(&server_handle,
+                                                notif_info->handle, &char_handle, &user_data_cfm);
+
+                if (cb == NULL)
+                        return;
+
+                cb(notif_info->notification, server_handle, char_handle, user_data_cfm);
+#endif
                break;
        }
        case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED: {
+#ifdef GATT_DIRECT
                bt_gatt_indicate_confirm_t *confrim_status = param->param_data;
                bt_gatt_server_notification_sent_cb cb;
                void *user_data = NULL;
@@ -2063,7 +2364,32 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                cb(_bt_get_error_code(param->result), confrim_status->address,
                                confrim_status->service_handle,
                                confrim_status->att_handle, confrim_status->complete, user_data);
+#else
+               BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_COMPLETED");
+                bluetooth_gatt_server_indicate_confirmed_info_t *cfm_info = (bluetooth_gatt_server_indicate_confirmed_info_t*)(param->param_data);
+                bt_gatt_server_notification_sent_cb cb;
+
+                bt_gatt_server_h server_handle = NULL;
+                bt_gatt_h char_handle = NULL;
+
+                void *user_data_cfm = NULL;
+
+                cb = __bt_gatt_attribute_get_notification_completed_cb(&server_handle,
+                                                cfm_info->handle, &char_handle, &user_data_cfm);
 
+                if (cb == NULL)
+                        return;
+
+                /* Copy data */
+                _bt_convert_address_to_string(&device_addr, &cfm_info->device_address);
+
+                cb(_bt_get_error_code(param->result), device_addr,
+                                server_handle, char_handle, cfm_info->completed, user_data_cfm);
+                /* Free Data */
+                if (device_addr != NULL)
+                        free(device_addr);
+
+#endif
                break;
        }
 #ifdef TIZEN_FEATURE_ENABLE_LEGACY_GATT_CLIENT
@@ -2111,7 +2437,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
                                                /* TODO : Fix build error temporary */
                                                if (chr->write_value_requested_cb)
                                                        chr->write_value_requested_cb(NULL, 0, (bt_gatt_server_h)serv, (bt_gatt_h)chr,
-                                                                                       0, (char*)char_val->char_value, char_val->val_len,
+                                                                                       0, TRUE, (char*)char_val->char_value, char_val->val_len,
                                                                                        chr->write_value_requested_user_data);
                                        }
                                }
index 315f8369793da6ce85964daf138f8b5e18163798..800eb4c501d5823569962740b75cad3459e3d574 100644 (file)
@@ -792,7 +792,7 @@ int bt_device_get_att_mtu(const char *remote_address, unsigned int *mtu)
        }
 
        *mtu = mtu_value;
-
+       BT_INFO("Got MTU: Remote address [%s] MTU Size [%u]", remote_address, mtu_value);
        return ret;
 
 }
index f790f01fbcf9eaebf53ce3a720a2ab5fc7b0d66c..3ff0add053a8ad272b8aafb1feea66ab7cd491aa 100644 (file)
 #include "bluetooth_internal.h"
 #include "bluetooth_type_internal.h"
 
+#ifndef GATT_DIRECT
+#include "bluetooth-gatt-server-api.h"
+int instance_id;
+#endif
+
 #define BT_ADDR_STR_LEN                17
 
 static GSList *gatt_client_list = NULL;
@@ -902,10 +907,20 @@ static void __bt_gatt_free_service(bt_gatt_h gatt_handle)
        g_slist_free_full(svc->characteristics, __bt_gatt_free_characteristic);
 
        if (svc->role == BT_GATT_ROLE_SERVER) {
+#ifdef GATT_DIRECT
                ret = _bt_get_error_code(bluetooth_gatt_unregister_service(svc->path));
                if (ret != BT_ERROR_NONE)
                        BT_ERR("%s(0x%08x) : Failed to unregister service",
                                        _bt_convert_error_to_string(ret), ret);
+#else
+               BT_INFO("GATT Server Delete Service: service handle [%d] Inst ID [%d]", svc->handle, instance_id);
+               ret = _bt_get_error_code(bluetooth_gatt_server_delete_service(svc->handle, instance_id));
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("%s(0x%08x)",
+                                       _bt_convert_error_to_string(ret), ret);
+               }
+#endif
+
        }
 
        g_strfreev(svc->include_handles);
@@ -1296,6 +1311,11 @@ int bt_gatt_set_value(bt_gatt_h gatt_handle, const char *value,
        bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
        bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
 
+#ifndef GATT_DIRECT
+       int k;
+       bluetooth_gatt_server_update_value_t param;
+#endif
+
        BT_CHECK_GATT_SUPPORT();
        BT_CHECK_INIT_STATUS();
 
@@ -1313,6 +1333,7 @@ int bt_gatt_set_value(bt_gatt_h gatt_handle, const char *value,
                return BT_ERROR_INVALID_PARAMETER;
        }
 
+#ifdef GATT_DIRECT
        if (handle->role == BT_GATT_ROLE_SERVER && handle->path) {
                ret = _bt_get_error_code(bluetooth_gatt_update_characteristic(handle->path,
                                                        value, value_length));
@@ -1321,7 +1342,26 @@ int bt_gatt_set_value(bt_gatt_h gatt_handle, const char *value,
                        return ret;
                }
        }
+#else
+       if (handle->role == BT_GATT_ROLE_SERVER && handle->handle) {
+
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_update_value_t));
+               /* DEBUG */
+               for(k=0; k < value_length; k++) {
+                       BT_DBG("New Value[%d] = [0x%x]", k, value[k]);
+               }
+               param.length = value_length;
+               memcpy(&param.data.data[0], value, value_length);
 
+               param.attribute_handle = handle->handle;
+               ret = _bt_get_error_code(bluetooth_gatt_server_update_characteristic(instance_id,
+                                       &param));
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+                       return ret;
+               }
+       }
+#endif
        g_free(*val);
        *val = NULL;
        if (value_length > 0)
@@ -1344,6 +1384,10 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
        bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
        bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
 
+#ifndef GATT_DIRECT
+        bluetooth_gatt_server_update_value_t param;
+#endif
+
        BT_CHECK_GATT_SUPPORT();
        BT_CHECK_INIT_STATUS();
 
@@ -1441,8 +1485,20 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
        }
 
        if (handle->role == BT_GATT_ROLE_SERVER && handle->path) {
+
+#ifdef GATT_DIRECT
                ret = _bt_get_error_code(bluetooth_gatt_update_characteristic(handle->path,
                                                        *val, *val_len));
+#else
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_update_value_t));
+                param.length = *val_len;
+                memcpy(&param.data.data[0], *val, *val_len);
+
+                param.attribute_handle = handle->handle;
+                ret = _bt_get_error_code(bluetooth_gatt_server_update_characteristic(instance_id,
+                                        &param));
+
+#endif
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
                        return ret;
@@ -1467,6 +1523,10 @@ int bt_gatt_set_float_value(bt_gatt_h gatt_handle, bt_data_type_float_e type,
        bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
        bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
 
+#ifndef GATT_DIRECT
+        bluetooth_gatt_server_update_value_t param;
+#endif
+
        BT_CHECK_GATT_SUPPORT();
        BT_CHECK_INIT_STATUS();
 
@@ -1547,8 +1607,19 @@ int bt_gatt_set_float_value(bt_gatt_h gatt_handle, bt_data_type_float_e type,
        }
 
        if (handle->role == BT_GATT_ROLE_SERVER && handle->path) {
+
+#ifdef GATT_DIRECT
                ret = _bt_get_error_code(bluetooth_gatt_update_characteristic(handle->path,
                                                        *val, *val_len));
+#else
+               memset(&param, 0x00, sizeof(bluetooth_gatt_server_update_value_t));
+                param.length = *val_len;
+                memcpy(&param.data.data[0], *val, *val_len);
+
+                param.attribute_handle = handle->handle;
+                ret = _bt_get_error_code(bluetooth_gatt_server_update_characteristic(instance_id,
+                                        &param));
+#endif
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
                        return ret;
@@ -1666,10 +1737,15 @@ bt_gatt_service_s* __bt_gatt_service_create(const char *uuid,
                return NULL;
 
        svc->type = BT_GATT_TYPE_SERVICE;
+#ifdef GATT_DIRECT
        if (strlen(uuid) == 8)
                svc->uuid = _bt_convert_uuid_to_uuid128(uuid);
        else
                svc->uuid = strdup(uuid);
+#else
+       svc->uuid = _bt_convert_uuid_to_uuid128(uuid);
+
+#endif
        if (svc->uuid == NULL) {
                g_free(svc);
                return NULL;
@@ -1701,7 +1777,10 @@ int bt_gatt_service_create(const char *uuid, bt_gatt_service_type_e type,
                return BT_ERROR_OUT_OF_MEMORY;
        svc->role = BT_GATT_ROLE_SERVER;
        svc->is_included_service = false;
-
+#ifndef GATT_DIRECT
+       BT_INFO("Current handle count of service [%d]", svc->numhandles);
+       svc->numhandles = 1; /* Initalize numhandles to 1 */
+#endif
        *service = (bt_gatt_h)svc;
 
        return BT_ERROR_NONE;
@@ -1725,7 +1804,10 @@ int bt_gatt_service_add_characteristic(bt_gatt_h service,
 
        svc->characteristics = g_slist_append(svc->characteristics, chr);
        chr->parent = (void *)service;
-
+#ifndef GATT_DIRECT
+       BT_INFO("Current handle count of service [%d]", svc->numhandles);
+        svc->numhandles += 2;
+#endif
        return BT_ERROR_NONE;
 }
 
@@ -1748,6 +1830,10 @@ int bt_gatt_service_add_included_service(bt_gatt_h service,
        svc->included_services = g_slist_append(svc->included_services,
                                                        included_svc);
        included_svc->parent = (void *)service;
+#ifndef GATT_DIRECT
+       BT_INFO("Current handle count of service [%d]", svc->numhandles);
+        svc->numhandles = 1; /* Initalize numhandles to 1 */
+#endif
 
        return BT_ERROR_NONE;
 }
@@ -1964,10 +2050,14 @@ int bt_gatt_characteristic_create(const char *uuid, int permissions,
 
        chr->type = BT_GATT_TYPE_CHARACTERISTIC;
        chr->role = BT_GATT_ROLE_SERVER;
+#ifdef GATT_DIRECT
        if (strlen(uuid) == 8)
                chr->uuid = _bt_convert_uuid_to_uuid128(uuid);
        else
                chr->uuid = g_strdup(uuid);
+#else
+       chr->uuid = _bt_convert_uuid_to_uuid128(uuid);
+#endif
        if (chr->uuid == NULL) {
                ret = BT_ERROR_OUT_OF_MEMORY;
                goto fail;
@@ -2000,6 +2090,9 @@ int bt_gatt_characteristic_add_descriptor(bt_gatt_h characteristic,
                                          bt_gatt_h descriptor)
 {
        bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)characteristic;
+#ifndef GATT_DIRECT
+       bt_gatt_service_s *svc = (bt_gatt_service_s *)chr->parent;
+#endif
        bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)descriptor;
 
        BT_CHECK_GATT_SUPPORT();
@@ -2021,6 +2114,10 @@ int bt_gatt_characteristic_add_descriptor(bt_gatt_h characteristic,
 
        chr->descriptors = g_slist_append(chr->descriptors, desc);
        desc->parent = (void *)characteristic;
+#ifndef GATT_DIRECT
+       BT_INFO("Current handle count of service [%d]", svc->numhandles);
+        svc->numhandles += 1; /* Initalize numhandles to 1 */
+#endif
 
        return BT_ERROR_NONE;
 }
@@ -2243,10 +2340,14 @@ int bt_gatt_descriptor_create(const char *uuid, int permissions,
 
        desc->type = BT_GATT_TYPE_DESCRIPTOR;
        desc->role = BT_GATT_ROLE_SERVER;
+#ifdef GATT_DIRECT
        if (strlen(uuid) == 8)
                desc->uuid = _bt_convert_uuid_to_uuid128(uuid);
        else
                desc->uuid = g_strdup(uuid);
+#else
+               desc->uuid = _bt_convert_uuid_to_uuid128(uuid);
+#endif
        if (desc->uuid == NULL) {
                ret = BT_ERROR_OUT_OF_MEMORY;
                goto fail;
@@ -2303,7 +2404,11 @@ int bt_gatt_server_initialize(void)
        }
 
        if (!is_gatt_server_initialized) {
+#ifndef GATT_DIRECT
+               ret = _bt_get_error_code(bluetooth_gatt_server_init(&instance_id, _bt_gatt_server_event_proxy, NULL));
+#else
                ret = _bt_get_error_code(bluetooth_gatt_init());
+#endif
 
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)",
@@ -2338,14 +2443,34 @@ int bt_gatt_server_deinitialize(void)
                g_slist_free(gatt_server_list);
                gatt_server_list = NULL;
 
+#ifndef GATT_DIRECT
+               ret = _bt_get_error_code(bluetooth_gatt_deinit());
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("%s(0x%08x)",
+                               _bt_convert_error_to_string(ret), ret);
+                       return BT_ERROR_OPERATION_FAILED;
+               }
+
+               ret = _bt_get_error_code(bluetooth_gatt_server_unregister(instance_id));
+
+               if (ret != BT_ERROR_NONE) {
+                       BT_ERR("%s(0x%08x)",
+                               _bt_convert_error_to_string(ret), ret);
+                       return BT_ERROR_OPERATION_FAILED;
+               }
+#else
                ret = _bt_get_error_code(bluetooth_gatt_deinit());
 
+#endif
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)",
                                _bt_convert_error_to_string(ret), ret);
                        return BT_ERROR_OPERATION_FAILED;
                }
 
+#ifndef GATT_DIRECT
+               instance_id = -1;
+#endif
                is_gatt_server_initialized = false;
                is_gatt_server_started = false;
                return BT_ERROR_NONE;
@@ -2375,6 +2500,7 @@ int bt_gatt_server_create(bt_gatt_server_h *server)
 
        *server = (bt_gatt_server_h)serv;
 
+       BT_INFO("Creating a GATT Server");
        gatt_server_list = g_slist_append(gatt_server_list, serv);
 
        return BT_ERROR_NONE;
@@ -2446,6 +2572,9 @@ int bt_gatt_server_set_characteristic_notification_state_change_cb(bt_gatt_h gat
 int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
 {
        int ret = BT_ERROR_NONE;
+#ifndef GATT_DIRECT
+       bluetooth_gatt_server_attribute_params_t param;
+#endif
        bt_gatt_server_s *serv = (bt_gatt_server_s *)server;
        bt_gatt_service_s *svc = (bt_gatt_service_s *)service;
        GSList *char_l;
@@ -2465,9 +2594,15 @@ int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
                BT_ERR("Already Server started");
                return BT_ERROR_OPERATION_FAILED;
        }
-
+#ifndef GATT_DIRECT
+       BT_INFO("Service number of total handles [%d]", svc->numhandles);
+       ret = _bt_get_error_code(bluetooth_gatt_server_add_service(svc->uuid, svc->type,
+                               svc->numhandles, instance_id, &svc->handle));
+       BT_INFO("Service added handle [%d]", svc->handle);
+#else
        ret = _bt_get_error_code(bluetooth_gatt_add_service(svc->uuid,
-                                                       &svc->path));
+                               &svc->path));
+#endif
        if (ret != BT_ERROR_NONE) {
                BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
                return ret;
@@ -2477,65 +2612,98 @@ int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
                GSList *desc_l;
                bt_gatt_characteristic_s *chr = char_l->data;
 
+#ifndef GATT_DIRECT
+               /* Add Characteristic to GATT database */
+               memset(&param, 0x00, sizeof(param));
+               param.permissions = chr->permissions;
+               param.properties = chr->properties;
+               param.service_handle = svc->handle;
+               param.instance_id = instance_id;
+               BT_INFO("GATT Server Add Char: UUID [%s] permission [%d] properties [%d] service handle [%d] Inst ID [%d]",
+                               chr->uuid, chr->permissions, chr->properties, svc->handle, instance_id);
+               ret = _bt_get_error_code(bluetooth_gatt_server_add_new_characteristic(chr->uuid, &param, &chr->handle));
+               BT_INFO("Char added handle [%d]", chr->handle);
+#else
                ret = _bt_get_error_code(bluetooth_gatt_add_new_characteristic(
                                        svc->path, chr->uuid,
                                        (bt_gatt_permission_t)chr->permissions,
                                        (bt_gatt_characteristic_property_t)chr->properties,
                                        &chr->path));
+#endif
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)",
-                               _bt_convert_error_to_string(ret), ret);
+                                       _bt_convert_error_to_string(ret), ret);
                        goto fail;
                }
 
+               /* Only in platform */
+#ifdef GATT_DIRECT
                ret = _bt_get_error_code(bluetooth_gatt_set_characteristic_value(chr->path,
                                        chr->value, chr->value_length));
 
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)",
-                               _bt_convert_error_to_string(ret), ret);
+                                       _bt_convert_error_to_string(ret), ret);
                        goto fail;
                }
-
+#endif
                for (desc_l = chr->descriptors; desc_l; desc_l = g_slist_next(desc_l)) {
                        bt_gatt_descriptor_s *desc = desc_l->data;
 
+#ifndef GATT_DIRECT
+                       /* Add descriptor to GATT database */
+                       BT_INFO("GATT Server Add Descriptor: UUID [%s] permission [%d] service handle [%d] Inst ID [%d]",
+                                       desc->uuid, desc->permissions, svc->handle, instance_id);
+                       ret = _bt_get_error_code(bluetooth_gatt_server_add_descriptor(desc->uuid, (bt_gatt_permission_t)desc->permissions,
+                                               svc->handle, instance_id, &desc->handle));
+                       BT_INFO("Descriptor added handle [%d]", desc->handle);
+#else
                        ret = _bt_get_error_code(bluetooth_gatt_add_descriptor(
-                                                       chr->path, desc->uuid,
-                                                       (bt_gatt_permission_t)desc->permissions,
-                                                       &desc->path));
-
+                                               chr->path, desc->uuid,
+                                               (bt_gatt_permission_t)desc->permissions,
+                                               &desc->path));
+#endif
                        if (ret != BT_ERROR_NONE) {
                                BT_ERR("%s(0x%08x)",
-                                       _bt_convert_error_to_string(ret), ret);
+                                               _bt_convert_error_to_string(ret), ret);
                                goto fail;
                        }
 
+                       /* Only in platform */
+#ifdef GATT_DIRECT
                        ret = _bt_get_error_code(bluetooth_gatt_set_descriptor_value(desc->path,
-                                       desc->value, desc->value_length));
+                                               desc->value, desc->value_length));
 
                        if (ret != BT_ERROR_NONE) {
                                BT_ERR("%s(0x%08x)",
-                                       _bt_convert_error_to_string(ret), ret);
+                                               _bt_convert_error_to_string(ret), ret);
                                goto fail;
                        }
+#endif
                }
        }
 
+       /* Only in platform */
+#ifdef GATT_DIRECT
        ret = _bt_get_error_code(bluetooth_gatt_register_service(svc->path));
 
        if (ret != BT_ERROR_NONE) {
                BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
                goto fail;
        }
+#endif
 
        serv->services = g_slist_append(serv->services, svc);
+       BT_INFO("@@Appending one service to the server, current service count [%d]", g_slist_length(serv->services));
        svc->parent = (void *)server;
-
        return ret;
 
 fail:
+       /* Only in platform */
+       BT_ERR("Registering Service failed!!!!!");
+#ifdef GATT_DIRECT
        bluetooth_gatt_unregister_service(svc->path);
+#endif
 
        return ret;
 }
@@ -2576,7 +2744,11 @@ int bt_gatt_server_unregister_all_services(bt_gatt_server_h server)
        g_slist_free_full(serv->services, __bt_gatt_free_service);
        serv->services = NULL;
 
+#ifdef GATT_DIRECT
        ret = bluetooth_gatt_unregister_application();
+#else
+       ret = bluetooth_gatt_server_unregister(instance_id);
+#endif
        is_gatt_server_started = false;
 
        return ret;
@@ -2585,14 +2757,41 @@ int bt_gatt_server_unregister_all_services(bt_gatt_server_h server)
 int bt_gatt_server_start(void)
 {
        int ret = BT_ERROR_NONE;
-
+#ifndef GATT_DIRECT
+       GSList *l;
+       GSList *l1;
+#endif
        BT_CHECK_GATT_SUPPORT();
        BT_CHECK_INIT_STATUS();
        BT_CHECK_GATT_SERVER_INIT_STATUS();
 
        if (!is_gatt_server_started) {
+#ifdef GATT_DIRECT
                ret = bluetooth_gatt_register_application();
+#else
+               /* Kick Start all services*/
+               BT_INFO("Total GATT Servers for this application [%d]", g_slist_length(gatt_server_list));
+               for (l = gatt_server_list; l; l = g_slist_next(l)) {
+                       bt_gatt_server_s *server = (bt_gatt_server_s *)l->data;
 
+                       BT_INFO("Total GATT Services for this current server(server) of this App [%d]", g_slist_length(server->services));
+
+                       for (l1 = server->services; l1; l1 = g_slist_next(l1)) {
+                               bt_gatt_service_s *service = (bt_gatt_service_s *)l1->data;
+                               BT_DBG("Service handle [%d] Service UUID [%s]", service->handle, service->uuid);
+                               /* Mark the service Registered */
+                               ret = _bt_get_error_code(bluetooth_gatt_server_start_service(service->handle, instance_id));
+
+                               if (ret != BT_ERROR_NONE) {
+                                       BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+                               }
+                       }
+               }
+
+               /* No need to RegisterApplication, when last service gets started, automatically
+                  application will be registered */
+               //ret = bluetooth_gatt_register_application();
+#endif
                if (ret != BT_ERROR_NONE) {
                        BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
                        return ret;
@@ -2622,10 +2821,40 @@ int bt_gatt_server_send_response(int request_id, bt_gatt_att_request_type_e requ
                        return BT_ERROR_INVALID_PARAMETER;
        }
 
+#ifdef GATT_DIRECT
        ret = _bt_get_error_code(bluetooth_gatt_send_response(request_id,
                                        request_type, resp_status,
                                        offset, value, value_length));
-
+#else
+       bluetooth_gatt_att_data_t resp;
+        bluetooth_gatt_server_response_params_t param;
+
+       memset(&resp,  0x00, sizeof(resp));
+       memset(&param, 0x00, sizeof(param));
+
+       /* Copy response data */
+       resp.length = value_length;
+       resp.offset = offset;
+       memcpy(&resp.data[0], value, value_length);
+
+       /* Copy Response parameters */
+       param.req_type = request_type;
+       param.request_id = request_id;
+       param.response_status = resp_status;
+       param.auth_req = 0;   /* Default value set to 0 as Platform API does not provide this option */
+
+       BT_INFO("GATT Server Send Response: Response type [%d]", request_type);
+       BT_INFO("Req ID [%d] data_len [%d] offset [%d] Resp Status [%d]",
+                        request_id, value_length, offset, resp_status);
+
+        ret = _bt_get_error_code(bluetooth_gatt_server_send_response(&param, &resp));
+
+        if (ret != BT_ERROR_NONE) {
+                BT_ERR("%s(0x%08x)",
+                                _bt_convert_error_to_string(ret), ret);
+                return BT_ERROR_OPERATION_FAILED;
+        }
+#endif
        if (ret != BT_ERROR_NONE)
                BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
 
@@ -2641,6 +2870,13 @@ int bt_gatt_server_notify_characteristic_changed_value(bt_gatt_h characteristic,
        bluetooth_device_address_t addr_hex = { {0,} };
        int ret = BT_ERROR_NONE;
 
+#ifndef GATT_DIRECT
+       int attribute_handle;
+       bluetooth_gatt_att_data_t indication;
+       bluetooth_gatt_server_indication_params_t param;
+       int k;
+#endif
+
        BT_CHECK_GATT_SUPPORT();
        BT_CHECK_INIT_STATUS();
        BT_CHECK_GATT_SERVER_INIT_STATUS();
@@ -2649,27 +2885,85 @@ int bt_gatt_server_notify_characteristic_changed_value(bt_gatt_h characteristic,
 
        _bt_convert_address_to_hex(&addr_hex, device_address);
 
+#ifdef GATT_DIRECT
        if (chr->value_length > 0 && chr->value) {
                if (handle->role == BT_GATT_ROLE_SERVER && handle->path) {
                        ret = bluetooth_gatt_server_set_notification(handle->path,
-                                                               &addr_hex);
+                                       &addr_hex);
                        if (ret != BT_ERROR_NONE) {
                                BT_ERR("%s(0x%08x)",
-                                       _bt_convert_error_to_string(ret), ret);
+                                               _bt_convert_error_to_string(ret), ret);
                                return ret;
                        }
                        ret = _bt_get_error_code(bluetooth_gatt_update_characteristic(
-                                                       handle->path,
-                                                       chr->value,
-                                                       chr->value_length));
+                                               handle->path,
+                                               chr->value,
+                                               chr->value_length));
                        if (ret != BT_ERROR_NONE) {
                                BT_ERR("%s(0x%08x)",
-                                       _bt_convert_error_to_string(ret), ret);
+                                               _bt_convert_error_to_string(ret), ret);
                                return ret;
                        }
                }
        }
 
+#else
+       if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
+               attribute_handle = chr->handle;
+       } else {
+               BT_ERR("Type is invalid(type:%d)", handle->type);
+               return BT_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!(chr->properties & BT_GATT_PROPERTY_INDICATE) &&
+                       !(chr->properties & BT_GATT_PROPERTY_NOTIFY)) {
+               BT_ERR("Characteristic [%d] does not have either Notifcation or Indicate property enabled", attribute_handle);
+               return BT_ERROR_INVALID_PARAMETER;
+       }
+
+       BT_INFO("GATT Server: Notify/Indicate char value changed to Remote GATT client");
+       if (!device_address)
+               BT_INFO("Indication to be Multicasted!");
+       else
+               BT_INFO("Indication to be Unicasted.. [%s]", device_address);
+
+       if (chr->value_length > 0 && chr->value) {
+               if (handle->role == BT_GATT_ROLE_SERVER) {
+
+                       /* DEBUG */
+                       for(k=0; k < chr->value_length; k++) {
+                               BT_DBG("Indication Data [%d] = [0x%x]", k, chr->value[k]);
+                       }
+                       /* Copy Indication data */
+                       indication.length = chr->value_length;
+                       indication.offset = 0; /* Default value */
+                       memcpy(&indication.data[0], chr->value, chr->value_length);
+
+                       /* Copy Indication parameters */
+                       param.atrribute_handle = attribute_handle;
+
+                       if (chr->properties & BT_GATT_PROPERTY_INDICATE) {
+                               BT_DBG("Characteritsic [%d]has Indicate Property", attribute_handle);
+                               param.need_confirmation = TRUE;
+                       } else {
+                               param.need_confirmation = FALSE;
+                               BT_DBG("Enable Notifcation for the characteristic [%d]",attribute_handle);
+                       }
+                       param.instance_id = instance_id;
+                       ret = _bt_get_error_code(bluetooth_gatt_server_send_indication(&addr_hex, &param, &indication));
+                       BT_INFO("Sent Indication to Remote GATT client: result [%d]", ret);
+
+                       if (ret != BT_ERROR_NONE) {
+                               BT_ERR("%s(0x%08x)",
+                                               _bt_convert_error_to_string(ret), ret);
+                               return BT_ERROR_OPERATION_FAILED;
+                       }
+               }
+       }
+
+       /* Save the Remote GATT client address to be used for notification later on */
+       memcpy(&chr->address.addr, &addr_hex.addr, BLUETOOTH_ADDRESS_LENGTH);
+#endif
        chr->notified_cb = callback;
        chr->notified_user_data = user_data;
 
index 559e33e51b9a58c8b9367f642f6456bb33654719..22422289108518ef07548f32f6b5bef26b6c7908 100644 (file)
@@ -2523,11 +2523,12 @@ void __bt_gatt_server_notification_sent_cb(int result,
 
 void __bt_gatt_server_write_value_requested_cb(const char *remote_address,
                                int request_id, bt_gatt_server_h server,
-                               bt_gatt_h gatt_handle, int offset,
+                               bt_gatt_h gatt_handle,  bool response_needed, int offset,
                                const char *value, int len, void *user_data)
 {
        int i, resp_status =  BT_ERROR_NONE;
        TC_PRT("remote_address : %s", remote_address);
+       TC_PRT("Response needed : %d", response_needed);
        TC_PRT("offset : %d", offset);
        TC_PRT("len [%d] : ", len);
        for (i = 0; i < len; i++)