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;
} \
}
+#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)
{
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);
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;
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;
return BT_ERROR_NONE;
}
+#endif
int _bt_gatt_client_update_include_services(bt_gatt_h service)
{
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;
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;
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)
{
_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);
{
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);
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;
- if (chr->role == BT_GATT_ROLE_CLIENT && chr->value_changed_cb &&
- chr->properties &
- (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
- BT_DBG("Unwatch characteristic");
- ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics(
- chr->path));
- if (ret != BT_ERROR_NONE)
+ 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 &
+ (BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_INDICATE)) {
+ BT_DBG("Unwatch characteristic");
+ ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics(
+ chr->path));
+ if (ret != BT_ERROR_NONE)
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);
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) {
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)
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);
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)
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 {
*val = g_memdup(value, value_length);
*val_len = value_length;
+ BT_INFO("Value is set");
return BT_ERROR_NONE; /* LCOV_EXCL_STOP */
}
*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;
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;
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 {
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 {
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)
#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;
}
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;
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;
}
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;
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");
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);
}
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;
return BT_ERROR_NONE;
}
+
/* LCOV_EXCL_START */
int bt_gatt_characteristic_create(const char *uuid, int permissions,
int properties, const char *value,
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
else
chr->uuid = g_strdup(uuid);
#endif
+
if (chr->uuid == NULL) {
ret = BT_ERROR_OUT_OF_MEMORY;
goto fail;
*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:
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;
}
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)
{
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");
int total;
int i;
+ BT_INFO("+");
BT_CHECK_GATT_SUPPORT();
BT_CHECK_INIT_STATUS();
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);
}
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)) {
return BT_ERROR_NONE;
}
+
/* LCOV_EXCL_START */
int bt_gatt_descriptor_create(const char *uuid, int permissions,
const char *value, int value_length,
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
else
desc->uuid = g_strdup(uuid);
#endif
+
if (desc->uuid == NULL) {
ret = BT_ERROR_OUT_OF_MEMORY;
goto fail;
*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:
return ret;
}
+
/* LCOV_EXCL_STOP */
int bt_gatt_descriptor_get_characteristic(bt_gatt_h descriptor,
bt_gatt_h *characteristic)
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;
return BT_ERROR_NONE;
}
- BT_DBG("Gatt-service already initialized");
+ BT_INFO("Gatt-service already initialized");
return ret;
}
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)) {
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);
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;
}
*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;
}
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);
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;
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;
}
#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;
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.");
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,
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();
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();
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
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;
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)
{
return ret; /* LCOV_EXCL_STOP */
}
+#endif
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 */
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;
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;
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 {
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 {
BT_ERR("Invalid handle type for read ");
}
+ BT_INFO("Result [%d]", ret);
return ret; /* LCOV_EXCL_STOP */
}
-
-int bt_gatt_client_write_value(bt_gatt_h gatt_handle,
+#else
+int bt_gatt_client_read_value(bt_gatt_h gatt_handle,
bt_gatt_client_request_completed_cb callback, void *user_data)
{
- bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
- bt_gatt_property_e write_prop = BT_GATT_PROPERTY_WRITE;
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); /* LCOV_EXCL_START */
+ 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->write_cb) {
- BT_ERR("write request is now in progress");
+ if (chr->read_cb) {
+ BT_ERR("read request is now in progress");
return BT_ERROR_NOW_IN_PROGRESS;
}
- ret = __get_write_prop(chr->write_type, &write_prop);
- if (ret != BT_ERROR_NONE)
- return BT_ERROR_OPERATION_FAILED;
-
- ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
- chr->path, (guint8 *)chr->value,
- chr->value_length, write_prop,
- gatt_handle));
+ ret = _bt_get_error_code(
+ bluetooth_gatt_read_characteristic_value(chr->path, gatt_handle));
if (ret == BT_ERROR_NONE) {
- chr->write_cb = callback;
- chr->write_user_data = user_data;
+ 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->write_cb) {
- BT_ERR("write request is now in progress");
+ 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_write_descriptor_value(
- desc->path, (guint8 *)desc->value,
- desc->value_length, gatt_handle));
+ ret = _bt_get_error_code(
+ bluetooth_gatt_read_descriptor_value(desc->path, gatt_handle));
if (ret == BT_ERROR_NONE) {
- desc->write_cb = callback;
- desc->write_user_data = user_data;
+ desc->read_cb = callback;
+ desc->read_user_data = user_data;
} else {
BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
}
} else {
- BT_ERR("Invalid handle type for write");
ret = BT_ERROR_INVALID_PARAMETER;
+ BT_ERR("Invalid handle type for read ");
}
- return ret;
+ return ret; /* LCOV_EXCL_STOP */
}
+#endif
-static bt_gatt_client_h __find_gatt_client(const char *remote_address)
+#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)
{
- GSList *l = NULL;
+ int ret = BT_ERROR_NONE;
+ bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
- for (l = gatt_client_list; l; l = g_slist_next(l)) {
- bt_gatt_client_s *client_s = l->data;
+ 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;
- if (!g_strcmp0(client_s->remote_address, remote_address))
- return (const bt_gatt_client_h)l->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;
}
- return NULL;
-}
+ if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
-static gboolean __get_bdaddr_from_path(const char *path, char *addr)
-{
- int i;
- char *tmp;
+ 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)
+{
+ bt_gatt_common_s *c = (bt_gatt_common_s *)gatt_handle;
+ bt_gatt_property_e write_prop = BT_GATT_PROPERTY_WRITE;
+ int ret = BT_ERROR_NONE;
+
+ BT_CHECK_GATT_CLIENT_SUPPORT();
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(gatt_handle); /* LCOV_EXCL_START */
+
+ if (c->type == BT_GATT_TYPE_CHARACTERISTIC) {
+ bt_gatt_characteristic_s *chr = (bt_gatt_characteristic_s *)gatt_handle;
+
+ if (chr->write_cb) {
+ BT_ERR("write request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
+ ret = __get_write_prop(chr->write_type, &write_prop);
+ if (ret != BT_ERROR_NONE)
+ return BT_ERROR_OPERATION_FAILED;
+
+ ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_by_type(
+ chr->path, (guint8 *)chr->value,
+ chr->value_length, write_prop,
+ gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ chr->write_cb = callback;
+ chr->write_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->write_cb) {
+ BT_ERR("write request is now in progress");
+ return BT_ERROR_NOW_IN_PROGRESS;
+ }
+
+ ret = _bt_get_error_code(bluetooth_gatt_write_descriptor_value(
+ desc->path, (guint8 *)desc->value,
+ desc->value_length, gatt_handle));
+ if (ret == BT_ERROR_NONE) {
+ desc->write_cb = callback;
+ desc->write_user_data = user_data;
+ } else {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ } else {
+ BT_ERR("Invalid handle type for write");
+ ret = BT_ERROR_INVALID_PARAMETER;
+ }
+
+ return ret;
+}
+#endif
+
+static bt_gatt_client_h __find_gatt_client(const char *remote_address)
+{
+ GSList *l = NULL;
+
+ for (l = gatt_client_list; l; l = g_slist_next(l)) {
+ bt_gatt_client_s *client_s = l->data;
+
+ if (!g_strcmp0(client_s->remote_address, remote_address))
+ return (const bt_gatt_client_h)l->data;
+ }
+
+ return NULL;
+}
+
+#ifndef TIZEN_GATT_CLIENT
+static gboolean __get_bdaddr_from_path(const char *path, char *addr)
+{
+ int i;
+ char *tmp;
/*
* e.g.
}
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;
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;
}
}
} /* 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;
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);
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;
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;
}
_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");
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;
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;