2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <glib/gprintf.h>
25 #include "bt-common.h"
26 #include "bt-event-handler.h"
27 #include "bt-gatt-client.h"
28 #include "bt-internal-types.h"
29 #include "bt-request-sender.h"
31 #ifdef TIZEN_GATT_CLIENT
32 #include "bluetooth-gatt-client-api.h"
33 #include <arpa/inet.h>
36 #define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
44 } char_descriptor_type_t;
46 static GSList *service_monitor_list = NULL;
48 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
52 BT_CHECK_PARAMETER(svc_pty, return);
54 #ifdef TIZEN_GATT_CLIENT
55 g_free(svc_pty->uuid);
57 g_free(svc_pty->uuid);
58 g_free(svc_pty->handle);
59 g_strfreev(svc_pty->include_handles.handle);
60 g_strfreev(svc_pty->char_handle.handle);
63 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
66 return BLUETOOTH_ERROR_NONE;
69 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
73 BT_CHECK_PARAMETER(char_pty, return);
75 g_free(char_pty->uuid);
76 g_free(char_pty->name);
77 g_free(char_pty->description);
78 g_free(char_pty->val);
79 #ifndef TIZEN_GATT_CLIENT
80 g_free(char_pty->handle);
81 g_strfreev(char_pty->char_desc_handle.handle);
84 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
87 return BLUETOOTH_ERROR_NONE;
90 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
94 BT_CHECK_PARAMETER(desc_pty, return);
96 g_free(desc_pty->uuid);
97 g_free(desc_pty->val);
98 #ifndef TIZEN_GATT_CLIENT
99 g_free(desc_pty->handle);
102 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
105 return BLUETOOTH_ERROR_NONE;
108 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
110 gchar *gp_path = NULL;
117 path = g_malloc0((gp->len + 1) * sizeof(char *));
119 for (i = 0; i < gp->len; i++) {
120 gp_path = g_ptr_array_index(gp, i);
121 path[i] = g_strdup(gp_path);
122 // BT_DBG("path[%d] : [%s]", i, path[i]);
128 gboolean _bluetooth_gatt_check_service_change_watcher_address(
129 const bluetooth_device_address_t *device_addr)
132 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
133 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
135 _bt_convert_addr_type_to_string(device_address,
136 (unsigned char *)device_addr->addr);
138 for (l = service_monitor_list; l != NULL; l = l->next) {
139 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
140 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
141 bluetooth_device_address_t *addr = l->data;
143 _bt_convert_addr_type_to_string(device_address2,
144 (unsigned char *)addr->addr);
145 _bt_convert_addr_string_to_secure_string(secure_address,
147 _bt_convert_addr_string_to_secure_string(secure_address2,
149 BT_INFO("service_monitor_list [%s] - Input [%s]",
150 secure_address2, secure_address);
152 if (!memcmp(device_addr, addr,
153 sizeof(bluetooth_device_address_t)))
160 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
161 const bluetooth_device_address_t *address, gboolean enable)
164 bluetooth_device_address_t *addr = NULL;
165 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
167 _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
168 BT_INFO("Set watcher for %s with %d", secure_address, enable);
170 if (enable == TRUE) {
171 if (_bluetooth_gatt_check_service_change_watcher_address(address)
173 BT_INFO("The watcher is already set");
174 return BLUETOOTH_ERROR_NONE;
177 if (service_monitor_list == NULL)
178 _bt_register_manager_subscribe_signal(TRUE);
180 addr = g_malloc0(sizeof(bluetooth_device_address_t));
181 memcpy(addr, address, sizeof(bluetooth_device_address_t));
183 service_monitor_list =
184 g_slist_append(service_monitor_list, addr);
186 for (l = service_monitor_list; l != NULL; l = l->next) {
189 if (!memcmp(address, addr,
190 sizeof(bluetooth_device_address_t))) {
191 service_monitor_list =
192 g_slist_remove(service_monitor_list, addr);
198 if (service_monitor_list == NULL)
199 _bt_register_manager_subscribe_signal(FALSE);
202 return BLUETOOTH_ERROR_NONE;
205 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
206 bt_gatt_service_property_t *service)
208 GDBusProxy *properties_proxy = NULL;
209 GError *error = NULL;
210 GVariant *result = NULL;
211 GDBusConnection *g_conn;
213 char *char_handle = NULL;
214 GPtrArray *gp_array = NULL ;
215 GVariantIter *property_iter, *char_iter = NULL;
219 BT_CHECK_PARAMETER(service_handle, return);
220 BT_CHECK_PARAMETER(service, return);
221 BT_CHECK_ENABLED(return);
223 g_conn = _bt_gdbus_get_system_gconn();
224 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
226 properties_proxy = g_dbus_proxy_new_sync(g_conn,
227 G_DBUS_PROXY_FLAGS_NONE, NULL,
230 BT_PROPERTIES_INTERFACE,
233 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
235 result = g_dbus_proxy_call_sync(properties_proxy,
237 g_variant_new("(s)", GATT_SERV_INTERFACE),
238 G_DBUS_CALL_FLAGS_NONE,
245 BT_ERR("Fail to get properties (Error: %s)", error->message);
246 g_clear_error(&error);
248 BT_ERR("Fail to get properties");
249 g_object_unref(properties_proxy);
250 return BLUETOOTH_ERROR_INTERNAL;
253 g_variant_get(result, "(a{sv})", &property_iter);
255 memset(service, 0, sizeof(bt_gatt_service_property_t));
257 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
258 if (!g_strcmp0(key, "UUID")) {
260 service->uuid = g_variant_dup_string(value, &len);
261 bluetooth_get_uuid_name(service->uuid, &name);
262 BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
264 } else if (!g_strcmp0(key, "Primary")) {
265 service->primary = g_variant_get_boolean(value);
267 } else if (!g_strcmp0(key, "Includes")) {
268 g_variant_get(value, "ao", &char_iter);
269 if (char_iter != NULL) {
270 gp_array = g_ptr_array_new();
271 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
272 g_ptr_array_add(gp_array, (gpointer)char_handle);
274 if (gp_array->len != 0) {
275 service->include_handles.count = gp_array->len;
276 service->include_handles.handle =
277 __get_string_array_from_gptr_array(gp_array);
279 g_ptr_array_free(gp_array, TRUE);
280 g_variant_iter_free(char_iter);
282 } else if (!g_strcmp0(key, "Characteristics")) {
283 g_variant_get(value, "ao", &char_iter);
284 if (char_iter != NULL) {
285 gp_array = g_ptr_array_new();
286 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
287 g_ptr_array_add(gp_array, (gpointer)char_handle);
289 if (gp_array->len != 0) {
290 service->char_handle.count = gp_array->len;
291 service->char_handle.handle =
292 __get_string_array_from_gptr_array(gp_array);
294 g_ptr_array_free(gp_array, TRUE);
295 g_variant_iter_free(char_iter);
297 BT_DBG("Characteristics count : %d", service->char_handle.count);
301 service->handle = g_strdup(service_handle);
303 g_variant_iter_free(property_iter);
304 g_variant_unref(result);
305 g_object_unref(properties_proxy);
307 return BLUETOOTH_ERROR_NONE;
310 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
311 const bluetooth_device_address_t *address,
312 bt_gatt_handle_info_t *prim_svc)
314 GVariant *result = NULL;
316 GVariantIter *svc_iter;
317 GVariantIter *interface_iter;
318 char *object_path = NULL;
319 char *interface_str = NULL;
320 const gchar *key = NULL;
321 GVariant *value = NULL;
322 GPtrArray *gp_array = NULL;
323 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
324 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
325 int ret = BLUETOOTH_ERROR_INTERNAL;
329 BT_CHECK_PARAMETER(address, return);
330 BT_CHECK_PARAMETER(prim_svc, return);
331 BT_CHECK_ENABLED(return);
333 result = _bt_get_managed_objects();
337 _bt_convert_addr_type_to_string(device_address,
338 (unsigned char *)address->addr);
340 gp_array = g_ptr_array_new();
341 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
343 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
345 if (object_path == NULL)
348 _bt_convert_device_path_to_address(object_path, temp_address);
350 if (g_strcmp0(temp_address, device_address) != 0)
353 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
354 &interface_str, &svc_iter)) {
355 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
358 BT_DBG("[%d] Object Path : %s", idx++, object_path);
359 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
360 if (g_strcmp0(key, "Primary") == 0) {
361 if (g_variant_get_boolean(value))
362 g_ptr_array_add(gp_array, (gpointer)object_path);
368 if (gp_array->len == 0) {
369 BT_ERR("gp_array is NULL");
370 ret = BLUETOOTH_ERROR_NOT_FOUND;
372 ret = BLUETOOTH_ERROR_NONE;
373 prim_svc->count = gp_array->len;
374 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
377 g_ptr_array_free(gp_array, TRUE);
378 g_variant_iter_free(iter);
379 g_variant_unref(result);
384 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
385 const char *service_uuid,
386 bt_gatt_service_property_t *service)
388 GVariant *result = NULL;
390 GVariantIter *svc_iter;
391 GVariantIter *interface_iter;
392 char *object_path = NULL;
393 char *interface_str = NULL;
394 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
395 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
396 int ret = BLUETOOTH_ERROR_INTERNAL;
398 BT_CHECK_PARAMETER(address, return);
399 BT_CHECK_PARAMETER(service_uuid, return);
400 BT_CHECK_PARAMETER(service, return);
401 BT_CHECK_ENABLED(return);
403 result = _bt_get_managed_objects();
407 _bt_convert_addr_type_to_string(device_address,
408 (unsigned char *)address->addr);
410 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
412 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
414 if (object_path == NULL)
417 _bt_convert_device_path_to_address(object_path,
420 if (g_strcmp0(temp_address, device_address) != 0)
423 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
424 &interface_str, &svc_iter)) {
425 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
428 BT_DBG("Object Path: %s", object_path);
429 ret = bluetooth_gatt_get_service_property(object_path,
432 if (ret != BLUETOOTH_ERROR_NONE) {
433 BT_ERR("Get service property failed(0x%08x)", ret);
435 if (service->primary == TRUE &&
436 g_strstr_len(service->uuid, -1,
438 ret = BLUETOOTH_ERROR_NONE;
442 bluetooth_gatt_free_service_property(service);
447 g_variant_iter_free(iter);
448 g_variant_unref(result);
453 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
454 GAsyncResult *res, gpointer user_data)
457 GVariant *char_value;
458 GVariantIter *char_iter;
459 GPtrArray *gp_array = NULL;
460 bt_gatt_discovered_char_t svc_char = { 0, };
462 GError *error = NULL;
463 bt_user_info_t *user_info;
467 user_info = _bt_get_user_data(BT_COMMON);
468 svc_char.service_handle = user_data;
470 value = g_dbus_proxy_call_finish(proxy, res, &error);
474 BT_ERR("Get service characteristics failed\n errCode[%x],"
475 "message[%s]\n", error->code, error->message);
476 g_clear_error(&error);
478 BT_ERR("Get service characteristics failed\n");
481 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
482 BLUETOOTH_ERROR_INTERNAL, NULL,
483 user_info->cb, user_info->user_data);
485 g_free(svc_char.service_handle);
486 g_object_unref(proxy);
490 g_variant_get(value, "(v)", &char_value);
491 g_variant_get(char_value, "ao", &char_iter);
493 gp_array = g_ptr_array_new();
494 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
495 g_ptr_array_add(gp_array, (gpointer)char_handle);
497 if (gp_array->len != 0) {
498 svc_char.handle_info.count = gp_array->len;
499 svc_char.handle_info.handle =
500 __get_string_array_from_gptr_array(gp_array);
502 g_ptr_array_free(gp_array, TRUE);
505 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
506 BLUETOOTH_ERROR_NONE, &svc_char,
507 user_info->cb, user_info->user_data);
510 g_strfreev(svc_char.handle_info.handle);
511 g_free(svc_char.service_handle);
512 g_variant_iter_free(char_iter);
513 g_variant_unref(value);
514 g_object_unref(proxy);
517 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
518 const char *service_handle)
520 GDBusProxy *properties_proxy = NULL;
521 GDBusConnection *g_conn;
522 GError *error = NULL;
527 BT_CHECK_PARAMETER(service_handle, return);
528 BT_CHECK_ENABLED(return);
530 g_conn = _bt_gdbus_get_system_gconn();
531 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
533 properties_proxy = g_dbus_proxy_new_sync(g_conn,
534 G_DBUS_PROXY_FLAGS_NONE, NULL,
537 BT_PROPERTIES_INTERFACE,
540 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
542 handle = g_strdup(service_handle);
543 g_dbus_proxy_call(properties_proxy,
545 g_variant_new("(ss)",
546 GATT_SERV_INTERFACE, "Characteristics"),
547 G_DBUS_CALL_FLAGS_NONE,
550 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
554 return BLUETOOTH_ERROR_NONE;
558 static int __get_permission_flag(char *permission)
562 retv_if(permission == NULL, ret);
564 BT_INFO("permission = %s", permission);
566 if (!g_strcmp0(permission, "broadcast"))
567 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
568 else if (!g_strcmp0(permission, "read"))
569 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
570 else if (!g_strcmp0(permission, "write-without-response"))
571 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
572 else if (!g_strcmp0(permission, "write"))
573 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
574 else if (!g_strcmp0(permission, "notify"))
575 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
576 else if (!g_strcmp0(permission, "indicate"))
577 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
578 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
579 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
580 else if (!g_strcmp0(permission, "reliable-write"))
581 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
582 else if (!g_strcmp0(permission, "writable-auxiliaries"))
583 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
584 else if (!g_strcmp0(permission, "encrypt-read"))
585 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
586 else if (!g_strcmp0(permission, "encrypt-write"))
587 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
588 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
589 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
590 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
591 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
596 static void __convert_permission_flag_to_str(unsigned int permission)
598 char perm[200] = { 0, };
600 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
601 g_strlcat(perm, "broadcast ", sizeof(perm));
602 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
603 g_strlcat(perm, "read ", sizeof(perm));
604 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
605 g_strlcat(perm, "write-without-response ", sizeof(perm));
606 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
607 g_strlcat(perm, "write ", sizeof(perm));
608 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
609 g_strlcat(perm, "notify ", sizeof(perm));
610 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
611 g_strlcat(perm, "indicate ", sizeof(perm));
612 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
613 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
614 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
615 g_strlcat(perm, "reliable-write ", sizeof(perm));
616 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
617 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
618 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
619 g_strlcat(perm, "encrypt-read ", sizeof(perm));
620 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
621 g_strlcat(perm, "encrypt-write ", sizeof(perm));
622 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
623 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
624 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
625 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
627 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
631 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
632 const char *char_handle, bt_gatt_char_property_t *characteristic)
634 GDBusProxy *properties_proxy = NULL;
635 GError *error = NULL;
636 GVariant *value = NULL;
637 GVariant *result = NULL;
638 GByteArray *gb_array = NULL;
639 GPtrArray *gp_array = NULL ;
640 GDBusConnection *g_conn;
644 char *char_desc_handle = NULL;
646 GVariantIter *property_iter;
647 GVariantIter *char_value_iter;
648 GVariantIter *char_perm_iter;
649 GVariantIter *char_desc_iter;
652 BT_CHECK_PARAMETER(char_handle, return);
653 BT_CHECK_PARAMETER(characteristic, return);
655 BT_CHECK_ENABLED(return);
657 g_conn = _bt_gdbus_get_system_gconn();
658 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
660 properties_proxy = g_dbus_proxy_new_sync(g_conn,
661 G_DBUS_PROXY_FLAGS_NONE, NULL,
664 BT_PROPERTIES_INTERFACE,
667 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
669 result = g_dbus_proxy_call_sync(properties_proxy,
671 g_variant_new("(s)", GATT_CHAR_INTERFACE),
672 G_DBUS_CALL_FLAGS_NONE,
679 BT_ERR("Fail to get properties (Error: %s)", error->message);
680 g_clear_error(&error);
682 BT_ERR("Fail to get properties");
683 g_object_unref(properties_proxy);
684 return BLUETOOTH_ERROR_INTERNAL;
687 g_variant_get(result, "(a{sv})", &property_iter);
689 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
690 characteristic->handle = g_strdup(char_handle);
692 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
693 if (!g_strcmp0(key, "UUID")) {
695 characteristic->uuid = g_variant_dup_string(value, &len);
696 bluetooth_get_uuid_name(characteristic->uuid, &name);
697 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
699 } else if (!g_strcmp0(key, "Value")) {
700 gb_array = g_byte_array_new();
701 g_variant_get(value, "ay", &char_value_iter);
702 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
703 // BT_DBG("value of char = %d",char_value);
704 g_byte_array_append(gb_array, &char_value, 1);
706 g_variant_iter_free(char_value_iter);
708 if (gb_array->len != 0) {
709 characteristic->val = g_malloc0(gb_array->len *
710 sizeof(unsigned char));
711 memcpy(characteristic->val, gb_array->data, gb_array->len);
713 characteristic->val_len = gb_array->len;
714 g_byte_array_free(gb_array, TRUE);
715 } else if (!g_strcmp0(key, "Flags")) {
716 g_variant_get(value, "as", &char_perm_iter);
717 characteristic->permission = 0x00;
719 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
720 characteristic->permission |= __get_permission_flag(permission);
721 __convert_permission_flag_to_str(characteristic->permission);
723 g_variant_iter_free(char_perm_iter);
724 } else if (!g_strcmp0(key, "Descriptors")) {
725 g_variant_get(value, "ao", &char_desc_iter);
726 gp_array = g_ptr_array_new();
727 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
728 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
730 g_variant_iter_free(char_desc_iter);
731 if (gp_array->len != 0) {
732 characteristic->char_desc_handle.count = gp_array->len;
733 characteristic->char_desc_handle.handle =
734 __get_string_array_from_gptr_array(gp_array);
736 g_ptr_array_free(gp_array, TRUE);
740 g_variant_iter_free(property_iter);
741 g_variant_unref(result);
742 g_object_unref(properties_proxy);
745 return BLUETOOTH_ERROR_NONE;
748 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
749 GAsyncResult *res, gpointer user_data)
752 GVariantIter *char_iter;
754 GError *error = NULL;
755 bt_user_info_t *user_info;
756 int ret = BLUETOOTH_ERROR_INTERNAL;
757 bt_gatt_char_property_t characteristic;
759 user_info = _bt_get_user_data(BT_COMMON);
761 value = g_dbus_proxy_call_finish(proxy, res, &error);
765 BT_ERR("Get service characteristics failed\n errCode[%x],"
766 "message[%s]\n", error->code, error->message);
767 g_clear_error(&error);
769 BT_ERR("Get service characteristics failed\n");
772 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
773 BLUETOOTH_ERROR_INTERNAL, NULL,
774 user_info->cb, user_info->user_data);
776 g_object_unref(proxy);
781 g_variant_get(value, "(ao)", &char_iter);
783 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
786 ret = bluetooth_gatt_get_characteristics_property(char_handle,
789 if (ret != BLUETOOTH_ERROR_NONE) {
790 BT_ERR("Get characteristic property failed(0x%08x)", ret);
792 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
793 ret = BLUETOOTH_ERROR_NONE;
797 bluetooth_gatt_free_char_property(&characteristic);
801 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
802 &characteristic, user_info->cb, user_info->user_data);
805 bluetooth_gatt_free_char_property(&characteristic);
806 g_variant_iter_free(char_iter);
807 g_variant_unref(value);
811 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
812 const char *char_uuid)
814 GDBusProxy *properties_proxy = NULL;
815 GDBusConnection *g_conn;
816 GError *error = NULL;
819 BT_CHECK_PARAMETER(service_handle, return);
820 BT_CHECK_PARAMETER(char_uuid, return);
821 BT_CHECK_ENABLED(return);
823 g_conn = _bt_gdbus_get_system_gconn();
824 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
826 properties_proxy = g_dbus_proxy_new_sync(g_conn,
827 G_DBUS_PROXY_FLAGS_NONE, NULL,
830 BT_PROPERTIES_INTERFACE,
833 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
835 uuid = g_strdup(char_uuid);
836 g_dbus_proxy_call(properties_proxy,
838 g_variant_new("(ss)",
839 GATT_SERV_INTERFACE, "Characteristics"),
840 G_DBUS_CALL_FLAGS_NONE,
843 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
846 return BLUETOOTH_ERROR_NONE;
849 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
850 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
852 GDBusProxy *properties_proxy = NULL;
853 GError *error = NULL;
854 GDBusConnection *g_conn;
855 GVariant *result = NULL;
856 GVariantIter *property_iter;
860 GVariant *value = NULL;
861 GByteArray *gb_array = NULL;
862 GVariantIter *desc_value_iter;
865 BT_CHECK_PARAMETER(descriptor_handle, return);
866 BT_CHECK_PARAMETER(descriptor, return);
868 BT_CHECK_ENABLED(return);
870 g_conn = _bt_gdbus_get_system_gconn();
871 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
873 properties_proxy = g_dbus_proxy_new_sync(g_conn,
874 G_DBUS_PROXY_FLAGS_NONE, NULL,
877 BT_PROPERTIES_INTERFACE,
880 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
882 result = g_dbus_proxy_call_sync(properties_proxy,
884 g_variant_new("(s)", GATT_DESC_INTERFACE),
885 G_DBUS_CALL_FLAGS_NONE,
892 BT_ERR("Fail to get properties (Error: %s)", error->message);
893 g_clear_error(&error);
895 BT_ERR("Fail to get properties");
896 g_object_unref(properties_proxy);
897 return BLUETOOTH_ERROR_INTERNAL;
900 g_variant_get(result, "(a{sv})", &property_iter);
902 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
903 descriptor->handle = g_strdup(descriptor_handle);
905 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
906 if (!g_strcmp0(key, "UUID")) {
908 descriptor->uuid = g_variant_dup_string(value, &len);
909 bluetooth_get_uuid_name(descriptor->uuid, &name);
910 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
912 } else if (!g_strcmp0(key, "Value")) {
913 gb_array = g_byte_array_new();
914 g_variant_get(value, "ay", &desc_value_iter);
915 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
916 BT_DBG("value of descriptor = %d", char_value);
917 g_byte_array_append(gb_array, &char_value, 1);
919 g_variant_iter_free(desc_value_iter);
921 if (gb_array->len != 0) {
922 descriptor->val = g_malloc0(gb_array->len *
923 sizeof(unsigned char));
924 memcpy(descriptor->val, gb_array->data, gb_array->len);
926 descriptor->val_len = gb_array->len;
927 g_byte_array_free(gb_array, TRUE);
931 g_variant_iter_free(property_iter);
932 g_variant_unref(result);
933 g_object_unref(properties_proxy);
936 return BLUETOOTH_ERROR_NONE;
939 static int __bluetooth_get_att_error_code(GError *error)
945 BT_ERR("Error : %s", error->message);
946 str = g_strrstr(error->message, "ATT error: 0x");
949 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
950 att_ecode += g_ascii_xdigit_value(str[len - 1]);
952 return BLUETOOTH_ATT_ERROR_INTERNAL;
955 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
956 BT_ERR("Read not permitted");
958 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
959 BT_ERR("Write not permitted");
961 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
962 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
963 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
964 BT_ERR("Not paired");
966 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
967 BT_ERR("Invalid offset");
969 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
970 BT_ERR("Invalid Length");
972 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
973 BT_ERR("Operation not Authorized");
976 BT_ERR("default ecode");
980 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
981 BT_ERR("Application error");
986 static void __bluetooth_internal_read_cb(GObject *source_object,
987 GAsyncResult *res, gpointer user_data)
989 GError *error = NULL;
990 GDBusConnection *system_gconn = NULL;
992 bt_user_info_t *user_info;
994 GByteArray *gp_byte_array = NULL;
997 bt_gatt_resp_data_t *resp_data = user_data;
1001 system_gconn = _bt_gdbus_get_system_gconn();
1002 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1004 user_info = _bt_get_user_data(BT_COMMON);
1008 BT_ERR("Error : %s", error->message);
1009 g_clear_error(&error);
1012 g_variant_unref(value);
1017 att_ecode = __bluetooth_get_att_error_code(error);
1018 g_clear_error(&error);
1020 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1021 att_ecode, resp_data,
1022 user_info->cb, user_info->user_data);
1027 gp_byte_array = g_byte_array_new();
1028 g_variant_get(value, "(ay)", &iter);
1030 while (g_variant_iter_loop(iter, "y", &g_byte))
1031 g_byte_array_append(gp_byte_array, &g_byte, 1);
1033 if (gp_byte_array->len != 0) {
1034 resp_data->len = gp_byte_array->len;
1035 resp_data->value = gp_byte_array->data;
1038 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1039 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1040 user_info->cb, user_info->user_data);
1043 g_byte_array_free(gp_byte_array, TRUE);
1044 g_variant_iter_free(iter);
1045 g_variant_unref(value);
1050 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1053 GDBusConnection *conn;
1054 bt_gatt_resp_data_t *resp_data;
1055 GVariantBuilder *builder = NULL;
1058 BT_CHECK_PARAMETER(chr, return);
1059 BT_CHECK_ENABLED(return);
1061 conn = _bt_gdbus_get_system_gconn();
1062 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1064 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1065 resp_data->user_data = user_data;
1067 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1070 g_variant_builder_add(builder, "{sv}", "offset",
1071 g_variant_new("q", offset));
1073 /* Device Object path*/
1074 // g_variant_builder_add(builder, "{sv}", "device",
1075 // g_variant_new_object("o", NULL));
1077 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1078 "ReadValue", g_variant_new("(a{sv})", builder),
1079 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1080 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1081 (gpointer)resp_data);
1082 g_variant_builder_unref(builder);
1084 return BLUETOOTH_ERROR_NONE;
1087 static void __bluetooth_internal_write_cb(GObject *source_object,
1088 GAsyncResult *res, gpointer user_data)
1090 GError *error = NULL;
1091 GDBusConnection *system_gconn = NULL;
1092 bt_user_info_t *user_info;
1095 bt_gatt_resp_data_t *resp_data = user_data;
1097 system_gconn = _bt_gdbus_get_system_gconn();
1098 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1100 user_info = _bt_get_user_data(BT_COMMON);
1104 BT_ERR("Error : %s", error->message);
1105 g_clear_error(&error);
1108 g_variant_unref(value);
1113 att_ecode = __bluetooth_get_att_error_code(error);
1114 g_clear_error(&error);
1116 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1117 att_ecode, resp_data,
1118 user_info->cb, user_info->user_data);
1123 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1124 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1125 user_info->cb, user_info->user_data);
1128 g_variant_unref(value);
1132 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1133 const char *char_handle, const guint8 *value, int length)
1135 GVariant *val, *options;
1136 GVariantBuilder *builder1;
1137 GVariantBuilder *builder2;
1138 GError *error = NULL;
1139 GDBusConnection *conn;
1144 BT_CHECK_PARAMETER(char_handle, return);
1145 BT_CHECK_PARAMETER(value, return);
1146 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1147 BT_CHECK_ENABLED(return);
1149 conn = _bt_gdbus_get_system_gconn();
1150 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1152 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1153 for (i = 0; i < length; i++)
1154 g_variant_builder_add(builder1, "y", value[i]);
1156 val = g_variant_new("ay", builder1);
1158 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1160 g_variant_builder_add(builder2, "{sv}", "offset",
1161 g_variant_new_uint16(offset));
1163 /* Device Object path*/
1164 // g_variant_builder_add(builder2, "{sv}", "device",
1165 // g_variant_new_object("o", NULL));
1167 options = g_variant_new("a{sv}", builder2);
1169 g_dbus_connection_call(conn,
1172 GATT_CHAR_INTERFACE,
1174 g_variant_new("(@ay@a{sv})",
1177 G_DBUS_CALL_FLAGS_NONE,
1179 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1184 BT_ERR("Set value Failed: %s", error->message);
1185 g_clear_error(&error);
1186 g_variant_builder_unref(builder1);
1187 return BLUETOOTH_ERROR_INTERNAL;
1189 g_variant_builder_unref(builder1);
1190 g_variant_builder_unref(builder2);
1193 return BLUETOOTH_ERROR_NONE;
1196 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1197 const char *chr, const guint8 *value, int length,
1198 guint8 write_type, gpointer user_data)
1200 GVariant *val, *options;
1201 GVariantBuilder *builder1;
1202 GVariantBuilder *builder2;
1203 GDBusConnection *conn;
1206 int ret = BLUETOOTH_ERROR_NONE;
1207 bt_gatt_resp_data_t *resp_data;
1209 BT_CHECK_PARAMETER(chr, return);
1210 BT_CHECK_PARAMETER(value, return);
1211 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1212 BT_CHECK_ENABLED_INTERNAL(return);
1214 conn = _bt_gdbus_get_system_gconn();
1215 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1217 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1219 for (i = 0; i < length; i++)
1220 g_variant_builder_add(builder1, "y", value[i]);
1222 val = g_variant_new("ay", builder1);
1224 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1226 g_variant_builder_add(builder2, "{sv}", "offset",
1227 g_variant_new_uint16(offset));
1229 /* Device Object path*/
1230 // g_variant_builder_add(builder2, "{sv}", "device",
1231 // g_variant_new_object("o", NULL));
1233 options = g_variant_new("a{sv}", builder2);
1235 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1236 resp_data->user_data = user_data;
1238 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1240 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1242 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1243 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1244 (gpointer)resp_data);
1246 g_variant_builder_unref(builder1);
1247 g_variant_builder_unref(builder2);
1252 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1253 const char *char_handle, const guint8 *value, int length)
1255 GVariant *val, *options;
1256 GDBusConnection *conn;
1257 GVariantBuilder *builder1;
1258 GVariantBuilder *builder2;
1263 BT_CHECK_PARAMETER(char_handle, return);
1264 BT_CHECK_PARAMETER(value, return);
1265 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1266 BT_CHECK_ENABLED(return);
1268 conn = _bt_gdbus_get_system_gconn();
1269 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1271 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1273 for (i = 0; i < length; i++) {
1274 g_variant_builder_add(builder1, "y", value[i]);
1275 BT_DBG("value [] = %d", value[i]);
1278 val = g_variant_new("ay", builder1);
1280 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1282 g_variant_builder_add(builder2, "{sv}", "offset",
1283 g_variant_new_uint16(offset));
1285 /* Device Object path*/
1286 // g_variant_builder_add(builder2, "{sv}", "device",
1287 // g_variant_new_object("o", NULL));
1289 options = g_variant_new("a{sv}", builder2);
1291 g_dbus_connection_call(conn,
1294 GATT_CHAR_INTERFACE,
1296 g_variant_new("(@ay@a{sv})",
1299 G_DBUS_CALL_FLAGS_NONE,
1301 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1304 g_variant_builder_unref(builder1);
1305 g_variant_builder_unref(builder2);
1308 return BLUETOOTH_ERROR_NONE;
1311 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1312 bt_gatt_char_property_t *characteristic)
1315 GDBusProxy *properties_proxy = NULL;
1316 GError *error = NULL;
1317 GVariant *value = NULL;
1318 GVariant *result = NULL;
1319 GDBusConnection *g_conn;
1320 int i, ret = BLUETOOTH_ERROR_NONE;
1321 const char *uuid = NULL;
1323 GVariantIter *desc_value_iter, *property_iter;
1325 char_descriptor_type_t desc_type = TYPE_NONE;
1327 g_conn = _bt_gdbus_get_system_gconn();
1328 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1330 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1331 G_DBUS_PROXY_FLAGS_NONE, NULL,
1334 BT_PROPERTIES_INTERFACE,
1337 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1339 result = g_dbus_proxy_call_sync(properties_proxy,
1341 g_variant_new("(s)", GATT_DESC_INTERFACE),
1342 G_DBUS_CALL_FLAGS_NONE,
1348 if (error != NULL) {
1349 BT_ERR("Fail to get properties (Error: %s)", error->message);
1350 g_clear_error(&error);
1352 BT_ERR("Fail to get properties");
1353 g_object_unref(properties_proxy);
1354 return BLUETOOTH_ERROR_INTERNAL;
1356 g_variant_get(result, "(a{sv})", &property_iter);
1357 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1358 if (!g_strcmp0(key, "UUID")) {
1359 uuid = g_variant_get_string(value, &len);
1360 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1361 BT_DBG("GATT_USER_DESC_UUID");
1362 desc_type = USER_DESC;
1363 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1364 BT_DBG("GATT_CHAR_FORMAT");
1365 desc_type = CHAR_FORMAT;
1366 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1367 BT_DBG("GATT_CHAR_CLIENT_CONF");
1368 desc_type = CLIENT_CONF;
1369 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1370 BT_DBG("GATT_CHAR_SERVER_CONF");
1371 desc_type = SERVER_CONF;
1373 BT_DBG("descriptor uuid = %s", uuid);
1375 } else if (!g_strcmp0(key, "Value")) {
1376 switch (desc_type) {
1378 BT_DBG("Format descriptor");
1379 g_variant_get(value, "(yyqyq)",
1380 &(characteristic->format.format),
1381 &(characteristic->format.exponent),
1382 &(characteristic->format.unit),
1383 &(characteristic->format.name_space),
1384 &(characteristic->format.description));
1387 BT_DBG("User descriptor");
1388 g_variant_get(value, "ay", &desc_value_iter);
1389 len = g_variant_get_size((GVariant *)desc_value_iter);
1392 characteristic->description = (char *)g_malloc0(len + 1);
1394 for (i = 0; i < len; i++) {
1395 g_variant_iter_loop(desc_value_iter, "y",
1396 &characteristic->description[i]);
1397 BT_DBG("description = %s", characteristic->description);
1399 g_variant_iter_free(desc_value_iter);
1402 BT_DBG(" CLIENT_CONF");
1405 BT_DBG(" SERVER_CONF");
1413 g_variant_iter_free(property_iter);
1414 g_variant_unref(result);
1415 g_object_unref(properties_proxy);
1422 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1423 GAsyncResult *res, gpointer user_data)
1427 GVariant *char_value;
1428 GVariantIter *char_iter;
1430 GError *error = NULL;
1431 bt_user_info_t *user_info;
1432 bt_gatt_char_property_t characteristic = {0, };
1433 int ret = BLUETOOTH_ERROR_INTERNAL;
1435 user_info = _bt_get_user_data(BT_COMMON);
1437 value = g_dbus_proxy_call_finish(proxy, res, &error);
1438 characteristic.handle = user_data;
1440 if (value == NULL) {
1441 if (error != NULL) {
1442 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1443 "message[%s]\n", error->code, error->message);
1444 g_clear_error(&error);
1446 BT_ERR("Get characteristic descriptor failed\n");
1449 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1450 BLUETOOTH_ERROR_INTERNAL, NULL,
1451 user_info->cb, user_info->user_data);
1453 g_free(characteristic.handle);
1454 g_object_unref(proxy);
1458 g_variant_get(value, "(v)", &char_value);
1459 g_variant_get(char_value, "ao", &char_iter);
1461 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1462 BT_DBG("object path of descriptor = %s", char_handle);
1464 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1466 BT_DBG("Descriptor read status [%d]", ret);
1471 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1472 ret, &characteristic, user_info->cb, user_info->user_data);
1474 bluetooth_gatt_free_char_property(&characteristic);
1476 g_variant_iter_free(char_iter);
1477 g_variant_unref(value);
1481 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1482 const char *characteristic_handle)
1484 GDBusProxy *properties_proxy = NULL;
1485 GDBusConnection *g_conn;
1487 GError *error = NULL;
1489 BT_CHECK_PARAMETER(characteristic_handle, return);
1490 BT_CHECK_ENABLED(return);
1492 g_conn = _bt_gdbus_get_system_gconn();
1493 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1495 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1496 G_DBUS_PROXY_FLAGS_NONE, NULL,
1498 characteristic_handle,
1499 BT_PROPERTIES_INTERFACE,
1502 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1504 handle = g_strdup(characteristic_handle);
1505 g_dbus_proxy_call(properties_proxy,
1507 g_variant_new("(ss)",
1508 GATT_CHAR_INTERFACE, "Descriptors"),
1509 G_DBUS_CALL_FLAGS_NONE,
1511 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1514 return BLUETOOTH_ERROR_NONE;
1517 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1521 GError *error = NULL;
1522 GDBusConnection *system_gconn = NULL;
1524 bt_user_info_t *user_info;
1525 GByteArray *gp_byte_array = NULL;
1529 bt_gatt_resp_data_t *resp_data = user_data;
1533 system_gconn = _bt_gdbus_get_system_gconn();
1534 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1536 user_info = _bt_get_user_data(BT_COMMON);
1540 BT_ERR("Error : %s", error->message);
1541 g_clear_error(&error);
1544 g_variant_unref(value);
1549 att_ecode = __bluetooth_get_att_error_code(error);
1550 g_clear_error(&error);
1552 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1553 att_ecode, resp_data,
1554 user_info->cb, user_info->user_data);
1559 gp_byte_array = g_byte_array_new();
1560 g_variant_get(value, "(ay)", &iter);
1562 while (g_variant_iter_loop(iter, "y", &g_byte))
1563 g_byte_array_append(gp_byte_array, &g_byte, 1);
1565 if (gp_byte_array->len != 0) {
1566 resp_data->len = gp_byte_array->len;
1567 resp_data->value = gp_byte_array->data;
1570 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1571 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1572 user_info->cb, user_info->user_data);
1576 g_byte_array_free(gp_byte_array, TRUE);
1577 g_variant_iter_free(iter);
1578 g_variant_unref(value);
1583 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1586 GDBusConnection *conn;
1587 GVariantBuilder *builder;
1589 bt_gatt_resp_data_t *resp_data;
1593 BT_CHECK_PARAMETER(desc, return);
1594 BT_CHECK_ENABLED(return);
1596 conn = _bt_gdbus_get_system_gconn();
1597 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1599 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1600 resp_data->user_data = user_data;
1602 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1605 g_variant_builder_add(builder, "{sv}", "offset",
1606 g_variant_new("q", offset));
1607 /* Device Object path*/
1608 // g_variant_builder_add(builder, "{sv}", "device",
1609 // g_variant_new("o", serv_info->serv_path));
1611 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1612 "ReadValue", g_variant_new("(a{sv})", builder),
1613 G_VARIANT_TYPE("(ay)"),
1614 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1615 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1616 (gpointer)resp_data);
1617 g_variant_builder_unref(builder);
1620 return BLUETOOTH_ERROR_NONE;
1623 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1624 GAsyncResult *res, gpointer user_data)
1626 GError *error = NULL;
1627 bt_user_info_t *user_info;
1628 GDBusConnection *system_gconn = NULL;
1630 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1631 bt_gatt_resp_data_t *resp_data = user_data;
1635 system_gconn = _bt_gdbus_get_system_gconn();
1636 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1638 user_info = _bt_get_user_data(BT_COMMON);
1642 BT_ERR("Error : %s", error->message);
1643 g_clear_error(&error);
1646 g_variant_unref(value);
1651 att_ecode = __bluetooth_get_att_error_code(error);
1652 g_clear_error(&error);
1654 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1655 att_ecode, resp_data,
1656 user_info->cb, user_info->user_data);
1661 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1662 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1663 user_info->cb, user_info->user_data);
1666 g_variant_unref(value);
1670 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1671 const guint8 *value, int length, gpointer user_data)
1673 GVariant *val, *options;
1674 GDBusConnection *conn;
1675 GVariantBuilder *builder1;
1676 GVariantBuilder *builder2;
1679 bt_gatt_resp_data_t *resp_data;
1683 BT_CHECK_PARAMETER(desc, return);
1684 BT_CHECK_PARAMETER(value, return);
1685 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1686 BT_CHECK_ENABLED(return);
1688 conn = _bt_gdbus_get_system_gconn();
1689 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1691 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1693 for (i = 0; i < length; i++)
1694 g_variant_builder_add(builder1, "y", value[i]);
1696 val = g_variant_new("ay", builder1);
1698 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1700 g_variant_builder_add(builder2, "{sv}", "offset",
1701 g_variant_new_uint16(offset));
1703 /* Device Object path*/
1704 // g_variant_builder_add(builder2, "{sv}", "device",
1705 // g_variant_new_object("o", NULL));
1707 options = g_variant_new("a{sv}", builder2);
1709 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1710 resp_data->user_data = user_data;
1712 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1713 "WriteValue", g_variant_new("(@ay@a{sv})",
1714 val, options), NULL,
1715 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1716 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1717 (gpointer)resp_data);
1719 g_variant_builder_unref(builder1);
1720 g_variant_builder_unref(builder2);
1723 return BLUETOOTH_ERROR_NONE;
1726 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1728 GDBusConnection *conn;
1729 GError *error = NULL;
1730 int ret = BLUETOOTH_ERROR_NONE;
1732 BT_CHECK_PARAMETER(char_handle, return);
1733 BT_CHECK_ENABLED(return);
1735 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
1737 conn = _bt_gdbus_get_system_gconn();
1738 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1740 g_dbus_connection_call_sync(conn,
1743 GATT_CHAR_INTERFACE,
1747 G_DBUS_CALL_FLAGS_NONE,
1748 GATT_DEFAULT_TIMEOUT, NULL, &error);
1751 g_dbus_error_strip_remote_error(error);
1752 BT_ERR_C("### Watch Failed: %s", error->message);
1753 if (g_strrstr(error->message, "Already notifying"))
1754 ret = BLUETOOTH_ERROR_NONE;
1755 else if (g_strrstr(error->message, "In Progress"))
1756 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1757 else if (g_strrstr(error->message, "Operation is not supported"))
1758 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1759 /*failed because of either Insufficient Authorization or Write Not Permitted */
1760 else if (g_strrstr(error->message, "Write not permitted") ||
1761 g_strrstr(error->message, "Operation Not Authorized"))
1762 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1763 /* failed because of either Insufficient Authentication,
1764 Insufficient Encryption Key Size, or Insufficient Encryption. */
1765 else if (g_strrstr(error->message, "Not paired"))
1766 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1768 ret = BLUETOOTH_ERROR_INTERNAL;
1770 g_clear_error(&error);
1776 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1779 GDBusConnection *conn;
1780 GError *error = NULL;
1781 int ret = BLUETOOTH_ERROR_NONE;
1782 BT_CHECK_PARAMETER(char_handle, return);
1784 BT_CHECK_ENABLED(return);
1786 BT_INFO("Disable CCCD : %s", char_handle);
1788 conn = _bt_gdbus_get_system_gconn();
1789 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1791 g_dbus_connection_call_sync(conn,
1794 GATT_CHAR_INTERFACE,
1798 G_DBUS_CALL_FLAGS_NONE,
1799 GATT_DEFAULT_TIMEOUT, NULL, &error);
1802 BT_ERR("Watch Failed: %s", error->message);
1803 g_clear_error(&error);
1804 ret = BLUETOOTH_ERROR_INTERNAL;
1810 #ifdef TIZEN_GATT_CLIENT
1811 void __bt_uuid_hex_to_string(unsigned char *uuid, char *str)
1813 uint32_t uuid0, uuid4;
1814 uint16_t uuid1, uuid2, uuid3, uuid5;
1816 memcpy(&uuid0, &(uuid[0]), 4);
1817 memcpy(&uuid1, &(uuid[4]), 2);
1818 memcpy(&uuid2, &(uuid[6]), 2);
1819 memcpy(&uuid3, &(uuid[8]), 2);
1820 memcpy(&uuid4, &(uuid[10]), 4);
1821 memcpy(&uuid5, &(uuid[14]), 2);
1823 snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1824 ntohl(uuid0), ntohs(uuid1),
1825 ntohs(uuid2), ntohs(uuid3),
1826 ntohl(uuid4), ntohs(uuid5));
1831 static void __bt_fill_service_handle_informations(bt_services_browse_info_t *props,
1832 bt_gatt_handle_info_t *svcs)
1835 BT_INFO("Total services found [%d]", props->count);
1837 if (props->count == 0)
1840 svcs->count = props->count;
1842 for (count = 0; count < props->count; count++) {
1843 BT_INFO("UUID[%d] = [%s] instance_id [%d] Is Primary [%d]",
1844 count, props->uuids[count], props->inst_id[count], props->primary[count]);
1845 g_strlcpy(svcs->uuids[count], props->uuids[count],
1846 BLUETOOTH_UUID_STRING_MAX);
1847 svcs->inst_id[count] = props->inst_id[count];
1851 static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props,
1852 bt_gatt_service_property_t *service)
1855 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1856 BT_INFO("Total number of characteristics found [%d]",
1859 service->char_handle.count = props->count;
1861 /* Before filling all char handles, fill the service's UUID and instance ID */
1862 __bt_uuid_hex_to_string(props->svc_uuid, uuid_string);
1863 service->uuid = g_strdup(uuid_string);
1864 service->primary = TRUE;
1866 /* Now fill all the char handles [UUID and Instance ID's]*/
1867 for (count = 0; count < props->count; count++) {
1868 BT_INFO("UUID[%d] = [%s] instance_id [%d] properties [%d]",
1869 count, props->uuids[count], props->inst_id[count], props->props[count]);
1871 g_strlcpy(service->char_handle.uuids[count],
1872 props->uuids[count],
1873 BLUETOOTH_UUID_STRING_MAX);
1875 service->char_handle.inst_id[count] = props->inst_id[count];
1879 static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *props,
1880 bt_gatt_char_property_t *charc)
1883 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1884 BT_INFO("Total descriptor count found [%d]", props->count);
1886 charc->char_desc_handle.count = props->count;
1888 /* Before filling all desc handles, fill the charac's UUID and instance ID */
1889 __bt_uuid_hex_to_string(props->char_uuid, uuid_string);
1890 charc->uuid = g_strdup(uuid_string);
1892 /* Now fill all the descriptor handles [UUID and Instance ID's]*/
1893 for (count = 0; count < props->count; count++) {
1894 BT_INFO("UUID[%d] = [%s] instance_id [%d]",
1895 count, props->uuids[count], props->inst_id[count]);
1897 g_strlcpy(charc->char_desc_handle.uuids[count],
1898 props->uuids[count],
1899 BLUETOOTH_UUID_STRING_MAX);
1901 charc->char_desc_handle.inst_id[count] = props->inst_id[count];
1903 charc->permission = props->char_props_map;
1904 BT_INFO("Characteritic property map val [%d]", charc->permission);
1908 BT_EXPORT_API int bluetooth_gatt_client_init(
1910 const bluetooth_device_address_t *address,
1911 gatt_client_cb_func_ptr callback_ptr)
1913 int ret = BLUETOOTH_ERROR_NONE;
1914 bt_event_info_t *event_info;
1917 BT_CHECK_PARAMETER(client_id, return);
1918 BT_CHECK_PARAMETER(callback_ptr, return);
1919 BT_CHECK_ENABLED(return);
1924 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1926 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1928 ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_REGISTER,
1929 in_param1, in_param2, in_param3, in_param4, &out_param);
1931 /* App ID -1 is invalid */
1932 if (ret == BLUETOOTH_ERROR_NONE) {
1934 *client_id = g_array_index(out_param, int, 0);
1936 BT_INFO("GATT Client Registered successfully: Client instance ID [%d]", *client_id);
1938 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
1941 count = (int*)event_info->user_data;
1943 BT_INFO("Total num of GATT client instances [%d]", *count);
1945 /* Increement the count */
1948 BT_INFO("No GATT Client instances found in this application: Set User data");
1949 count = g_malloc0(sizeof(int));
1952 /* Register event handler for GATT */
1953 _bt_register_event(BT_GATT_CLIENT_EVENT,
1954 (void *)callback_ptr,
1956 _bt_set_user_data(BT_GATT_CLIENT, (void *)callback_ptr, NULL);
1959 BT_ERR("GATT Client Registration failed!! ret [%d]", ret);
1961 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1968 BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
1969 const bluetooth_device_address_t *address, /* Remote GATT Server */
1970 bt_gatt_handle_info_t *prim_svc) /* UUID & instance_id */
1973 int result = BLUETOOTH_ERROR_NONE;
1974 bt_services_browse_info_t service_props;
1978 BT_CHECK_PARAMETER(address, return);
1979 BT_CHECK_PARAMETER(prim_svc, return);
1980 BT_CHECK_ENABLED(return);
1983 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1984 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1986 result = _bt_send_request(BT_BLUEZ_SERVICE,
1987 BT_GATT_GET_PRIMARY_SERVICES,
1988 in_param1, in_param2, in_param3, in_param4, &out_param);
1990 if (BLUETOOTH_ERROR_NONE != result)
1993 memset(&service_props, 0x00, sizeof(bt_services_browse_info_t));
1995 service_props = g_array_index(
1996 out_param, bt_services_browse_info_t, 0);
1998 __bt_fill_service_handle_informations(
1999 &service_props, prim_svc);
2002 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2003 BT_DBG("result = %d", result);
2007 BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
2008 const char *address,
2009 bt_gatt_handle_property_t *service_handle,
2010 bt_gatt_service_property_t *service)
2012 int result = BLUETOOTH_ERROR_NONE;
2013 bluetooth_gatt_client_svc_prop_info_t svc_prop;
2014 bt_char_browse_info_t char_handles_info;
2015 BT_INFO("Remote Address [%s]", address);
2017 BT_CHECK_PARAMETER(address, return);
2018 BT_CHECK_PARAMETER(service_handle, return);
2019 BT_CHECK_PARAMETER(service, return);
2020 BT_CHECK_ENABLED(return);
2022 /* Call to bt-service (sync) and send address and service_handle info */
2024 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2026 memset(&svc_prop, 0x00, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2027 /* All characteristics handles are discovered */
2028 memset(&char_handles_info, 0x00, sizeof(bt_char_browse_info_t));
2030 svc_prop.svc.instance_id = service_handle->instance_id;
2031 memcpy(&svc_prop.svc.uuid, &service_handle->uuid, 16);
2033 _bt_convert_addr_string_to_type(svc_prop.device_address.addr, address);
2035 g_array_append_vals(in_param1, &svc_prop, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2037 result = _bt_send_request(BT_BLUEZ_SERVICE,
2038 BT_GATT_GET_SERVICE_PROPERTIES,
2039 in_param1, in_param2, in_param3, in_param4, &out_param);
2041 if (BLUETOOTH_ERROR_NONE != result)
2044 char_handles_info = g_array_index(
2045 out_param, bt_char_browse_info_t, 0);
2046 __bt_fill_char_handle_informations(&char_handles_info,
2048 /* TODO Get all Included Services */
2051 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2052 BT_INFO("result = %d", result);
2056 BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
2057 const char *address,
2058 bt_gatt_handle_property_t *service_handle,
2059 bt_gatt_handle_property_t *char_handle,
2060 bt_gatt_char_property_t *char_property)
2062 int result = BLUETOOTH_ERROR_NONE;
2063 bt_descriptor_browse_info_t desc_handles_info;
2064 bluetooth_gatt_client_char_prop_info_t char_prop;
2065 BT_INFO("Get Properties of characteristics from remote device [%s]", address);
2067 BT_CHECK_PARAMETER(address, return);
2068 BT_CHECK_PARAMETER(service_handle, return);
2069 BT_CHECK_PARAMETER(char_handle, return);
2070 BT_CHECK_PARAMETER(char_property, return);
2071 BT_CHECK_ENABLED(return);
2074 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2076 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2078 memset(&char_prop, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2079 char_prop.svc.instance_id = service_handle->instance_id;
2080 memcpy(&char_prop.svc.uuid, &service_handle->uuid, 16);
2082 char_prop.characteristic.instance_id = char_handle->instance_id;
2083 memcpy(&char_prop.characteristic.uuid, &char_handle->uuid, 16);
2085 _bt_convert_addr_string_to_type(char_prop.device_address.addr, address);
2087 g_array_append_vals(in_param1, &char_prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
2089 result = _bt_send_request(BT_BLUEZ_SERVICE,
2090 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
2091 in_param1, in_param2, in_param3, in_param4, &out_param);
2093 BT_INFO("result = [%d]", result);
2094 if (BLUETOOTH_ERROR_NONE != result)
2097 /* All descriptors handles are discovered */
2098 memset(&desc_handles_info, 0x00, sizeof(bt_descriptor_browse_info_t));
2100 desc_handles_info = g_array_index(
2101 out_param, bt_descriptor_browse_info_t, 0);
2103 __bt_fill_desc_handle_informations(&desc_handles_info,
2107 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2108 BT_INFO("result = %d", result);
2110 /* Call to bt-service (sync) and send address, service_handle & char_handle infos */
2112 /* After result is fetched, extract descriptor handles (UUID's & instance_id's) */
2114 /* Fill the info in *char_prop */
2116 /*No: Before returning, call bluetooth_gatt_client_read_characteristic_value as
2117 an asyn function and leave every thing else in the callback */
2120 BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
2121 const char *address,
2122 bt_gatt_handle_property_t *service_handle,
2123 bt_gatt_handle_property_t *char_handle,
2124 bt_gatt_handle_property_t *descriptor_handle,
2125 bt_gatt_char_descriptor_property_t *desc_prop)
2127 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
2128 BT_DBG("Remote Address [%s]", address);
2130 BT_CHECK_PARAMETER(address, return);
2131 BT_CHECK_PARAMETER(service_handle, return);
2132 BT_CHECK_PARAMETER(char_handle, return);
2133 BT_CHECK_PARAMETER(descriptor_handle, return);
2134 BT_CHECK_PARAMETER(desc_prop, return);
2135 /* No Need to Call to bt-service (sync) and send address, service_handle,
2136 char_handle & descriptor handle infos */
2137 /* After result is fetched, extract descriptior handles (UUID's & instance_id's) */
2138 /* Fill the info in *desc_prop */
2139 __bt_uuid_hex_to_string(descriptor_handle->uuid, uuid_string);
2141 /* Before filling all desc handles, fill the charac's UUID and instance ID */
2142 desc_prop->uuid = g_strdup(uuid_string);
2144 return BLUETOOTH_ERROR_NONE;
2145 /* No: Before returning, call bluetooth_gatt_client_read_descriptor_value
2146 as an asyn function and leave every thing else in the callback */
2149 BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
2150 const char *address,
2151 bt_gatt_handle_property_t *service_handle,
2152 bt_gatt_handle_property_t *char_handle,
2156 int result = BLUETOOTH_ERROR_NONE;
2157 bluetooth_gatt_client_char_prop_info_t param;
2160 BT_CHECK_PARAMETER(address, return);
2161 BT_CHECK_PARAMETER(service_handle, return);
2162 BT_CHECK_PARAMETER(char_handle, return);
2164 /* ASync Function, result expected in callback from bt-service */
2167 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2169 BT_INFO("Address [%s]", address);
2170 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2172 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2173 param.svc.instance_id = service_handle->instance_id;
2175 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2176 param.characteristic.instance_id = char_handle->instance_id;
2178 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2180 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2181 g_array_append_vals(in_param2, &client_id, sizeof(int));
2182 g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
2184 result = _bt_send_request(BT_BLUEZ_SERVICE,
2185 BT_GATT_WATCH_CHARACTERISTIC,
2186 in_param1, in_param2, in_param3, in_param4, &out_param);
2188 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2190 BT_INFO("Result [%d]", result);
2194 BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
2195 const char *address,
2196 bt_gatt_handle_property_t *service_handle,
2197 bt_gatt_handle_property_t *char_handle)
2199 int result = BLUETOOTH_ERROR_NONE;
2200 bt_user_info_t *user_info;
2201 bluetooth_gatt_client_char_prop_info_t param;
2204 BT_CHECK_PARAMETER(address, return);
2205 BT_CHECK_PARAMETER(service_handle, return);
2206 BT_CHECK_PARAMETER(char_handle, return);
2208 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2209 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2212 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2214 /* Async Function, result expected in callback from bt-service */
2215 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2216 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2218 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2219 param.svc.instance_id = service_handle->instance_id;
2221 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2222 param.characteristic.instance_id = char_handle->instance_id;
2224 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2226 g_array_append_vals(in_param1, ¶m,
2227 sizeof(bluetooth_gatt_client_char_prop_info_t));
2230 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_CHARACTERISTIC,
2231 in_param1, in_param2, in_param3, in_param4,
2232 user_info->cb, user_info->user_data);
2235 BT_INFO("result = [%d]", result);
2236 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2240 BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
2241 const char *address,
2242 bt_gatt_handle_property_t *service_handle,
2243 bt_gatt_handle_property_t *char_handle,
2244 bt_gatt_handle_property_t *descriptor_handle)
2246 int result = BLUETOOTH_ERROR_NONE;
2247 bt_user_info_t *user_info;
2248 bluetooth_gatt_client_desc_prop_info_t param;
2251 BT_CHECK_PARAMETER(address, return);
2252 BT_CHECK_PARAMETER(service_handle, return);
2253 BT_CHECK_PARAMETER(char_handle, return);
2254 BT_CHECK_PARAMETER(descriptor_handle, return);
2256 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2257 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2260 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2262 /* Async Function, result expected in callback from bt-service */
2263 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2265 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2266 param.svc.instance_id = service_handle->instance_id;
2268 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2269 param.characteristic.instance_id = char_handle->instance_id;
2271 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2272 param.descriptor.instance_id = descriptor_handle->instance_id;
2274 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2276 g_array_append_vals(in_param1, ¶m,
2277 sizeof(bluetooth_gatt_client_desc_prop_info_t));
2280 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_DESCRIPTOR_VALUE,
2281 in_param1, in_param2, in_param3, in_param4,
2282 user_info->cb, user_info->user_data);
2284 BT_INFO("result = [%d]", result);
2285 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2289 BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
2290 const char *address,
2291 bt_gatt_handle_property_t *service_handle,
2292 bt_gatt_handle_property_t *char_handle,
2293 bluetooth_gatt_att_data_t *data,
2294 bluetooth_gatt_write_type_e write_type)
2296 int result = BLUETOOTH_ERROR_NONE;
2297 bt_user_info_t *user_info;
2298 bluetooth_gatt_client_char_prop_info_t param;
2301 BT_CHECK_PARAMETER(address, return);
2302 BT_CHECK_PARAMETER(service_handle, return);
2303 BT_CHECK_PARAMETER(char_handle, return);
2304 BT_CHECK_PARAMETER(data, return);
2306 /* ASync Function, result expected in callback from bt-service */
2307 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2308 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2311 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2313 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2315 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2316 param.svc.instance_id = service_handle->instance_id;
2318 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2319 param.characteristic.instance_id = char_handle->instance_id;
2321 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2323 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2324 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2325 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2327 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2328 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
2329 in_param1, in_param2, in_param3, in_param4,
2330 user_info->cb, user_info->user_data);
2332 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2337 BT_EXPORT_API int bluetooth_gatt_client_write_descriptor_value(
2338 const char *address,
2339 bt_gatt_handle_property_t *service_handle,
2340 bt_gatt_handle_property_t *char_handle,
2341 bt_gatt_handle_property_t *descriptor_handle,
2342 bluetooth_gatt_att_data_t *data,
2343 bluetooth_gatt_write_type_e write_type)
2345 int result = BLUETOOTH_ERROR_NONE;
2346 bt_user_info_t *user_info;
2347 bluetooth_gatt_client_desc_prop_info_t param;
2350 BT_CHECK_PARAMETER(address, return);
2351 BT_CHECK_PARAMETER(service_handle, return);
2352 BT_CHECK_PARAMETER(char_handle, return);
2353 BT_CHECK_PARAMETER(descriptor_handle, return);
2354 BT_CHECK_PARAMETER(data, return);
2356 /* Async Function, result expected in callback from bt-service */
2357 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2358 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2361 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2363 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2365 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2366 param.svc.instance_id = service_handle->instance_id;
2368 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2369 param.characteristic.instance_id = char_handle->instance_id;
2371 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2372 param.descriptor.instance_id = descriptor_handle->instance_id;
2374 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2376 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2377 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2378 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2380 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2381 BT_GATT_WRITE_DESCRIPTOR_VALUE,
2382 in_param1, in_param2, in_param3, in_param4,
2383 user_info->cb, user_info->user_data);
2385 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2390 BT_EXPORT_API int bluetooth_gatt_client_set_service_change_watcher(
2391 const bluetooth_device_address_t *address, gboolean enable)
2394 bluetooth_device_address_t *addr = NULL;
2395 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2396 int result = BLUETOOTH_ERROR_NONE;
2401 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2403 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
2404 g_array_append_vals(in_param2, &enable, sizeof(gboolean));
2407 _bt_convert_addr_string_to_secure_string(secure_address, (const char *)address->addr);
2408 BT_INFO("Set watcher for %s with %d", secure_address, enable);
2410 if (enable == TRUE) {
2411 if (_bluetooth_gatt_check_service_change_watcher_address(address)
2413 BT_INFO("The watcher is already set");
2414 return BLUETOOTH_ERROR_NONE;
2417 if (service_monitor_list == NULL) {
2418 //_bt_register_manager_subscribe_signal(TRUE);
2420 result = _bt_send_request(BT_BLUEZ_SERVICE,
2421 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2422 in_param1, in_param2, in_param3, in_param4, &out_param);
2425 if (result == BLUETOOTH_ERROR_NONE) {
2426 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2427 memcpy(addr, address, sizeof(bluetooth_device_address_t));
2429 service_monitor_list =
2430 g_slist_append(service_monitor_list, addr);
2433 for (l = service_monitor_list; l != NULL; l = l->next) {
2436 if (!memcmp(address, addr,
2437 sizeof(bluetooth_device_address_t))) {
2438 service_monitor_list =
2439 g_slist_remove(service_monitor_list, addr);
2445 if (service_monitor_list == NULL) {
2446 //_bt_register_manager_subscribe_signal(FALSE);
2447 result = _bt_send_request(BT_BLUEZ_SERVICE,
2448 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2449 in_param1, in_param2, in_param3, in_param4, &out_param);
2454 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2458 BT_EXPORT_API int bluetooth_gatt_client_deinit(
2463 bt_event_info_t *event_info;
2465 BT_CHECK_ENABLED(return);
2467 BT_INFO("GATT Client Deinit Client instance ID [%d]", client_id);
2470 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2472 g_array_append_vals(in_param1, &client_id, sizeof(int));
2474 /* Unregistration MUST NOT FAIL */
2475 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_UNREGISTER,
2476 in_param1, in_param2, in_param3, in_param4, &out_param);
2478 if (result != BLUETOOTH_ERROR_NONE)
2479 BT_INFO("GATT Client Unregistration failed result [%d]", result);
2481 BT_INFO("GATT Client Unregistration successful");
2483 /* Unregister event handler if this is the only instance */
2484 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
2487 count = (int*)event_info->user_data;
2489 BT_INFO("Total num of GATT client instances [%d]", *count);
2492 BT_INFO("Currently only one GATT client instance, so remove it and unregister GATT client events");
2493 _bt_unregister_event(BT_GATT_CLIENT_EVENT);
2494 _bt_set_user_data(BT_GATT_CLIENT, NULL, NULL);
2498 BT_ERR("Impossible that client is created, but no event handler is registered!!!");
2500 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);