summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Purwar <amit.purwar@samsung.com>2018-05-17 13:00:08 +0530
committerAmit Purwar <amit.purwar@samsung.com>2018-05-23 09:28:45 +0530
commite3b95eee9e7fe07140319d1485d6f04b9c18a970 (patch)
tree78c21eeced575bb57df33667177efe30b57affbf
parentb95261690f7ded61bf1bd576b235396095074b9b (diff)
downloadbluetooth-e3b95eee9e7fe07140319d1485d6f04b9c18a970.tar.gz
bluetooth-e3b95eee9e7fe07140319d1485d6f04b9c18a970.tar.bz2
bluetooth-e3b95eee9e7fe07140319d1485d6f04b9c18a970.zip
Change-Id: I2a424cc32498e54aa852d572523503123d59bbf0 Signed-off-by: Amit Purwar <amit.purwar@samsung.com>
-rw-r--r--include/bluetooth_private.h57
-rw-r--r--packaging/capi-network-bluetooth.spec2
-rw-r--r--src/bluetooth-common.c143
-rw-r--r--src/bluetooth-gatt.c1718
4 files changed, 1872 insertions, 48 deletions
diff --git a/include/bluetooth_private.h b/include/bluetooth_private.h
index 77e4136..518e5f5 100644
--- a/include/bluetooth_private.h
+++ b/include/bluetooth_private.h
@@ -32,6 +32,10 @@
#include <bluetooth-gatt-server-api.h>
#endif
+#ifdef TIZEN_GATT_CLIENT
+#include <bluetooth-gatt-client-api.h>
+#endif
+
#include "bluetooth.h"
#include "bluetooth_internal.h"
@@ -328,6 +332,9 @@ typedef struct {
bt_gatt_client_service_changed_cb service_changed_cb;
void *service_changed_user_data;
void *att_mtu_changed_user_data;
+#ifdef TIZEN_GATT_CLIENT
+ int client_id;
+#endif
} bt_gatt_client_s;
typedef struct {
@@ -358,6 +365,11 @@ typedef struct {
GSList *included_services;
GSList *characteristics;
+#ifdef TIZEN_GATT_CLIENT
+ int instance_id; /* Instance ID of the service object */
+ bt_gatt_handle_info_t svc_include_handles;
+ bt_gatt_handle_info_t charc_handles;
+#endif
char **include_handles;
char **char_handles;
} bt_gatt_service_s;
@@ -378,6 +390,10 @@ typedef struct {
GSList *descriptors;
+#ifdef TIZEN_GATT_CLIENT
+ int instance_id; /* Instance ID of the characteristic object */
+ bt_gatt_handle_info_t descriptor_handles;
+#endif
char **desc_handles;
bt_gatt_client_characteristic_value_changed_cb value_changed_cb;
@@ -397,12 +413,13 @@ typedef struct {
int value_length;
char *value;
-
+#ifdef TIZEN_GATT_CLIENT
bt_gatt_client_request_completed_cb read_cb;
void *read_user_data;
bt_gatt_client_request_completed_cb write_cb;
void *write_user_data;
+#endif
} bt_gatt_characteristic_s;
typedef struct {
@@ -414,6 +431,9 @@ typedef struct {
#ifdef TIZEN_FEATURE_GATT_RELAY
int handle;
#endif
+#ifdef TIZEN_GATT_CLIENT
+ int instance_id; /* Instance ID of the descriptor object */
+#endif
int permissions;
bt_gatt_server_write_value_requested_cb write_value_requested_cb;
@@ -424,12 +444,13 @@ typedef struct {
int value_length;
char *value;
-
+#ifdef TIZEN_GATT_CLIENT
bt_gatt_client_request_completed_cb read_cb;
void *read_user_data;
bt_gatt_client_request_completed_cb write_cb;
void *write_user_data;
+#endif
} bt_gatt_descriptor_s;
typedef struct {
@@ -497,6 +518,23 @@ typedef void (*bt_rssi_strength_cb)(char *bt_address,
typedef void (*_bt_gatt_client_value_changed_cb)(char *char_path,
unsigned char *value, int value_length, void *user_data);
+#ifdef TIZEN_GATT_CLIENT
+typedef void (*_bt_gatt_client_val_changed_cb)(unsigned char *uuid, char *remote_address,
+ char *value, int value_length, void *user_data);
+
+void _bt_handle_gatt_client_char_read_completed_event(int result,
+ void *resp);
+
+void _bt_handle_gatt_client_desc_read_completed_event(int result,
+ void *resp);
+
+void _bt_handle_gatt_client_char_write_completed_event(int result,
+ void *resp);
+
+void _bt_handle_gatt_client_desc_write_completed_event(int result,
+ void *resp);
+#endif
+
/**
* @internal
* @ingroup CAPI_NETWORK_BLUETOOTH_ADAPTER_MODULE
@@ -566,7 +604,7 @@ do { \
do { \
bool is_supported = false; \
if (!system_info_get_platform_bool(feature_name1, &is_supported)) { \
- if (is_supported == false) { \
+ if (is_supported == false) { \
LOGE("[%s] NOT_SUPPORTED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_SUPPORTED); \
return BT_ERROR_NOT_SUPPORTED; \
} \
@@ -574,7 +612,7 @@ do { \
LOGE("[%s] Fail to get the system feature: [%s]", __FUNCTION__, feature_name1); \
} \
if (!system_info_get_platform_bool(feature_name2, &is_supported)) { \
- if (is_supported == false) { \
+ if (is_supported == false) { \
LOGE("[%s] NOT_SUPPORTED(0x%08x)", __FUNCTION__, BT_ERROR_NOT_SUPPORTED); \
return BT_ERROR_NOT_SUPPORTED; \
} \
@@ -771,7 +809,12 @@ bt_gatt_client_h _bt_gatt_get_client(const char *remote_addr);
const GSList* _bt_gatt_get_server_list(void);
+#ifdef TIZEN_GATT_CLIENT
+bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client,
+ const char *uuid, int instance_id);
+#else
bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client, const char *path);
+#endif
int _bt_gatt_client_update_services(bt_gatt_client_h client);
@@ -790,6 +833,12 @@ void _bt_gatt_server_event_proxy(int event, gatt_server_event_param_t *param, vo
#endif
+#ifdef TIZEN_GATT_CLIENT
+void _bt_gatt_client_event_proxy(int event,
+ gatt_client_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.
diff --git a/packaging/capi-network-bluetooth.spec b/packaging/capi-network-bluetooth.spec
index ac6a66d..eb1d305 100644
--- a/packaging/capi-network-bluetooth.spec
+++ b/packaging/capi-network-bluetooth.spec
@@ -57,7 +57,7 @@ export LDFLAGS+=" -lgcov"
#export CXXFLAGS="$CXXFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT"
#export FFLAGS="$FFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT"
-export CFLAGS="$CFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT -DTIZEN_FEATURE_GATT_RELAY -DTIZEN_FEATURE_TCT_TMP_SUPPORT"
+export CFLAGS="$CFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT -DTIZEN_FEATURE_GATT_RELAY -DTIZEN_FEATURE_TCT_TMP_SUPPORT -DTIZEN_GATT_CLIENT"
export CXXFLAGS="$CXXFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT -DTIZEN_FEATURE_GATT_RELAY -DTIZEN_FEATURE_TCT_TMP_SUPPORT"
export FFLAGS="$FFLAGS -DTIZEN_FEATURE_AUDIO_HF_DISABLE -DTIZEN_FEATURE_OTP_SUPPORT -DTIZEN_FEATURE_GATT_RELAY -DTIZEN_FEATURE_TCT_TMP_SUPPORT"
diff --git a/src/bluetooth-common.c b/src/bluetooth-common.c
index 3200a89..30e3341 100644
--- a/src/bluetooth-common.c
+++ b/src/bluetooth-common.c
@@ -81,7 +81,6 @@ int bt_initialize(void)
int bt_deinitialize(void)
{
-
BT_CHECK_SUPPORTED_FEATURE(BT_FEATURE_COMMON);
BT_CHECK_INIT_STATUS();
if (bluetooth_unregister_callback() != BLUETOOTH_ERROR_NONE) {
@@ -1079,6 +1078,20 @@ 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);
}
+
+#ifdef TIZEN_GATT_CLIENT
+void _bt_gatt_client_event_proxy(int event,
+ gatt_client_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)
@@ -1088,8 +1101,15 @@ static bool __bt_need_to_handle(int event)
switch (event) {
case BLUETOOTH_EVENT_ADVERTISING_STARTED:
case BLUETOOTH_EVENT_ADVERTISING_STOPPED:
+#ifdef TIZEN_GATT_CLIENT
+ case BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED:
+ case BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_CONNECTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED:
+#else
case BLUETOOTH_EVENT_GATT_CONNECTED:
case BLUETOOTH_EVENT_GATT_DISCONNECTED:
+#endif
case BLUETOOTH_EVENT_GATT_SERVER_VALUE_CHANGED:
case BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED:
case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED:
@@ -2032,6 +2052,94 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
((bt_hid_device_data_received_cb)bt_event_slot_container[event_index].callback)
((bt_hid_device_received_data_s *)(param->param_data), bt_event_slot_container[event_index].user_data);
break;
+#ifdef TIZEN_GATT_CLIENT
+ /* Local is GATT server */
+ case BLUETOOTH_EVENT_GATT_SERVER_CONNECTED: {
+ bt_gatt_connection_state_changed_cb cb = NULL;
+ BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_CONNECTED");
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ BT_INFO("GATT Server Connected address[%s]", device_addr);
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), TRUE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
+ break;
+ }
+ case BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED: {
+ bt_gatt_connection_state_changed_cb cb = NULL;
+ BT_INFO("BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED");
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), FALSE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
+ break;
+ }
+ /* Local is GATT client */
+ case BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED: {
+ bt_gatt_client_s *client_s;
+ bt_gatt_connection_state_changed_cb cb = NULL;
+ BT_INFO("BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED");
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ BT_INFO("GATT Connected address[%s] result [%d]", device_addr,
+ _bt_get_error_code(param->result));
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+
+ if (BT_ERROR_NONE == _bt_get_error_code(param->result)) {
+ if (client_s && !client_s->services_discovered) {
+ BT_INFO("GATT Connected but services are not discovered yet, start browse client id [%d]",
+ client_s->client_id);
+ BT_INFO("GATT Client Connected address[%s]", device_addr);
+ if (client_s)
+ client_s->connected = true;
+ _bt_gatt_client_update_services(client_s);
+ }
+ }
+
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), TRUE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
+ break;
+ }
+ case BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED: {
+ bt_gatt_client_s *client_s;
+ bt_gatt_connection_state_changed_cb cb = NULL;
+ BT_INFO("BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED");
+ _bt_convert_address_to_string(&device_addr,
+ (bluetooth_device_address_t *)(param->param_data));
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ BT_INFO("GATT DisConnected address[%s] result [%d]", device_addr,
+ _bt_get_error_code(param->result));
+ if (client_s) {
+ BT_INFO("GATT CLient instance present for addr [%s] client ID [%d]",
+ client_s->remote_address, client_s->client_id);
+ client_s->connected = false;
+ /* Mark services not discovered */
+ client_s->services_discovered = false;
+ }
+ if (event_index >= 0)
+ cb = bt_event_slot_container[event_index].callback;
+ if (cb)
+ cb(_bt_get_error_code(param->result), FALSE, device_addr,
+ bt_event_slot_container[event_index].user_data);
+ g_free(device_addr);
+ device_addr = NULL;
+ break;
+ }
+#else
case BLUETOOTH_EVENT_GATT_CONNECTED: {
bt_gatt_client_s *client_s;
bt_gatt_connection_state_changed_cb cb = NULL;
@@ -2097,6 +2205,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
device_addr = NULL;
break;
}
+#endif
case BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED:
char_val = (bt_gatt_char_value_t *)(param->param_data);
@@ -2108,6 +2217,24 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
bt_event_slot_container[event_index].user_data);
break;
+#ifdef TIZEN_GATT_CLIENT
+ case BLUETOOTH_EVENT_GATT_READ_CHAR:
+ BT_INFO("BLUETOOTH_EVENT_GATT_READ_CHAR");
+ _bt_handle_gatt_client_char_read_completed_event(param->result, param->param_data);
+ break;
+ case BLUETOOTH_EVENT_GATT_WRITE_CHAR:
+ BT_INFO("BLUETOOTH_EVENT_GATT_WRITE_CHAR");
+ _bt_handle_gatt_client_char_write_completed_event(param->result, param->param_data);
+ break;
+ case BLUETOOTH_EVENT_GATT_READ_DESC:
+ BT_INFO("BLUETOOTH_EVENT_GATT_READ_DESC");
+ _bt_handle_gatt_client_desc_read_completed_event(param->result, param->param_data);
+ break;
+ case BLUETOOTH_EVENT_GATT_WRITE_DESC:
+ BT_INFO("BLUETOOTH_EVENT_GATT_WRITE_DESC");
+ _bt_handle_gatt_client_desc_write_completed_event(param->result, param->param_data);
+ break;
+#else
case BLUETOOTH_EVENT_GATT_READ_CHAR:
BT_INFO("BLUETOOTH_EVENT_GATT_READ_CHAR");
_handle_gatt_client_read_completed_event(param->result,
@@ -2128,6 +2255,7 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
_handle_gatt_client_write_completed_event(param->result,
param->param_data);
break;
+#endif
case BLUETOOTH_EVENT_GATT_SERVER_READ_REQUESTED: {
#ifdef TIZEN_FEATURE_GATT_RELAY
bluetooth_gatt_server_read_requested_info_t *read_req =
@@ -2434,9 +2562,12 @@ static void __bt_event_proxy(int event, bluetooth_event_param_t *param, void *us
BT_INFO("already added service : %s", svc->path);
break;
}
-
+#ifdef TIZEN_GATT_CLIENT
+ BT_INFO("TODO this task");
+#else
svc = _bt_gatt_client_add_service(client,
service_change->svc_path);
+#endif
if (svc == NULL) {
BT_ERR("_bt_gatt_client_add_service is failed");
break;
@@ -3343,9 +3474,17 @@ static int __bt_get_cb_index(int event)
case BLUETOOTH_EVENT_DEVICE_CONNECTED:
case BLUETOOTH_EVENT_DEVICE_DISCONNECTED:
return BT_EVENT_DEVICE_CONNECTION_STATUS;
+#ifdef TIZEN_GATT_CLIENT
+ case BLUETOOTH_EVENT_GATT_CLIENT_CONNECTED:
+ case BLUETOOTH_EVENT_GATT_CLIENT_DISCONNECTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_CONNECTED:
+ case BLUETOOTH_EVENT_GATT_SERVER_DISCONNECTED:
+ return BT_EVENT_GATT_CONNECTION_STATUS;
+#else
case BLUETOOTH_EVENT_GATT_CONNECTED:
case BLUETOOTH_EVENT_GATT_DISCONNECTED:
return BT_EVENT_GATT_CONNECTION_STATUS;
+#endif
case BLUETOOTH_EVENT_SERVICE_SEARCHED:
return BT_EVENT_SERVICE_SEARCHED;
case BLUETOOTH_EVENT_RFCOMM_DATA_RECEIVED:
diff --git a/src/bluetooth-gatt.c b/src/bluetooth-gatt.c
index 2b6313e..a698f47 100644
--- a/src/bluetooth-gatt.c
+++ b/src/bluetooth-gatt.c
@@ -30,10 +30,20 @@
int instance_id;
#endif
+#ifdef TIZEN_GATT_CLIENT
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <arpa/inet.h>
+#include "bluetooth-gatt-client-api.h"
+#endif
+
#define BT_ADDR_STR_LEN 17
static GSList *gatt_client_list = NULL;
+static GSList *gatt_handle_list = NULL;
+
static GSList *gatt_server_list = NULL;
static bool is_gatt_server_initialized = false;
static bool is_gatt_server_started = false;
@@ -70,6 +80,51 @@ static void __bt_gatt_free_service(bt_gatt_h gatt_handle);
} \
}
+#define BT_VALIDATE_GATT_HANDLE(h1) \
+{ \
+ GSList *l; \
+ bool valid = FALSE; \
+ for (l = gatt_handle_list; l; l = g_slist_next(l)) { \
+ bt_gatt_h h2 = (bt_gatt_h)l->data; \
+ if (h1 == h2) { \
+ BT_INFO("Handle matched [%p]", h2); \
+ valid = TRUE; break; \
+ } \
+ } \
+ if (valid == FALSE) { \
+ BT_ERR("App Handle [%p] did not match with any stored handles!!! Must be Invalid Handle!!", h1); \
+ return BT_ERROR_INVALID_PARAMETER; \
+ } \
+} \
+
+#ifdef TIZEN_GATT_CLIENT
+static void __bt_gatt_free_service(bt_gatt_h gatt_handle);
+
+void __bt_string_to_uuid_hex(const char *str, unsigned char *uuid)
+{
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
+
+ sscanf(str, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+ &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
+
+ uuid0 = htonl(uuid0);
+ uuid1 = htons(uuid1);
+ uuid2 = htons(uuid2);
+ uuid3 = htons(uuid3);
+ uuid4 = htonl(uuid4);
+ uuid5 = htons(uuid5);
+
+ memcpy(&(uuid[0]), &uuid0, 4);
+ memcpy(&(uuid[4]), &uuid1, 2);
+ memcpy(&(uuid[6]), &uuid2, 2);
+ memcpy(&(uuid[8]), &uuid3, 2);
+ memcpy(&(uuid[10]), &uuid4, 4);
+ memcpy(&(uuid[14]), &uuid5, 2);
+ return;
+}
+#endif
+
/* LCOV_EXCL_START */
static int __bt_check_gatt_server_init_status(void)
{
@@ -88,6 +143,7 @@ static int __get_gatt_handle_by_uuid(GSList *list, const char *uuid,
char *uuid128_a;
char *uuid128_b;
+ BT_INFO("UUID [%s]", uuid);
uuid128_a = _bt_convert_uuid_to_uuid128(uuid);
if (uuid128_a == NULL) {
BT_ERR("Wrong type of uuid : %s", uuid);
@@ -145,6 +201,75 @@ const GSList* _bt_gatt_get_server_list(void)
return gatt_server_list;
}
+static void __bt_gatt_client_handle_destroy(bt_gatt_h gatt_handle)
+{
+ bt_gatt_common_s *handle = (bt_gatt_common_s*)gatt_handle;
+
+ if (handle->type == BT_GATT_TYPE_SERVICE)
+ bt_gatt_service_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
+ bt_gatt_characteristic_destroy(gatt_handle);
+ else if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
+ bt_gatt_descriptor_destroy(gatt_handle);
+}
+
+#ifdef TIZEN_GATT_CLIENT
+bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client,
+ const char *uuid, int instance_id)
+{
+ int ret;
+ bt_gatt_client_s *client_s = (bt_gatt_client_s*)client;
+ bt_gatt_service_s *svc = NULL;
+ bt_gatt_service_property_t property;
+ bt_gatt_handle_property_t service;
+
+ if (client == NULL || uuid == NULL) {
+ BT_ERR("Invalid parameter");
+ return NULL;
+ }
+
+ memset(&property, 0x00, sizeof(bt_gatt_service_property_t));
+ memset(&service, 0x00, sizeof(bt_gatt_handle_property_t));
+
+ __bt_string_to_uuid_hex(uuid, service.uuid);
+ service.instance_id = instance_id;
+
+ BT_INFO("GATT client add service: get all properties of this service");
+ ret = bluetooth_gatt_client_get_service_property(client_s->remote_address,
+ &service, &property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_service_property is failed");
+ return NULL;
+ }
+
+ BT_INFO("Service properties are retrieved successfully, now create and add service object");
+ svc = __bt_gatt_service_create(property.uuid,
+ BT_GATT_SERVICE_TYPE_PRIMARY);
+ if (svc == NULL) {
+ BT_ERR("svc is NULL");
+ return NULL;
+ }
+ svc->role = BT_GATT_ROLE_CLIENT;
+ svc->instance_id = instance_id;
+ svc->parent = (void *)client_s;
+ svc->is_included_service = false;
+
+ /* Copy included service handles and charc handles in just created service object */
+ memcpy(&svc->svc_include_handles, &property.include_handles, sizeof(bt_gatt_handle_info_t));
+ BT_INFO("Total number of Included service handles [%d]", svc->svc_include_handles.count);
+ memcpy(&svc->charc_handles, &property.char_handle, sizeof(bt_gatt_handle_info_t));
+ BT_INFO("Total number of Characteristic handles [%d]", svc->charc_handles.count);
+
+ bluetooth_gatt_free_service_property(&property);
+
+ client_s->services = g_slist_append(client_s->services, svc);
+ BT_INFO("GATT service added , current count of Client services [%d]",
+ g_slist_length(client_s->services));
+
+ return svc;
+}
+#else
bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client, const char *path)
{
int ret;
@@ -189,7 +314,61 @@ bt_gatt_h _bt_gatt_client_add_service(bt_gatt_client_h client, const char *path)
return svc;
}
+#endif
+
+#ifdef TIZEN_GATT_CLIENT
+int _bt_gatt_client_update_services(bt_gatt_client_h client)
+{
+ bt_gatt_client_s *client_s = client;
+ bluetooth_device_address_t addr_hex = { {0, } };
+ bt_gatt_handle_info_t prim_svc;
+ int ret;
+ int i;
+
+ if (!client_s->connected) {
+ BT_INFO("Not connected");
+ return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
+ }
+
+ if (client_s->services_discovered) {
+ BT_INFO("Already discovered");
+ return BT_ERROR_ALREADY_DONE;
+ }
+
+ BT_INFO("Update services for remote GATT server [%s]",
+ client_s->remote_address);
+ _bt_convert_address_to_hex(&addr_hex, client_s->remote_address);
+
+ ret = bluetooth_gatt_client_get_primary_services(&addr_hex, &prim_svc);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_client_get_primary_services is failed");
+ return ret;
+ }
+ if (client_s->services)
+ g_slist_free_full(client_s->services, __bt_gatt_free_service);
+ client_s->services = NULL;
+
+ if (prim_svc.count == 0) {
+ BT_INFO("There is no service");
+ return BT_ERROR_NONE;
+ }
+
+ BT_INFO("Services discovered");
+ client_s->services_discovered = true;
+ for (i = 0; i < prim_svc.count; i++) {
+ BT_INFO("Service UUID[%d][%s] Instance ID[%d]",
+ i, prim_svc.uuids[i], prim_svc.inst_id[i]);
+ if (!_bt_gatt_client_add_service(client, prim_svc.uuids[i], prim_svc.inst_id[i])) {
+ BT_ERR("_bt_gatt_client_add_service is failed [%s]",
+ prim_svc.uuids[i]);
+ client_s->services_discovered = false;
+ }
+ }
+ return BT_ERROR_NONE;
+}
+#else
int _bt_gatt_client_update_services(bt_gatt_client_h client)
{
bt_gatt_client_s *client_s = client;
@@ -239,6 +418,7 @@ int _bt_gatt_client_update_services(bt_gatt_client_h client)
return BT_ERROR_NONE;
}
+#endif
int _bt_gatt_client_update_include_services(bt_gatt_h service)
{
@@ -296,6 +476,109 @@ next:
return BT_ERROR_NONE;
}
+#ifdef TIZEN_GATT_CLIENT
+int _bt_gatt_client_update_characteristics(bt_gatt_h service)
+{
+ bt_gatt_service_s *svc = service;
+ bt_gatt_client_s *client_s;
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t char_handle;
+ GSList *chr_list = NULL;
+ int i;
+
+ BT_INFO("+");
+ if (svc == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ if (svc->charc_handles.count == 0)
+ return BT_ERROR_NONE;
+
+ memset(&svc_handle, 0x00, sizeof(bt_gatt_handle_property_t));
+ memset(&char_handle, 0x00, sizeof(bt_gatt_handle_property_t));
+
+ client_s = (bt_gatt_client_s*)svc->parent;
+
+ __bt_string_to_uuid_hex(svc->uuid, svc_handle.uuid);
+ svc_handle.instance_id = svc->instance_id;
+
+ BT_INFO("Total number of charcs [%d]", svc->charc_handles.count);
+
+ for (i = 0; i < svc->charc_handles.count; i++) {
+ bt_gatt_characteristic_s *chr = NULL;
+ bt_gatt_char_property_t char_property;
+ int ret;
+
+ memset(&char_property, 0x00, sizeof(char_property));
+
+ __bt_string_to_uuid_hex(svc->charc_handles.uuids[i], char_handle.uuid);
+ char_handle.instance_id = svc->charc_handles.inst_id[i];
+
+ BT_INFO("Retrieve Characteristics properties");
+ ret = bluetooth_gatt_client_get_characteristics_property(
+ client_s->remote_address,
+ &svc_handle,
+ &char_handle,
+ &char_property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_characteristics_property is failed");
+ continue;
+ }
+
+ BT_INFO("Characteristics properties are retreived, not create charc object");
+ ret = bt_gatt_characteristic_create(char_property.uuid, 0,
+ char_property.permission,
+ (char *)char_property.val,
+ (int)char_property.val_len, (bt_gatt_h *)&chr);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_characteristic_create is failed");
+ goto next;
+ }
+
+ if (char_property.permission & BT_GATT_PROPERTY_WRITE_WITHOUT_RESPONSE) {
+ chr->write_type = BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE;
+ BT_INFO("Characterics has Write No Response property");
+ }
+ if (char_property.permission & BT_GATT_PROPERTY_WRITE) {
+ BT_INFO("Characterics has Write property");
+ chr->write_type = BT_GATT_WRITE_TYPE_WRITE;
+ }
+ if (char_property.permission & BT_GATT_PROPERTY_READ)
+ BT_INFO("Characterics has Read property");
+
+ if (char_property.permission & BT_GATT_PROPERTY_BROADCAST)
+ BT_INFO("Characterics has Broadcast property");
+
+ if (char_property.permission & BT_GATT_PROPERTY_INDICATE)
+ BT_INFO("Characterics has Indicate property");
+
+ if (char_property.permission & BT_GATT_PROPERTY_NOTIFY)
+ BT_INFO("Characterics has Notify property");
+
+ /* Copy descriptor handles in just created charc object */
+ memcpy(&chr->descriptor_handles, &char_property.char_desc_handle,
+ sizeof(bt_gatt_handle_info_t));
+ chr->instance_id = char_handle.instance_id;
+ chr->parent = (void *)svc;
+ chr->role = BT_GATT_ROLE_CLIENT;
+ chr->properties = char_property.permission;
+
+ chr_list = g_slist_append(chr_list, chr);
+next:
+ bluetooth_gatt_free_char_property(&char_property);
+ }
+
+ memset(&svc->charc_handles, 0x00, sizeof(bt_gatt_handle_info_t));
+ g_slist_free_full(svc->characteristics,
+ __bt_gatt_client_handle_destroy);
+
+ svc->characteristics = chr_list;
+ BT_INFO("Total number of characteristics whose properties are retrieved is [%d]",
+ g_slist_length(svc->characteristics));
+
+ return BT_ERROR_NONE;
+}
+#else
int _bt_gatt_client_update_characteristics(bt_gatt_h service)
{
bt_gatt_service_s *svc = service;
@@ -357,7 +640,96 @@ next:
return BT_ERROR_NONE;
}
+#endif
+
+
+#ifdef TIZEN_GATT_CLIENT
+int _bt_gatt_client_update_descriptors(bt_gatt_h characteristic)
+{
+ bt_gatt_characteristic_s *chr = characteristic;
+ GSList *desc_list = NULL;
+ int i;
+
+ bt_gatt_service_s *svc;
+ bt_gatt_client_s *client_s;
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t char_handle;
+ bt_gatt_handle_property_t desc_handle;
+
+ BT_INFO("+");
+ if (chr == NULL)
+ return BT_ERROR_INVALID_PARAMETER;
+ if (chr->descriptor_handles.count == 0)
+ return BT_ERROR_NONE;
+
+ svc = (bt_gatt_service_s*)chr->parent;
+ memset(&svc_handle, 0x00, sizeof(bt_gatt_handle_property_t));
+ memset(&char_handle, 0x00, sizeof(bt_gatt_handle_property_t));
+ memset(&desc_handle, 0x00, sizeof(bt_gatt_handle_property_t));
+
+ client_s = (bt_gatt_client_s*)svc->parent;
+
+ __bt_string_to_uuid_hex(svc->uuid, svc_handle.uuid);
+ svc_handle.instance_id = svc->instance_id;
+
+ __bt_string_to_uuid_hex(chr->uuid, char_handle.uuid);
+ char_handle.instance_id = chr->instance_id;
+
+ for (i = 0; i < chr->descriptor_handles.count; i++) {
+ bt_gatt_descriptor_s *desc = NULL;
+ bt_gatt_char_descriptor_property_t desc_property;
+ int ret;
+
+ memset(&desc_property, 0x00, sizeof(desc_property));
+
+
+ __bt_string_to_uuid_hex(chr->descriptor_handles.uuids[i], desc_handle.uuid);
+ desc_handle.instance_id = chr->descriptor_handles.inst_id[i];
+
+ BT_INFO("Retreieve Desceriptor Properties from remote [%s]",
+ client_s->remote_address);
+ ret = bluetooth_gatt_client_get_char_descriptor_property(
+ client_s->remote_address,
+ &svc_handle,
+ &char_handle,
+ &desc_handle,
+ &desc_property);
+ ret = _bt_get_error_code(ret);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bluetooth_gatt_get_char_descriptor_property is failed");
+ continue;
+ }
+
+ BT_INFO("Retreieved Desceriptor Properties, now create Descriptor object");
+ ret = bt_gatt_descriptor_create(desc_property.uuid, 0,
+ (char*)desc_property.val,
+ (int)desc_property.val_len,
+ (bt_gatt_h *)&desc);
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("bt_gatt_descriptor_create is failed");
+ goto next;
+ }
+
+
+ desc->instance_id = desc_handle.instance_id;
+ desc->parent = (void *)characteristic;
+ desc->role = BT_GATT_ROLE_CLIENT;
+ desc_list = g_slist_append(desc_list, desc);
+next:
+ bluetooth_gatt_free_desc_property(&desc_property);
+ }
+
+
+ memset(&chr->descriptor_handles, 0x00, sizeof(bt_gatt_handle_info_t));
+
+ g_slist_free_full(chr->descriptors,
+ __bt_gatt_client_handle_destroy);
+ chr->descriptors = desc_list;
+
+ return BT_ERROR_NONE;
+}
+#else
int _bt_gatt_client_update_descriptors(bt_gatt_h characteristic)
{
bt_gatt_characteristic_s *chr = characteristic;
@@ -412,7 +784,47 @@ next:
return BT_ERROR_NONE;
}
+#endif
+#ifdef TIZEN_GATT_CLIENT
+/* LCOV_EXCL_STOP */
+int bt_gatt_connect(const char *address, bool auto_connect)
+{
+ int ret;
+ bluetooth_device_address_t bd_addr = { {0,} };
+
+ bt_gatt_client_s *client_s;
+
+ BT_INFO("Address [%s] Auto Connect [%d]",
+ address, auto_connect);
+
+ BT_CHECK_GATT_CLIENT_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(address);
+ _bt_convert_address_to_hex(&bd_addr, address);
+
+ /* Find any client attached with remote address or not */
+ client_s = _bt_gatt_get_client(address);
+ if (client_s) {
+ BT_INFO("GATT client instance is already present for the rmeote addr [%s] client_id[%d]",
+ address, client_s->client_id);
+ ret = _bt_get_error_code(bluetooth_connect_le(&bd_addr,
+ auto_connect, client_s->client_id));
+ } else {
+ BT_INFO("GATT client instance is NOT present for the remote addr [%s]",
+ address);
+
+ ret = _bt_get_error_code(bluetooth_connect_le(&bd_addr,
+ auto_connect, 0/* Default Client ID */));
+
+ }
+
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ return ret;
+}
+#else
/* LCOV_EXCL_STOP */
int bt_gatt_connect(const char *address, bool auto_connect)
{
@@ -425,25 +837,43 @@ int bt_gatt_connect(const char *address, bool auto_connect)
_bt_convert_address_to_hex(&bd_addr, address);
ret = _bt_get_error_code(bluetooth_connect_le(&bd_addr,
- auto_connect ? TRUE : FALSE));
+ auto_connect ? TRUE : FALSE));
if (ret != BT_ERROR_NONE)
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
return ret;
}
+#endif
int bt_gatt_disconnect(const char *address)
{
int ret;
bluetooth_device_address_t bd_addr = { {0,} };
+#ifdef TIZEN_GATT_CLIENT
+ bt_gatt_client_s *client_s;
+#endif
BT_CHECK_GATT_CLIENT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(address);
_bt_convert_address_to_hex(&bd_addr, address);
+#ifdef TIZEN_GATT_CLIENT
+ /* Find any client attached with remote address or not */
+ client_s = _bt_gatt_get_client(address);
+ if (client_s) {
+ BT_INFO("GATT client instance is already present for the remote addr [%s] client interface [%d]",
+ address, client_s->client_id);
+ ret = _bt_get_error_code(bluetooth_disconnect_le(&bd_addr, client_s->client_id));
+ } else {
+ BT_INFO("GATT client instance is NOT present for the remote addr [%s]",
+ address);
+ ret = _bt_get_error_code(bluetooth_disconnect_le(&bd_addr, 0 /* Default CLient ID */));
+ }
+#else
ret = _bt_get_error_code(bluetooth_disconnect_le(&bd_addr));
+#endif
if (ret != BT_ERROR_NONE)
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
@@ -474,6 +904,10 @@ static void __bt_gatt_free_descriptor(bt_gatt_h gatt_handle)
{
bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
+ /* Remove descriptor from List of GATT handles */
+ if (gatt_handle_list)
+ gatt_handle_list = g_slist_remove(gatt_handle_list, gatt_handle);
+
g_free(desc->path);
g_free(desc->uuid);
g_free(desc->value);
@@ -487,10 +921,49 @@ static void __bt_gatt_free_descriptor(bt_gatt_h gatt_handle)
static void __bt_gatt_free_characteristic(bt_gatt_h gatt_handle)
{
int ret;
+#ifdef TIZEN_GATT_CLIENT
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t chr_handle;
+ bt_gatt_service_s *service_s;
+ bt_gatt_client_s *client_s;
+#endif
+
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s*)gatt_handle;
+ BT_INFO("+");
+
+ /* Remove characteristic from List of GATT handles */
+ if (gatt_handle_list)
+ gatt_handle_list = g_slist_remove(gatt_handle_list, gatt_handle);
+
+#ifdef TIZEN_GATT_CLIENT
+ service_s = (bt_gatt_service_s*)chr->parent;
+ if (!service_s) {
+ BT_ERR("service_s is null");
+ goto fail;
+ }
+ client_s = (bt_gatt_client_s*)service_s->parent;
+ if (!client_s) {
+ BT_ERR("client_s is null");
+ goto fail;
+ }
+ /* Create Service and Charc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ BT_INFO("Service UUID [%s]", service_s->uuid);
+ BT_INFO("Charc Instance ID [%d]", service_s->instance_id);
+
+ BT_INFO("Charc UUID [%s]", chr->uuid);
+ BT_INFO("Charc Instance ID [%d]", chr->instance_id);
+
+ BT_INFO("Client ID [%d]", client_s->client_id);
+
+ __bt_string_to_uuid_hex(chr->uuid, chr_handle.uuid);
+ chr_handle.instance_id = chr->instance_id;
+#endif
if (chr->role == BT_GATT_ROLE_CLIENT && chr->value_changed_cb &&
- chr->properties &
+ chr->properties &
(BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
BT_DBG("Unwatch characteristic");
ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics(
@@ -499,9 +972,12 @@ static void __bt_gatt_free_characteristic(bt_gatt_h gatt_handle)
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
+fail:
g_slist_free_full(chr->descriptors, __bt_gatt_free_descriptor);
+#ifndef TIZEN_GATT_CLIENT
g_strfreev(chr->desc_handles);
+#endif
g_free(chr->path);
g_free(chr->uuid);
@@ -521,6 +997,10 @@ static void __bt_gatt_free_service(bt_gatt_h gatt_handle)
g_slist_free_full(svc->included_services, __bt_gatt_free_service);
g_slist_free_full(svc->characteristics, __bt_gatt_free_characteristic);
+ /* Remove service from List of GATT handles */
+ if (gatt_handle_list)
+ gatt_handle_list = g_slist_remove(gatt_handle_list, gatt_handle);
+
if (svc->role == BT_GATT_ROLE_SERVER) {
#ifdef TIZEN_FEATURE_GATT_RELAY
if (is_gatt_server_initialized) {
@@ -723,7 +1203,6 @@ int bt_gatt_destroy(bt_gatt_h gatt_handle)
return BT_ERROR_NONE;
}
-/* LCOV_EXCL_START */
static int __get_write_prop(bt_gatt_write_type_e type, bt_gatt_property_e *prop)
{
if (!prop)
@@ -758,6 +1237,9 @@ int bt_gatt_service_destroy(bt_gatt_h gatt_handle)
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(gatt_handle);
+ BT_INFO("Destroy GATT Service");
+
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
if (handle->type == BT_GATT_TYPE_SERVICE)
__bt_gatt_destroy_service(gatt_handle);
@@ -820,6 +1302,8 @@ int bt_gatt_get_value(bt_gatt_h gatt_handle, char **value, int *value_length)
BT_CHECK_INPUT_PARAMETER(value); /* LCOV_EXCL_START */
BT_CHECK_INPUT_PARAMETER(value_length);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
*value_length = chr->value_length;
if (chr->value_length > 0)
@@ -962,16 +1446,21 @@ int bt_gatt_set_value(bt_gatt_h gatt_handle, const char *value,
bluetooth_gatt_server_update_value_t param;
#endif
+ BT_INFO("+");
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(value); /* LCOV_EXCL_START */
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ BT_INFO("Request is for Char write value");
val = &chr->value;
val_len = &chr->value_length;
} else if (handle->type == BT_GATT_TYPE_DESCRIPTOR) {
+ BT_INFO("Request is for Descriptor write value");
val = &desc->value;
val_len = &desc->value_length;
} else {
@@ -1015,6 +1504,7 @@ int bt_gatt_set_value(bt_gatt_h gatt_handle, const char *value,
*val = g_memdup(value, value_length);
*val_len = value_length;
+ BT_INFO("Value is set");
return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
}
@@ -1064,16 +1554,22 @@ int bt_gatt_set_int_value(bt_gatt_h gatt_handle, bt_data_type_int_e type,
*val_len = fmt_size;
} else if (*val_len == offset) { /* Added */
tmp = g_malloc0(*val_len + fmt_size);
- if (tmp == NULL)
+ /* Fix : NULL_RETURNS */
+ if (!tmp) {
+ g_free(*val);
return BT_ERROR_OUT_OF_MEMORY;
+ }
memcpy(tmp, *val, *val_len);
g_free(*val);
*val = tmp;
*val_len += fmt_size;
} else if (*val_len < offset + fmt_size) {/* Overlapped */
tmp = g_malloc0(offset + fmt_size);
- if (tmp == NULL)
+ /* Fix : NULL_RETURNS */
+ if (!tmp) {
+ g_free(*val);
return BT_ERROR_OUT_OF_MEMORY;
+ }
memcpy(tmp, *val, *val_len);
g_free(*val);
*val = tmp;
@@ -1187,15 +1683,28 @@ int bt_gatt_set_float_value(bt_gatt_h gatt_handle, bt_data_type_float_e type,
if (*val == NULL) {
*val = g_malloc0(fmt_size);
+ /* Fix : NULL_RETURNS */
+ if (*val == NULL)
+ return BT_ERROR_OUT_OF_MEMORY;
*val_len = fmt_size;
} else if (*val_len == offset) {/* Added */
tmp = g_malloc0(*val_len + fmt_size);
+ /* Fix : NULL_RETURNS */
+ if (tmp == NULL) {
+ g_free(*val);
+ return BT_ERROR_OUT_OF_MEMORY;
+ }
memcpy(tmp, *val, *val_len);
g_free(*val);
*val = tmp;
*val_len += fmt_size;
} else if (*val_len < offset + fmt_size) {/* Overlapped */
tmp = g_malloc0(offset + fmt_size);
+ /* Fix : NULL_RETURNS */
+ if (tmp == NULL) {
+ g_free(*val);
+ return BT_ERROR_OUT_OF_MEMORY;
+ }
memcpy(tmp, *val, *val_len);
g_free(*val);
*val = tmp;
@@ -1258,6 +1767,8 @@ int bt_gatt_characteristic_get_permissions(bt_gatt_h gatt_handle, int *permissio
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(permissions);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
*permissions = chr->permissions;
else {
@@ -1279,6 +1790,8 @@ int bt_gatt_descriptor_get_permissions(bt_gatt_h gatt_handle, int *permissions)
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(permissions);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
*permissions = desc->permissions;
else {
@@ -1300,6 +1813,8 @@ int bt_gatt_set_permissions(bt_gatt_h gatt_handle, int permissions)
BT_CHECK_INPUT_PARAMETER(gatt_handle);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC)
chr->permissions = permissions;
else if (handle->type == BT_GATT_TYPE_DESCRIPTOR)
@@ -1400,6 +1915,9 @@ int bt_gatt_service_create(const char *uuid, bt_gatt_service_type_e type,
#endif
*service = (bt_gatt_h)svc;
+ /* Add service to list of GATT handles */
+ gatt_handle_list = g_slist_append(gatt_handle_list, (gpointer)svc);
+
return BT_ERROR_NONE;
}
@@ -1414,6 +1932,10 @@ int bt_gatt_service_add_characteristic(bt_gatt_h service,
BT_CHECK_INPUT_PARAMETER(service);
BT_CHECK_INPUT_PARAMETER(characteristic);
+
+ BT_VALIDATE_GATT_HANDLE(service);
+ BT_VALIDATE_GATT_HANDLE(characteristic);
+
if (chr->parent) {
BT_ERR("This characteristic is already added.");
return BT_ERROR_INVALID_PARAMETER;
@@ -1421,12 +1943,6 @@ int bt_gatt_service_add_characteristic(bt_gatt_h service,
svc->characteristics = g_slist_append(svc->characteristics, chr);
chr->parent = (void *)service;
-#ifdef TIZEN_FEATURE_GATT_RELAY
- if (svc) {
- BT_INFO("Current handle count of service [%d]", svc->numhandles);
- svc->numhandles += 2;
- }
-#endif
return BT_ERROR_NONE;
}
@@ -1441,6 +1957,10 @@ int bt_gatt_service_add_included_service(bt_gatt_h service,
BT_CHECK_INPUT_PARAMETER(service);
BT_CHECK_INPUT_PARAMETER(included_service);
+
+ BT_VALIDATE_GATT_HANDLE(service);
+ BT_VALIDATE_GATT_HANDLE(included_service);
+
if (included_svc->parent) {
BT_ERR("This service is already added.");
return BT_ERROR_INVALID_PARAMETER;
@@ -1523,7 +2043,13 @@ int bt_gatt_service_get_characteristic(bt_gatt_h service, const char *uuid,
BT_CHECK_INPUT_PARAMETER(uuid); /* LCOV_EXCL_START */
BT_CHECK_INPUT_PARAMETER(characteristic);
+ BT_INFO("Get Characteristic rom service, charc uuid [%s], total charcs of this service [%d]",
+ uuid, svc->charc_handles.count);
+#ifdef TIZEN_GATT_CLIENT
+ if (svc->charc_handles.count > 0) {
+#else
if (svc->char_handles) {
+#endif
ret = _bt_gatt_client_update_characteristics(svc);
if (ret != BT_ERROR_NONE) {
BT_ERR("_bt_gatt_client_update_characteristics failed");
@@ -1557,7 +2083,12 @@ int bt_gatt_service_foreach_characteristics(bt_gatt_h service,
BT_CHECK_INPUT_PARAMETER(service);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
+#ifdef TIZEN_GATT_CLIENT
+ BT_INFO("Total num of characteristics [%d]", svc->charc_handles.count);
+ if (svc->charc_handles.count > 0) {
+#else
if (svc->char_handles) {
+#endif
int ret;
ret = _bt_gatt_client_update_characteristics(svc);
@@ -1568,6 +2099,7 @@ int bt_gatt_service_foreach_characteristics(bt_gatt_h service,
}
total = g_slist_length(svc->characteristics);
+ BT_INFO("Total charcs [%d]", total);
for (l = svc->characteristics; l; l = g_slist_next(l)) {
chr = l->data;
@@ -1647,6 +2179,7 @@ int bt_gatt_service_foreach_included_services(bt_gatt_h service,
return BT_ERROR_NONE;
}
+
/* LCOV_EXCL_START */
int bt_gatt_characteristic_create(const char *uuid, int permissions,
int properties, const char *value,
@@ -1670,6 +2203,9 @@ int bt_gatt_characteristic_create(const char *uuid, int permissions,
chr->type = BT_GATT_TYPE_CHARACTERISTIC;
chr->role = BT_GATT_ROLE_SERVER;
+ BT_INFO("Characteristic UUID : [%s] len [%d] permissions [%d] properties [%d]",
+ uuid, strlen(uuid), permissions, properties);
+
#ifdef TIZEN_FEATURE_GATT_RELAY
chr->uuid = _bt_convert_uuid_to_uuid128(uuid);
#else
@@ -1678,6 +2214,7 @@ int bt_gatt_characteristic_create(const char *uuid, int permissions,
else
chr->uuid = g_strdup(uuid);
#endif
+
if (chr->uuid == NULL) {
ret = BT_ERROR_OUT_OF_MEMORY;
goto fail;
@@ -1696,6 +2233,9 @@ int bt_gatt_characteristic_create(const char *uuid, int permissions,
*characteristic = (bt_gatt_h)chr;
+ /* Add charactristic to list of GATT handles */
+ gatt_handle_list = g_slist_append(gatt_handle_list, (gpointer)chr);
+
return BT_ERROR_NONE;
fail:
@@ -1718,8 +2258,11 @@ int bt_gatt_characteristic_add_descriptor(bt_gatt_h characteristic,
BT_CHECK_INPUT_PARAMETER(characteristic);
BT_CHECK_INPUT_PARAMETER(descriptor);
+ BT_VALIDATE_GATT_HANDLE(characteristic);
+ BT_VALIDATE_GATT_HANDLE(descriptor);
+
if (chr->type != BT_GATT_TYPE_CHARACTERISTIC ||
- desc->type != BT_GATT_TYPE_DESCRIPTOR) {
+ desc->type != BT_GATT_TYPE_DESCRIPTOR) {
BT_ERR("Wrong type. chr : %d, desc : %d", chr->type, desc->type);
return BT_ERROR_INVALID_PARAMETER;
}
@@ -1731,18 +2274,10 @@ int bt_gatt_characteristic_add_descriptor(bt_gatt_h characteristic,
chr->descriptors = g_slist_append(chr->descriptors, desc);
desc->parent = (void *)characteristic;
-#ifdef TIZEN_FEATURE_GATT_RELAY
-{
- bt_gatt_service_s *svc = (bt_gatt_service_s *)chr->parent;
- if (svc) {
- BT_INFO("Current handle count of service [%d]", svc->numhandles);
- svc->numhandles += 1; /* Initalize numhandles to 1 */
- }
-}
-#endif
return BT_ERROR_NONE;
}
+
/* LCOV_EXCL_STOP */
int bt_gatt_characteristic_get_service(bt_gatt_h characteristic, bt_gatt_h *service)
{
@@ -1868,8 +2403,11 @@ int bt_gatt_characteristic_get_descriptor(bt_gatt_h characteristic,
BT_ERR("Wrong type of GATT handle : %d", chr->type);
return BT_ERROR_INVALID_PARAMETER;
}
-
+#ifdef TIZEN_GATT_CLIENT
+ if (chr->descriptor_handles.count > 0) {
+#else
if (chr->desc_handles) {
+#endif
ret = _bt_gatt_client_update_descriptors(chr);
if (ret != BT_ERROR_NONE) {
BT_ERR("_bt_gatt_client_update_descriptors is failed");
@@ -1895,6 +2433,7 @@ int bt_gatt_characteristic_foreach_descriptors(bt_gatt_h characteristic,
int total;
int i;
+ BT_INFO("+");
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
@@ -1906,7 +2445,12 @@ int bt_gatt_characteristic_foreach_descriptors(bt_gatt_h characteristic,
return BT_ERROR_INVALID_PARAMETER;
}
+#ifdef TIZEN_GATT_CLIENT
+ BT_INFO("Total Descriptors for the current characteristic [%d]", chr->descriptor_handles.count);
+ if (chr->descriptor_handles.count > 0) {
+#else
if (chr->desc_handles) {
+#endif
int ret;
ret = _bt_gatt_client_update_descriptors(chr);
@@ -1917,6 +2461,7 @@ int bt_gatt_characteristic_foreach_descriptors(bt_gatt_h characteristic,
}
total = g_slist_length(chr->descriptors);
+ BT_INFO("Total number of descriptors found [%d]", total);
i = 1;
for (l = chr->descriptors; l; l = g_slist_next(l)) {
@@ -1926,6 +2471,7 @@ int bt_gatt_characteristic_foreach_descriptors(bt_gatt_h characteristic,
return BT_ERROR_NONE;
}
+
/* LCOV_EXCL_START */
int bt_gatt_descriptor_create(const char *uuid, int permissions,
const char *value, int value_length,
@@ -1948,6 +2494,7 @@ int bt_gatt_descriptor_create(const char *uuid, int permissions,
desc->type = BT_GATT_TYPE_DESCRIPTOR;
desc->role = BT_GATT_ROLE_SERVER;
+ BT_INFO("Descriptor UUID : [%s] len [%d] permissions [%d]", uuid, strlen(uuid), permissions);
#ifdef TIZEN_FEATURE_GATT_RELAY
desc->uuid = _bt_convert_uuid_to_uuid128(uuid);
#else
@@ -1956,6 +2503,7 @@ int bt_gatt_descriptor_create(const char *uuid, int permissions,
else
desc->uuid = g_strdup(uuid);
#endif
+
if (desc->uuid == NULL) {
ret = BT_ERROR_OUT_OF_MEMORY;
goto fail;
@@ -1973,6 +2521,9 @@ int bt_gatt_descriptor_create(const char *uuid, int permissions,
*descriptor = (bt_gatt_h)desc;
+ /* Add charactristic to list of GATT handles */
+ gatt_handle_list = g_slist_append(gatt_handle_list, (gpointer)desc);
+
return ret;
fail:
@@ -1982,6 +2533,7 @@ fail:
return ret;
}
+
/* LCOV_EXCL_STOP */
int bt_gatt_descriptor_get_characteristic(bt_gatt_h descriptor,
bt_gatt_h *characteristic)
@@ -2006,6 +2558,9 @@ int bt_gatt_server_initialize(void)
int ret = BT_ERROR_NONE;
+ BT_INFO("gatt_server_initialized [%d] gatt_server_started[%d] instance_id [%d]",
+ is_gatt_server_initialized, is_gatt_server_started, instance_id);
+
if (is_gatt_server_started) {
BT_ERR("Already Server started");
return BT_ERROR_OPERATION_FAILED;
@@ -2028,7 +2583,7 @@ int bt_gatt_server_initialize(void)
return BT_ERROR_NONE;
}
- BT_DBG("Gatt-service already initialized");
+ BT_INFO("Gatt-service already initialized");
return ret;
}
@@ -2040,6 +2595,9 @@ int bt_gatt_server_deinitialize(void)
int ret = BT_ERROR_NONE;
+ BT_INFO("gatt_server_initialized [%d] gatt_server_started[%d] instance_id [%d]",
+ is_gatt_server_initialized, is_gatt_server_started, instance_id);
+
if (is_gatt_server_initialized) {
GSList *l;
for (l = gatt_server_list; l; l = g_slist_next(l)) {
@@ -2050,7 +2608,7 @@ int bt_gatt_server_deinitialize(void)
gatt_server_list = NULL;
#ifdef TIZEN_FEATURE_GATT_RELAY
- ret = _bt_get_error_code(bluetooth_gatt_deinit());
+ ret = _bt_get_error_code(bluetooth_gatt_server_deinit());
if (ret != BT_ERROR_NONE) {
BT_ERR("%s(0x%08x)",
_bt_convert_error_to_string(ret), ret);
@@ -2073,10 +2631,12 @@ int bt_gatt_server_deinitialize(void)
is_gatt_server_initialized = false;
is_gatt_server_started = false;
instance_id = -1;
+
+ BT_INFO("gatt server deinitialised completed");
return BT_ERROR_NONE;
}
- BT_DBG("Gatt-service is not initialized");
+ BT_INFO("Gatt-service is not initialized");
return ret;
}
@@ -2100,8 +2660,12 @@ 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);
+ /* Add server to list of GATT handles */
+ gatt_handle_list = g_slist_append(gatt_handle_list, (gpointer)serv);
+
return BT_ERROR_NONE;
}
@@ -2112,6 +2676,12 @@ int bt_gatt_server_destroy(bt_gatt_server_h server)
BT_CHECK_GATT_SERVER_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(server);
+ BT_VALIDATE_GATT_HANDLE(server);
+ BT_INFO("Destroy GATT Server");
+
+ /* Remove Server from list of GATT handles */
+ if (gatt_handle_list)
+ gatt_handle_list = g_slist_remove(gatt_handle_list, serv);
g_slist_free_full(serv->services, __bt_gatt_free_service);
gatt_server_list = g_slist_remove(gatt_server_list, serv);
@@ -2134,6 +2704,8 @@ int bt_gatt_server_set_read_value_requested_cb(bt_gatt_h gatt_handle,
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(callback);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
chr->read_requested_cb = callback;
chr->read_requested_user_data = user_data;
@@ -2162,6 +2734,8 @@ int bt_gatt_server_set_characteristic_notification_state_change_cb(bt_gatt_h gat
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(callback);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
chr->notification_changed_cb = callback;
chr->notification_changed_user_data = user_data;
@@ -2169,6 +2743,36 @@ int bt_gatt_server_set_characteristic_notification_state_change_cb(bt_gatt_h gat
}
#ifdef TIZEN_FEATURE_GATT_RELAY
+static int __gatt_service_add_num_handle(bt_gatt_service_s *service)
+{
+ int handles_count = 0;
+ GSList *char_l = NULL;
+
+ BT_CHECK_INPUT_PARAMETER(service);
+
+ BT_INFO("total service handles [%d]", service->numhandles);
+
+ for (char_l = service->characteristics; char_l; char_l = g_slist_next(char_l)) {
+ bt_gatt_characteristic_s *chr = char_l->data;
+ int desc_numhandles = 0;
+
+ if (chr) {
+ handles_count += 2;
+
+ /*descriptor of each characteristic*/
+ if (chr->descriptors) {
+ desc_numhandles = g_slist_length(chr->descriptors);
+ handles_count += desc_numhandles;
+ }
+ }
+ }
+
+ service->numhandles += handles_count;
+ BT_INFO("total service handles [%d]", service->numhandles);
+
+ return BT_ERROR_NONE;
+}
+
int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
{
int ret = BT_ERROR_NONE;
@@ -2182,6 +2786,7 @@ int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
BT_CHECK_GATT_SERVER_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(server);
BT_CHECK_INPUT_PARAMETER(service);
+ BT_VALIDATE_GATT_HANDLE(server);
if (g_slist_find(serv->services, svc)) {
BT_ERR("Already added service.");
@@ -2193,6 +2798,7 @@ int bt_gatt_server_register_service(bt_gatt_server_h server, bt_gatt_h service)
return BT_ERROR_OPERATION_FAILED;
}
+ __gatt_service_add_num_handle(svc);
BT_INFO("Service number of total handles [%d]", svc->numhandles);
ret = _bt_get_error_code(bluetooth_gatt_server_add_service(svc->uuid, svc->type,
@@ -2357,6 +2963,8 @@ int bt_gatt_server_unregister_service(bt_gatt_server_h server,
bt_gatt_server_s *serv = (bt_gatt_server_s *)server;
bt_gatt_service_s *svc = (bt_gatt_service_s *)service;
+ BT_INFO("Unregister GATT Service");
+
BT_CHECK_GATT_SERVER_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_GATT_SERVER_INIT_STATUS();
@@ -2378,6 +2986,7 @@ int bt_gatt_server_unregister_all_services(bt_gatt_server_h server)
int ret = BT_ERROR_NONE;
bt_gatt_server_s *serv = (bt_gatt_server_s*)server;
+ BT_INFO("Unregister All GATT Services");
BT_CHECK_GATT_SERVER_SUPPORT();
BT_CHECK_INIT_STATUS();
@@ -2508,6 +3117,8 @@ int bt_gatt_server_notify_characteristic_changed_value(bt_gatt_h characteristic,
BT_CHECK_INPUT_PARAMETER(characteristic);
BT_CHECK_INPUT_PARAMETER(callback);
+ BT_VALIDATE_GATT_HANDLE(characteristic);
+
_bt_convert_address_to_hex(&addr_hex, device_address);
#ifdef TIZEN_FEATURE_GATT_RELAY
@@ -2615,6 +3226,8 @@ int bt_gatt_server_set_write_value_requested_cb(bt_gatt_h gatt_handle,
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(callback);
+ BT_VALIDATE_GATT_HANDLE(gatt_handle);
+
if (handle->type == BT_GATT_TYPE_CHARACTERISTIC) {
chr->write_value_requested_cb = callback;
chr->write_value_requested_user_data = user_data;
@@ -2679,6 +3292,85 @@ int bt_gatt_server_foreach_services(bt_gatt_server_h server,
return BT_ERROR_NONE;
}
+
+#ifdef TIZEN_GATT_CLIENT
+int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
+{
+ int ret = BT_ERROR_NONE;
+ bt_gatt_client_s *client_s;
+ bool connected = false;
+ GSList *l;
+ bluetooth_device_address_t bd_addr = { {0,} };
+
+ BT_CHECK_GATT_CLIENT_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address); /* LCOV_EXCL_START */
+
+ BT_INFO("Create GATT client: address[%s] Total gatt client instance list [%d]",
+ remote_address, g_slist_length(gatt_client_list));
+
+ for (l = gatt_client_list; l; l = g_slist_next(l)) {
+ bt_gatt_client_s *c = (bt_gatt_client_s *)l->data;
+ BT_INFO("Already present GATT client instance addr [%s]", c->remote_address);
+
+ if ((c == NULL) || (c->remote_address == NULL)) {
+ BT_ERR("bt_gatt_client_create Error Parameter are NULL..\n");
+ continue;
+ } else if (!g_ascii_strcasecmp(c->remote_address, remote_address)) {
+ BT_ERR("Gatt client for %s is already created",
+ remote_address);
+ return BT_ERROR_ALREADY_DONE;
+ }
+ }
+
+ client_s = g_malloc0(sizeof(*client_s));
+ if (client_s == NULL) {
+ ret = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ client_s->remote_address = g_strdup(remote_address);
+ if (client_s->remote_address == NULL) {
+ free(client_s);
+ ret = BT_ERROR_OUT_OF_MEMORY;
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ return ret;
+ }
+
+ /* Attempt to Register GATT Client instance */
+ _bt_convert_address_to_hex(&bd_addr, client_s->remote_address);
+
+ ret = bluetooth_gatt_client_init(&client_s->client_id, &bd_addr,
+ _bt_gatt_client_event_proxy);
+
+ if (BLUETOOTH_ERROR_NONE != ret) {
+ free(client_s->remote_address);
+ free(client_s);
+ return ret;
+ }
+ if (bt_device_is_profile_connected(remote_address, BT_PROFILE_GATT,
+ &connected) != BT_ERROR_NONE)
+ BT_ERR("bt_device_is_profile_connected is failed");
+ else
+ client_s->connected = connected;
+
+ ret = _bt_gatt_client_update_services(client_s);
+ if (ret != BT_ERROR_NONE) {
+ BT_INFO("_bt_gatt_client_update_services returns 0x%X. "
+ "It could be updated when service is available.", ret);
+ ret = BT_ERROR_NONE;
+ }
+
+ BT_INFO("GATT Client Handle is created instance ID [%d]",
+ client_s->client_id);
+
+ *client = (bt_gatt_client_h)client_s;
+ gatt_client_list = g_slist_append(gatt_client_list, client_s);
+
+ return ret; /* LCOV_EXCL_STOP */
+}
+#else
/* LCOV_EXCL_STOP */
int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
{
@@ -2739,6 +3431,7 @@ int bt_gatt_client_create(const char *remote_address, bt_gatt_client_h *client)
return ret; /* LCOV_EXCL_STOP */
}
+#endif
int bt_gatt_client_destroy(bt_gatt_client_h client)
{
@@ -2747,17 +3440,28 @@ int bt_gatt_client_destroy(bt_gatt_client_h client)
BT_CHECK_GATT_CLIENT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(client); /* LCOV_EXCL_START */
+ BT_INFO("Destroy GATT client: Client interface ID [%d] REmote address [%s]",
+ client_s->client_id, client_s->remote_address);
if (client_s->service_changed_cb) {
bluetooth_device_address_t bd_addr = { {0,} };
_bt_convert_address_to_hex(&bd_addr, client_s->remote_address);
+#ifdef TIZEN_GATT_CLIENT
+ bluetooth_gatt_client_set_service_change_watcher(&bd_addr, FALSE);
+#else
bluetooth_gatt_set_service_change_watcher(&bd_addr, FALSE);
+#endif
}
- g_free(client_s->remote_address);
g_slist_free_full(client_s->services, __bt_gatt_free_service);
gatt_client_list = g_slist_remove(gatt_client_list, client_s);
+
+#ifdef TIZEN_GATT_CLIENT
+ /* Unregister GATT Client instance: Unregister should never fail */
+ bluetooth_gatt_client_deinit(client_s->client_id);
+ g_free(client_s->remote_address);
+#endif
g_free(client_s);
return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
@@ -2778,6 +3482,20 @@ int bt_gatt_client_get_remote_address(bt_gatt_client_h client,
return BT_ERROR_NONE;
}
+static bool __bt_gatt_client_is_in_progress(void)
+{
+ if (_bt_check_cb(BT_EVENT_GATT_CLIENT_WRITE_CHARACTERISTIC) ||
+ _bt_check_cb(BT_EVENT_GATT_CLIENT_WRITE_DESCRIPTOR) ||
+ _bt_check_cb(BT_EVENT_GATT_CLIENT_READ_CHARACTERISTIC) ||
+ _bt_check_cb(BT_EVENT_GATT_CLIENT_READ_DESCRIPTOR)) {
+ BT_ERR("Operation is in progress");
+ return true;
+ }
+
+ return false; /* LCOV_EXCL_STOP */
+}
+
+
void _handle_gatt_client_read_completed_event(int result, bt_gatt_resp_data_t *resp)
{
bt_gatt_common_s *handle;
@@ -2883,17 +3601,31 @@ void _handle_gatt_client_write_completed_event(int result, bt_gatt_resp_data_t *
return; /* LCOV_EXCL_STOP */
}
+#ifdef TIZEN_GATT_CLIENT
int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
bt_gatt_client_request_completed_cb callback, void *user_data)
{
int ret = BT_ERROR_NONE;
bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
+ BT_INFO("+");
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t chr_handle;
+ bt_gatt_handle_property_t desc_handle;
+ bt_gatt_service_s *service_s;
+ bt_gatt_characteristic_s *charc_s;
+ bt_gatt_client_s *client_s;
+
BT_CHECK_GATT_CLIENT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(gatt_handle);
BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
+ if (__bt_gatt_client_is_in_progress()) {
+ BT_ERR("Operation is in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
@@ -2902,9 +3634,28 @@ int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
return BT_ERROR_NOW_IN_PROGRESS;
}
+ service_s = (bt_gatt_service_s*)chr->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+ BT_INFO("Read Characteristic from remote address [%s] service UUID [%s] char UUID [%s]",
+ client_s->remote_address,
+ service_s->uuid,
+ chr->uuid);
+
+ /* Create Service and Charc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(chr->uuid, chr_handle.uuid);
+ chr_handle.instance_id = chr->instance_id;
+
ret = _bt_get_error_code(
- bluetooth_gatt_read_characteristic_value(chr->path, gatt_handle));
+ bluetooth_gatt_client_read_characteristic_value(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle));
+
if (ret == BT_ERROR_NONE) {
+ BT_INFO("Characteristic read scheduled successfully, set callback");
chr->read_cb = callback;
chr->read_user_data = user_data;
} else {
@@ -2918,9 +3669,34 @@ int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
return BT_ERROR_NOW_IN_PROGRESS;
}
+ charc_s = (bt_gatt_characteristic_s*)desc->parent;
+ service_s = (bt_gatt_service_s*)charc_s->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+
+ BT_INFO("Read Descriptor from remote address [%s] service UUID [%s] char UUID [%s] desc UUID [%s]",
+ client_s->remote_address,
+ service_s->uuid,
+ charc_s->uuid,
+ desc->uuid);
+ /* Create Service and Charc & desc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(charc_s->uuid, chr_handle.uuid);
+ chr_handle.instance_id = charc_s->instance_id;
+
+ __bt_string_to_uuid_hex(desc->uuid, desc_handle.uuid);
+ desc_handle.instance_id = desc->instance_id;
+
ret = _bt_get_error_code(
- bluetooth_gatt_read_descriptor_value(desc->path, gatt_handle));
+ bluetooth_gatt_client_read_descriptor_value(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ &desc_handle));
+
if (ret == BT_ERROR_NONE) {
+ BT_INFO("Descriptor read scheduled successfully, set callback");
desc->read_cb = callback;
desc->read_user_data = user_data;
} else {
@@ -2931,9 +3707,188 @@ int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
BT_ERR("Invalid handle type for read ");
}
+ BT_INFO("Result [%d]", ret);
return ret; /* LCOV_EXCL_STOP */
}
+#else
+int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
+ bt_gatt_client_request_completed_cb callback, void *user_data)
+{
+ int ret = BT_ERROR_NONE;
+ bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
+ BT_CHECK_GATT_CLIENT_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(gatt_handle);
+ BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
+
+ if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+
+ if (chr->read_cb) {
+ BT_ERR("read request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
+ ret = _bt_get_error_code(
+ bluetooth_gatt_read_characteristic_value(chr->path, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ chr->read_cb = callback;
+ chr->read_user_data = user_data;
+ } else {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ } else if (c->type == BT_GATT_TYPE_DESCRIPTOR) {
+ bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
+
+ if (desc->read_cb) {
+ BT_ERR("read request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
+ ret = _bt_get_error_code(
+ bluetooth_gatt_read_descriptor_value(desc->path, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ desc->read_cb = callback;
+ desc->read_user_data = user_data;
+ } else {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ } else {
+ ret = BT_ERROR_INVALID_PARAMETER;
+ BT_ERR("Invalid handle type for read ");
+ }
+
+ return ret; /* LCOV_EXCL_STOP */
+}
+#endif
+
+#ifdef TIZEN_GATT_CLIENT
+int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
+ bt_gatt_client_request_completed_cb callback, void *user_data)
+{
+ int ret = BT_ERROR_NONE;
+ bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
+
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t chr_handle;
+ bt_gatt_handle_property_t desc_handle;
+ bt_gatt_service_s *service_s;
+ bt_gatt_characteristic_s *charc_s;
+ bt_gatt_client_s *client_s;
+ bluetooth_gatt_att_data_t write_data;
+
+ BT_INFO("+");
+ BT_CHECK_GATT_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(gatt_handle);
+ BT_CHECK_INPUT_PARAMETER(callback); /* LCOV_EXCL_START */
+
+ if (__bt_gatt_client_is_in_progress()) {
+ BT_ERR("Operation is in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
+ if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+
+ int k;
+ memset(&write_data, 0x00, sizeof(bluetooth_gatt_att_data_t));
+ write_data.length = chr->value_length;
+ BT_INFO("Char write value length [%d]", write_data.length);
+ for (k = 0; k < chr->value_length; k++)
+ BT_INFO("Character val [%d] [0x%x]", k, chr->value[k]);
+ memcpy(&write_data.data[0], chr->value, chr->value_length);
+ for (k = 0; k < write_data.length; k++)
+ BT_INFO("Write val [%d] [0x%x]", k, write_data.data[k]);
+
+ service_s = (bt_gatt_service_s*)chr->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+
+ /* Create Service and Charc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(chr->uuid, chr_handle.uuid);
+ chr_handle.instance_id = chr->instance_id;
+
+ if (chr->write_type == BT_GATT_WRITE_TYPE_WRITE) {
+ BT_INFO("Write characteristic: write type [%d]", chr->write_type);
+ ret = _bt_get_error_code(
+ bluetooth_gatt_client_write_characteristic_value_by_type(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ &write_data,
+ BLUETOOTH_GATT_TYPE_WRITE));
+ } else if (chr->write_type == BT_GATT_WRITE_TYPE_WRITE_NO_RESPONSE) {
+ BT_INFO("Write characteristic: write type [%d]", chr->write_type);
+ ret = _bt_get_error_code(
+ bluetooth_gatt_client_write_characteristic_value_by_type(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ &write_data,
+ BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE));
+ } else {
+ BT_ERR("Unknow write type : %d", chr->write_type);
+ ret = BT_ERROR_OPERATION_FAILED;
+ }
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ BT_INFO("GATT char write value scheuled successfully, set callback");
+ chr->write_cb = callback;
+ chr->write_user_data = user_data;
+ }
+ } else if (c->type == BT_GATT_TYPE_DESCRIPTOR) {
+ bt_gatt_descriptor_s *desc = (bt_gatt_descriptor_s *)gatt_handle;
+
+ BT_INFO("Write Descriptor");
+ int k;
+ charc_s = (bt_gatt_characteristic_s*)desc->parent;
+ service_s = (bt_gatt_service_s*)charc_s->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+
+ memset(&write_data, 0x00, sizeof(bluetooth_gatt_att_data_t));
+ write_data.length = desc->value_length;
+ BT_INFO("Desc write value length [%d]", write_data.length);
+ memcpy(&write_data.data[0], desc->value, desc->value_length);
+ for (k = 0; k < write_data.length; k++)
+ BT_INFO("Write val [%d] [0x%x]", k, write_data.data[k]);
+
+ /* Create Service and Charc & desc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(charc_s->uuid, chr_handle.uuid);
+ chr_handle.instance_id = charc_s->instance_id;
+
+ __bt_string_to_uuid_hex(desc->uuid, desc_handle.uuid);
+ desc_handle.instance_id = desc->instance_id;
+
+ ret = _bt_get_error_code(
+ bluetooth_gatt_client_write_descriptor_value(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ &desc_handle,
+ &write_data,
+ BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE));
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ BT_INFO("GATT Descriptor write value scheuled successfully, set callback");
+ desc->write_cb = callback;
+ desc->write_user_data = user_data;
+ }
+ } else {
+ BT_ERR("Invalid handle type for write ");
+ }
+
+ return ret;
+}
+#else
int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
bt_gatt_client_request_completed_cb callback, void *user_data)
{
@@ -2991,6 +3946,7 @@ int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
return ret;
}
+#endif
static bt_gatt_client_h __find_gatt_client(const char *remote_address)
{
@@ -3006,6 +3962,7 @@ static bt_gatt_client_h __find_gatt_client(const char *remote_address)
return NULL;
}
+#ifndef TIZEN_GATT_CLIENT
static gboolean __get_bdaddr_from_path(const char *path, char *addr)
{
int i;
@@ -3028,11 +3985,199 @@ static gboolean __get_bdaddr_from_path(const char *path, char *addr)
}
addr[i] = '\0';
+ BT_DBG("path : %s, addr : %s", path, addr);
+
return TRUE;
}
+#endif
+
+#ifdef TIZEN_GATT_CLIENT
+void __uuid_hex_to_string(unsigned char *uuid, char *str)
+{
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
+
+ memcpy(&uuid0, &(uuid[0]), 4);
+ memcpy(&uuid1, &(uuid[4]), 2);
+ memcpy(&uuid2, &(uuid[6]), 2);
+ memcpy(&uuid3, &(uuid[8]), 2);
+ memcpy(&uuid4, &(uuid[10]), 4);
+ memcpy(&uuid5, &(uuid[14]), 2);
+
+ snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+ ntohl(uuid0), ntohs(uuid1),
+ ntohs(uuid2), ntohs(uuid3),
+ ntohl(uuid4), ntohs(uuid5));
+ return;
+}
+
+static bt_gatt_characteristic_s* __gatt_get_characteristic_handle(
+ unsigned char *svc_uuid,
+ int svc_inst,
+ unsigned char *uuid,
+ int instance_id,
+ char *remote_address)
+{
+ GSList *l;
+ GSList *ll;
+ bt_gatt_client_h client;
+ bt_gatt_client_s *client_s;
+ bt_gatt_service_s *svc;
+ bt_gatt_characteristic_s *chr;
+
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+ char svc_uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ __uuid_hex_to_string(svc_uuid, svc_uuid_string);
+ __uuid_hex_to_string(uuid, uuid_string) ;
+
+ BT_INFO("Address [%s] Char UUID [%s]", remote_address, uuid_string);
+
+
+ client = __find_gatt_client(remote_address);
+ if (client == NULL) {
+ BT_ERR("Cannot find client [%s]", remote_address);
+ return NULL;
+ }
+
+ client_s = (bt_gatt_client_s *)client;
+ for (l = client_s->services; l; l = g_slist_next(l)) {
+ svc = (bt_gatt_service_s *)l->data;
+
+ if (svc == NULL)
+ continue;
+
+ if (g_ascii_strcasecmp(svc->uuid, svc_uuid_string) == 0 &&
+ svc->instance_id == svc_inst) {
+
+ for (ll = svc->characteristics; ll; ll = g_slist_next(ll)) {
+ chr = (bt_gatt_characteristic_s *)ll->data;
+
+ if (chr == NULL)
+ continue;
+ if (g_ascii_strcasecmp(chr->uuid, uuid_string) == 0 &&
+ chr->instance_id == instance_id) {
+ return chr;
+ }
+ }
+ }
+ }
+ return NULL;
+} /* LCOV_EXCL_STOP */
+
+static bt_gatt_descriptor_s* __gatt_get_descriptor_handle(
+ unsigned char *svc_uuid,
+ int svc_inst,
+ unsigned char *char_uuid,
+ int char_inst,
+ unsigned char *uuid,
+ int instance_id,
+ char *remote_address)
+{
+ GSList *l;
+ GSList *ll;
+ GSList *lll;
+ bt_gatt_client_h client;
+ bt_gatt_client_s *client_s;
+ bt_gatt_service_s *svc;
+ bt_gatt_characteristic_s *chr;
+ bt_gatt_descriptor_s *desc;
+
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+ char svc_uuid_string[BLUETOOTH_UUID_STRING_MAX];
+ char char_uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ __uuid_hex_to_string(uuid, uuid_string);
+ __uuid_hex_to_string(svc_uuid, svc_uuid_string);
+ __uuid_hex_to_string(char_uuid, char_uuid_string);
+
+ BT_INFO("Address [%s] Descriptor UUID [%s]", remote_address, uuid_string);
+
+
+ client = __find_gatt_client(remote_address);
+ if (client == NULL) {
+ BT_ERR("Cannot find client [%s]", remote_address);
+ return NULL;
+ }
+
+ client_s = (bt_gatt_client_s *)client;
+ for (l = client_s->services; l; l = g_slist_next(l)) {
+ svc = (bt_gatt_service_s *)l->data;
+
+ if (svc == NULL)
+ continue;
+
+ if (g_ascii_strcasecmp(svc->uuid, svc_uuid_string) == 0 &&
+ svc->instance_id == svc_inst) {
+
+ for (ll = svc->characteristics; ll; ll = g_slist_next(ll)) {
+ chr = (bt_gatt_characteristic_s *)ll->data;
+
+ if (chr == NULL)
+ continue;
+
+ if (g_ascii_strcasecmp(chr->uuid, char_uuid_string) == 0 &&
+ chr->instance_id == char_inst) {
+
+ for (lll = chr->descriptors; lll; lll = g_slist_next(lll)) {
+ desc = (bt_gatt_descriptor_s *)lll->data;
+
+ if (desc == NULL)
+ continue;
+
+ if (g_ascii_strcasecmp(desc->uuid, uuid_string) == 0 &&
+ desc->instance_id == instance_id) {
+ return desc;
+ }
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+} /* LCOV_EXCL_STOP */
+
+static void __gatt_value_changed_cb(unsigned char *uuid, char *remote_address,
+ char *value, int value_length, void *user_data)
+{
+ GSList *l;
+ GSList *ll;
+ bt_gatt_client_h client;
+ bt_gatt_client_s *client_s;
+ bt_gatt_service_s *svc;
+ bt_gatt_characteristic_s *chr;
+ BT_INFO("+");
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+ __uuid_hex_to_string(uuid, uuid_string) ;
+
+ BT_INFO("Address [%s] Char UUID [%s]", remote_address, uuid_string);
+
+ client = __find_gatt_client(remote_address);
+ if (client == NULL) {
+ BT_ERR("Cannot find client [%s]", remote_address);
+ return;
+ }
+
+ client_s = (bt_gatt_client_s *)client;
+ for (l = client_s->services; l; l = g_slist_next(l)) {
+ svc = (bt_gatt_service_s *)l->data;
+ for (ll = svc->characteristics; ll; ll = g_slist_next(ll)) {
+ chr = (bt_gatt_characteristic_s *)ll->data;
+ if (g_ascii_strcasecmp(chr->uuid, uuid_string) == 0) {
+ if (chr->value_changed_cb)
+ chr->value_changed_cb(chr, value,
+ value_length,
+ chr->value_changed_user_data);
+ bt_gatt_set_value(chr, value, value_length);
+ return;
+ }
+ }
+ }
+} /* LCOV_EXCL_STOP */
+#else
static void __value_changed_cb(char *char_path,
- char *value, int value_length, void *user_data)
+ char *value, int value_length, void *user_data)
{
GSList *l;
GSList *ll;
@@ -3042,6 +4187,8 @@ static void __value_changed_cb(char *char_path,
bt_gatt_characteristic_s *chr;
char remote_address[BT_ADDR_STR_LEN + 1] = { 0, };
+ BT_DBG("%s", char_path);
+
if (__get_bdaddr_from_path(char_path, remote_address) == FALSE) {
BT_ERR("Cannot get addr from path : %s", char_path);
return;
@@ -3074,37 +4221,78 @@ static void __value_changed_cb(char *char_path,
}
}
} /* LCOV_EXCL_STOP */
+#endif
int bt_gatt_client_set_characteristic_value_changed_cb(bt_gatt_h characteristic,
bt_gatt_client_characteristic_value_changed_cb callback,
void *user_data)
{
int ret;
- char *name = NULL;
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)characteristic;
- BT_CHECK_GATT_CLIENT_SUPPORT();
+#ifdef TIZEN_GATT_CLIENT
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t chr_handle;
+ bt_gatt_service_s *service_s;
+ bt_gatt_client_s *client_s;
+#endif
+
+ BT_INFO("+");
+
+ BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(characteristic);
BT_CHECK_INPUT_PARAMETER(callback);
- bt_gatt_service_s *svc = (bt_gatt_service_s *)chr->parent;
-
chr->value_changed_cb = callback;
chr->value_changed_user_data = user_data;
+#ifdef TIZEN_GATT_CLIENT
+
+ service_s = (bt_gatt_service_s*)chr->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+
+ /* Create Service and Charc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(chr->uuid, chr_handle.uuid);
+ chr_handle.instance_id = chr->instance_id;
+#endif
+
+ BT_INFO("Characteristic properties [%d] charc UUID [%s]",
+ chr->properties, chr->uuid);
+
if (chr->properties &
- (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
- bt_get_uuid_name(svc->uuid, &name);
+ (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
+
+#ifdef TIZEN_GATT_CLIENT
+ ret = _bt_get_error_code(bluetooth_gatt_client_watch_characteristics(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ client_s->client_id,
+ TRUE));
+#else
ret = _bt_get_error_code(bluetooth_gatt_watch_characteristics(
- chr->path, name));
- g_free(name);
+ chr->path));
+
+
+#endif
if (ret != BT_ERROR_NONE)
BT_ERR("%s(0x%08x)",
- _bt_convert_error_to_string(ret), ret);
- else
+ _bt_convert_error_to_string(ret), ret);
+ else {
+#ifdef TIZEN_GATT_CLIENT
+ BT_INFO("Set Char val changed callback at index [%d]", BT_EVENT_GATT_CLIENT_VALUE_CHANGED);
+ _bt_set_cb(BT_EVENT_GATT_CLIENT_VALUE_CHANGED,
+ __gatt_value_changed_cb, NULL);
+#else
_bt_set_cb(BT_EVENT_GATT_CLIENT_VALUE_CHANGED,
__value_changed_cb, NULL);
+#endif
+ BT_INFO("Char value changed callback registsred successfully");
+ }
} else {
BT_DBG("notify or indication is not supported");
ret = BT_ERROR_NOT_SUPPORTED;
@@ -3118,14 +4306,43 @@ int bt_gatt_client_unset_characteristic_value_changed_cb(bt_gatt_h characteristi
int ret;
bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)characteristic;
+#ifdef TIZEN_GATT_CLIENT
+ bt_gatt_handle_property_t svc_handle;
+ bt_gatt_handle_property_t chr_handle;
+ bt_gatt_service_s *service_s;
+ bt_gatt_client_s *client_s;
+#endif
+
BT_CHECK_GATT_CLIENT_SUPPORT();
BT_CHECK_INIT_STATUS();
BT_CHECK_INPUT_PARAMETER(characteristic); /* LCOV_EXCL_START */
+ BT_INFO("+");
+
+#ifdef TIZEN_GATT_CLIENT
+ service_s = (bt_gatt_service_s*)chr->parent;
+ client_s = (bt_gatt_client_s*)service_s->parent;
+
+ /* Create Service and Charc handles */
+ __bt_string_to_uuid_hex(service_s->uuid, svc_handle.uuid);
+ svc_handle.instance_id = service_s->instance_id;
+
+ __bt_string_to_uuid_hex(chr->uuid, chr_handle.uuid);
+ chr_handle.instance_id = chr->instance_id;
+#endif
if (chr->properties &
- (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
+ (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
+#ifdef TIZEN_GATT_CLIENT
+ ret = _bt_get_error_code(bluetooth_gatt_client_watch_characteristics(
+ client_s->remote_address,
+ &svc_handle,
+ &chr_handle,
+ client_s->client_id,
+ FALSE));
+#else
ret = _bt_get_error_code(
- bluetooth_gatt_unwatch_characteristics(chr->path));
+ bluetooth_gatt_unwatch_characteristics(chr->path));
+#endif
if (ret != BT_ERROR_NONE)
BT_ERR("%s(0x%08x)",
_bt_convert_error_to_string(ret), ret);
@@ -3154,6 +4371,7 @@ int bt_gatt_client_get_service(bt_gatt_client_h client, const char *uuid,
BT_CHECK_INPUT_PARAMETER(uuid);
BT_CHECK_INPUT_PARAMETER(service);
+ BT_INFO("Get Service from UUID [%s]", uuid);
ret = __get_gatt_handle_by_uuid(client_s->services, uuid, &gatt_handle);
if (ret == BT_ERROR_NONE && gatt_handle != NULL) {
*service = gatt_handle;
@@ -3181,6 +4399,7 @@ int bt_gatt_client_foreach_services(bt_gatt_client_h client,
total = g_slist_length(client_s->services); /* LCOV_EXCL_LINE */
for (l = client_s->services; l; l = g_slist_next(l)) { /* LCOV_EXCL_LINE */
+ BT_INFO("Call one service callback");
if (!callback(total, index++,
(bt_gatt_h)l->data, user_data)) /* LCOV_EXCL_LINE */
break;
@@ -3209,7 +4428,11 @@ int bt_gatt_client_set_service_changed_cb(bt_gatt_client_h client,
}
_bt_convert_address_to_hex(&bd_addr, client_s->remote_address);
+#ifdef TIZEN_GATT_CLIENT
+ ret = _bt_get_error_code(bluetooth_gatt_client_set_service_change_watcher(&bd_addr, TRUE));
+#else
ret = _bt_get_error_code(bluetooth_gatt_set_service_change_watcher(&bd_addr, TRUE));
+#endif
if (ret == BT_ERROR_NONE) {
BT_INFO("Service Changed callback registered");
@@ -3233,7 +4456,11 @@ int bt_gatt_client_unset_service_changed_cb(bt_gatt_client_h client)
BT_CHECK_INPUT_PARAMETER(client);
_bt_convert_address_to_hex(&bd_addr, client_s->remote_address);
+#ifdef TIZEN_GATT_CLIENT
+ ret = _bt_get_error_code(bluetooth_gatt_client_set_service_change_watcher(&bd_addr, FALSE));
+#else
ret = _bt_get_error_code(bluetooth_gatt_set_service_change_watcher(&bd_addr, FALSE));
+#endif
if (ret == BT_ERROR_NONE) {
BT_INFO("Service Changed callback unregistered [%s]", client_s->remote_address);
client_s->service_changed_cb = NULL;
@@ -3245,6 +4472,415 @@ int bt_gatt_client_unset_service_changed_cb(bt_gatt_client_h client)
return BT_ERROR_NONE;
}
+#ifdef TIZEN_GATT_CLIENT
+void _bt_handle_gatt_client_char_read_completed_event(int result,
+ void *resp)
+{
+ bt_gatt_client_request_completed_cb cb = NULL;
+ void *user_data = NULL;
+ bt_gatt_service_s *svc;
+ bt_gatt_characteristic_s *chr;
+
+ bt_gatt_char_property_t *char_prop1; /* Pass Case */
+ bluetooth_gatt_client_char_prop_info_t *char_prop2; /* Fail Case */
+ bt_gatt_client_s *client_s;
+
+ bt_gatt_h gatt_handle = NULL;
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+ if (result != BLUETOOTH_ERROR_NONE) {
+ char_prop2 = (bluetooth_gatt_client_char_prop_info_t*)resp;
+ char *device_addr = NULL;
+ _bt_convert_address_to_string(&device_addr, &char_prop2->device_address);
+
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (!client_s) {
+ BT_ERR("GATT client not found against address [%s]", device_addr);
+ g_free(device_addr);
+ return;
+ }
+ chr = __gatt_get_characteristic_handle(char_prop2->svc.uuid,
+ char_prop2->svc.instance_id,
+ char_prop2->characteristic.uuid,
+ char_prop2->characteristic.instance_id,
+ device_addr);
+
+ __uuid_hex_to_string(char_prop2->characteristic.uuid, uuid_string);
+ BT_INFO("GATT Char read completed Failed event UUID [%s] address [%s]",
+ uuid_string, device_addr);
+ g_free(device_addr);
+ if (!chr) {
+ BT_ERR("No characteristic found");
+ return;
+ }
+ } else {
+ char_prop1 = (bt_gatt_char_property_t *)resp;
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(char_prop1->address);
+ if (!client_s) {
+ BT_ERR("GATT client not found against address [%s]",
+ char_prop1->address);
+ return;
+ }
+ chr = __gatt_get_characteristic_handle(
+ char_prop1->svc_prop.uuid,
+ char_prop1->svc_prop.instance_id,
+ char_prop1->prop.uuid,
+ char_prop1->prop.instance_id,
+ char_prop1->address);
+
+ if (!chr) {
+ BT_ERR("No characteristic found");
+ return;
+ }
+
+ __uuid_hex_to_string(char_prop1->prop.uuid, uuid_string);
+ BT_INFO("GATT Char read completed Success event UUID [%s] address [%s]",
+ uuid_string, char_prop1->address);
+ }
+
+ cb = chr->read_cb;
+ user_data = chr->read_user_data;
+
+ chr->read_cb = NULL;
+ chr->read_user_data = NULL;
+
+ if (!chr->parent) {
+ BT_INFO("Already destroyed handle : %p", chr);
+ if (!chr->write_cb)
+ g_free(chr);
+ return;
+ }
+
+ svc = (bt_gatt_service_s*) chr->parent;
+
+ __get_gatt_handle_by_uuid(svc->characteristics, uuid_string, &gatt_handle);
+
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_INFO("Set value");
+ bt_gatt_set_value(gatt_handle,
+ (char *)char_prop1->value, (int)char_prop1->val_len);
+ }
+
+ if (cb) {
+ BT_INFO("callback present");
+ cb(result, gatt_handle, user_data);
+ } else
+ BT_ERR("Callback not present!!!");
+ return;
+}
+
+void _bt_handle_gatt_client_desc_read_completed_event(int result,
+ void *resp)
+{
+ void *user_data = NULL;
+ bt_gatt_h gatt_handle = NULL;
+ bt_gatt_characteristic_s *chr;
+ bt_gatt_client_request_completed_cb cb = NULL;
+
+ bt_gatt_char_descriptor_property_t *desc_prop1; /* Pass Case */
+ bluetooth_gatt_client_desc_prop_info_t *desc_prop2; /* Fail Case */
+ bt_gatt_descriptor_s *desc;
+ bt_gatt_client_s *client_s;
+
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+ if (result != BLUETOOTH_ERROR_NONE) {
+ desc_prop2 = (bluetooth_gatt_client_desc_prop_info_t*)resp;
+ char *device_addr = NULL;
+ _bt_convert_address_to_string(&device_addr, &desc_prop2->device_address);
+
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]", device_addr);
+ g_free(device_addr);
+ return;
+ }
+ desc = __gatt_get_descriptor_handle(desc_prop2->svc.uuid,
+ desc_prop2->svc.instance_id,
+ desc_prop2->characteristic.uuid,
+ desc_prop2->characteristic.instance_id,
+ desc_prop2->descriptor.uuid,
+ desc_prop2->descriptor.instance_id,
+ device_addr);
+
+
+ __uuid_hex_to_string(desc_prop2->descriptor.uuid, uuid_string);
+ BT_INFO("GATT Desc read completed Failed event UUID [%s] address [%s]",
+ uuid_string, device_addr);
+
+ g_free(device_addr);
+ if (!desc) {
+ BT_ERR("No Descriptor found");
+ return;
+ }
+ } else {
+ desc_prop1 = (bt_gatt_char_descriptor_property_t *)resp;
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(desc_prop1->address);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]",
+ desc_prop1->address);
+ return;
+ }
+ desc = __gatt_get_descriptor_handle(desc_prop1->svc_prop.uuid,
+ desc_prop1->svc_prop.instance_id,
+ desc_prop1->char_prop.uuid,
+ desc_prop1->char_prop.instance_id,
+ desc_prop1->prop.uuid,
+ desc_prop1->prop.instance_id,
+ desc_prop1->address);
+ if (!desc) {
+ BT_ERR("No Descriptor found");
+ return;
+ }
+ __uuid_hex_to_string(desc_prop1->prop.uuid, uuid_string);
+ BT_INFO("GATT Desc read completed Success event UUID [%s] address [%s]",
+ uuid_string, desc_prop1->address);
+ }
+
+ cb = desc->read_cb;
+ user_data = desc->read_user_data;
+
+ desc->read_cb = NULL;
+ desc->read_user_data = NULL;
+
+ if (!desc->parent) {
+ BT_INFO("Already destroyed handle : %p", desc);
+ if (!desc->write_cb)
+ g_free(desc);
+ return;
+ }
+
+ chr = (bt_gatt_characteristic_s*)desc->parent;
+
+ __get_gatt_handle_by_uuid(chr->descriptors, uuid_string, &gatt_handle);
+
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_INFO("Set value");
+ bt_gatt_set_value(gatt_handle,
+ (char *)desc_prop1->value, (int)desc_prop1->val_len);
+ }
+
+ if (cb) {
+ BT_INFO("callback present");
+ cb(result, gatt_handle, user_data);
+ } else
+ BT_ERR("Callback not present!!!!");
+
+ return;
+}
+
+void _bt_handle_gatt_client_char_write_completed_event(int result,
+ void *resp)
+{
+ bt_gatt_client_request_completed_cb cb = NULL;
+ void *user_data = NULL;
+ bt_gatt_service_s *svc;
+ bt_gatt_h gatt_handle = NULL;
+
+ bt_gatt_char_property_t *char_prop1; /* Pass Case */
+ bluetooth_gatt_client_char_prop_info_t *char_prop2; /* Fail Case */
+ bt_gatt_characteristic_s *chr;
+ bt_gatt_client_s *client_s;
+
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+
+ BT_INFO("GATT Char Write Clalback result [%d]", result);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ char_prop2 = (bluetooth_gatt_client_char_prop_info_t*)resp;
+ char *device_addr = NULL;
+ _bt_convert_address_to_string(&device_addr, &char_prop2->device_address);
+
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]", device_addr);
+ g_free(device_addr);
+ return;
+ }
+ chr = __gatt_get_characteristic_handle(char_prop2->svc.uuid,
+ char_prop2->svc.instance_id,
+ char_prop2->characteristic.uuid,
+ char_prop2->characteristic.instance_id,
+ device_addr);
+
+ __uuid_hex_to_string(char_prop2->characteristic.uuid, uuid_string);
+ BT_INFO("GATT Char Write completed Failed event UUID [%s] address [%s]",
+ uuid_string, device_addr);
+ g_free(device_addr);
+ if (!chr) {
+ BT_ERR("No characteristic found");
+ return;
+ }
+ } else {
+ char_prop1 = (bt_gatt_char_property_t *)resp;
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(char_prop1->address);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]",
+ char_prop1->address);
+ return;
+ }
+ chr = __gatt_get_characteristic_handle(
+ char_prop1->svc_prop.uuid,
+ char_prop1->svc_prop.instance_id,
+ char_prop1->prop.uuid,
+ char_prop1->prop.instance_id,
+ char_prop1->address);
+
+ if (!chr) {
+ BT_ERR("No characteristic found");
+ return;
+ }
+
+ __uuid_hex_to_string(char_prop1->prop.uuid, uuid_string);
+ BT_INFO("GATT Char Write completed Success event UUID [%s] address [%s]",
+ uuid_string, char_prop1->address);
+ }
+
+ cb = chr->write_cb;
+ user_data = chr->write_user_data;
+
+ chr->write_cb = NULL;
+ chr->write_user_data = NULL;
+
+ if (!chr->parent) {
+ BT_INFO("Already destroyed handle : %p", chr);
+ if (!chr->read_cb)
+ g_free(chr);
+ return;
+ }
+
+ svc = (bt_gatt_service_s*) chr->parent;
+
+ __get_gatt_handle_by_uuid(svc->characteristics, uuid_string, &gatt_handle);
+
+ if (cb)
+ cb(result, gatt_handle, user_data);
+ else
+ BT_ERR("Callback not present!!!");
+ return;
+}
+
+void _bt_handle_gatt_client_desc_write_completed_event(int result,
+ void *resp)
+{
+ void *user_data = NULL;
+ bt_gatt_client_request_completed_cb cb = NULL;
+ bt_gatt_characteristic_s *chr;
+ bt_gatt_h gatt_handle;
+
+ bt_gatt_char_descriptor_property_t *desc_prop1; /* Pass Case */
+ bluetooth_gatt_client_desc_prop_info_t *desc_prop2; /* Fail Case */
+ bt_gatt_descriptor_s *desc;
+ bt_gatt_client_s *client_s;
+
+ char uuid_string[BLUETOOTH_UUID_STRING_MAX];
+
+ if (resp == NULL) {
+ BT_ERR("GATT Client response data is NULL");
+ return;
+ }
+ if (result != BLUETOOTH_ERROR_NONE) {
+ desc_prop2 = (bluetooth_gatt_client_desc_prop_info_t*)resp;
+ char *device_addr = NULL;
+ _bt_convert_address_to_string(&device_addr, &desc_prop2->device_address);
+
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(device_addr);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]", device_addr);
+ g_free(device_addr);
+ return;
+ }
+ desc = __gatt_get_descriptor_handle(desc_prop2->svc.uuid,
+ desc_prop2->svc.instance_id,
+ desc_prop2->characteristic.uuid,
+ desc_prop2->characteristic.instance_id,
+ desc_prop2->descriptor.uuid,
+ desc_prop2->descriptor.instance_id,
+ device_addr);
+
+ __uuid_hex_to_string(desc_prop2->descriptor.uuid, uuid_string);
+ BT_INFO("GATT Desc Write completed Failed event UUID [%s] address [%s]",
+ uuid_string, device_addr);
+
+ g_free(device_addr);
+ if (!desc) {
+ BT_ERR("No Descriptor found");
+ return;
+ }
+ } else {
+ desc_prop1 = (bt_gatt_char_descriptor_property_t *)resp;
+ /* Return if Client not found */
+ client_s = (bt_gatt_client_s *)_bt_gatt_get_client(desc_prop1->address);
+ if (!client_s) {
+ BT_INFO("GATT client not found against address [%s]",
+ desc_prop1->address);
+ return;
+ }
+ desc = __gatt_get_descriptor_handle(desc_prop1->svc_prop.uuid,
+ desc_prop1->svc_prop.instance_id,
+ desc_prop1->char_prop.uuid,
+ desc_prop1->char_prop.instance_id,
+ desc_prop1->prop.uuid,
+ desc_prop1->prop.instance_id,
+ desc_prop1->address);
+ if (!desc) {
+ BT_ERR("No Descriptor found");
+ return;
+ }
+ __uuid_hex_to_string(desc_prop1->prop.uuid, uuid_string);
+ BT_INFO("GATT Desc read completed Success event UUID [%s] address [%s]",
+ uuid_string, desc_prop1->address);
+ }
+
+ cb = desc->write_cb;
+ user_data = desc->write_user_data;
+
+ desc->write_cb = NULL;
+ desc->write_user_data = NULL;
+
+ if (!desc->parent) {
+ BT_INFO("Already destroyed handle : %p", desc);
+ if (!desc->read_cb)
+ g_free(desc);
+ return;
+ }
+
+ chr = (bt_gatt_characteristic_s*)desc->parent;
+
+ BT_INFO("Total descriptors char has [%d]", g_slist_length(chr->descriptors));
+
+ __get_gatt_handle_by_uuid(chr->descriptors, uuid_string, &gatt_handle);
+
+ if (cb)
+ cb(result, gatt_handle, user_data);
+ else
+ BT_ERR("Callback not present!!!");
+
+ return;
+}
+#endif
+
+
int bt_gatt_client_request_att_mtu_change(bt_gatt_client_h client, unsigned int mtu)
{
int ret;