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 #define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
39 } char_descriptor_type_t;
41 static GSList *service_monitor_list = NULL;
43 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
45 BT_CHECK_PARAMETER(svc_pty, return);
47 g_free(svc_pty->uuid);
48 g_free(svc_pty->handle);
49 g_strfreev(svc_pty->include_handles.handle);
50 g_strfreev(svc_pty->char_handle.handle);
52 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
54 return BLUETOOTH_ERROR_NONE;
57 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
59 BT_CHECK_PARAMETER(char_pty, return);
61 g_free(char_pty->uuid);
62 g_free(char_pty->name);
63 g_free(char_pty->description);
64 g_free(char_pty->val);
65 g_free(char_pty->handle);
66 g_strfreev(char_pty->char_desc_handle.handle);
68 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
70 return BLUETOOTH_ERROR_NONE;
73 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
75 BT_CHECK_PARAMETER(desc_pty, return);
77 g_free(desc_pty->uuid);
78 g_free(desc_pty->val);
79 g_free(desc_pty->handle);
81 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
83 return BLUETOOTH_ERROR_NONE;
86 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
88 gchar *gp_path = NULL;
95 path = g_malloc0((gp->len + 1) * sizeof(char *));
97 for (i = 0; i < gp->len; i++) {
98 gp_path = g_ptr_array_index(gp, i);
99 path[i] = g_strdup(gp_path);
100 // BT_DBG("path[%d] : [%s]", i, path[i]);
106 gboolean _bluetooth_gatt_check_service_change_watcher_address(
107 const bluetooth_device_address_t *device_addr)
110 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
111 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
113 _bt_convert_addr_type_to_string(device_address,
114 (unsigned char *)device_addr->addr);
116 for (l = service_monitor_list; l != NULL; l = l->next) {
117 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
118 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
119 bluetooth_device_address_t *addr = l->data;
121 _bt_convert_addr_type_to_string(device_address2,
122 (unsigned char *)addr->addr);
123 _bt_convert_addr_string_to_secure_string(secure_address,
125 _bt_convert_addr_string_to_secure_string(secure_address2,
127 BT_INFO("service_monitor_list [%s] - Input [%s]",
128 secure_address2, secure_address);
130 if (!memcmp(device_addr, addr,
131 sizeof(bluetooth_device_address_t)))
138 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
139 const bluetooth_device_address_t *address, gboolean enable)
142 bluetooth_device_address_t *addr = NULL;
143 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
144 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
146 _bt_convert_addr_type_to_string(device_address,
147 (unsigned char *)address->addr);
148 _bt_convert_addr_string_to_secure_string(secure_address,
150 BT_INFO("Set watcher for %s with %d", secure_address, enable);
152 if (enable == TRUE) {
153 if (service_monitor_list == NULL)
154 _bt_register_manager_subscribe_signal(TRUE);
156 if (_bluetooth_gatt_check_service_change_watcher_address(address)
158 BT_INFO("The watcher is already set");
159 return BLUETOOTH_ERROR_NONE;
161 addr = g_malloc0(sizeof(bluetooth_device_address_t));
162 memcpy(addr, address, sizeof(bluetooth_device_address_t));
164 if (service_monitor_list == NULL) {
165 BT_ERR("There is NO watcher");
166 return BLUETOOTH_ERROR_NONE;
169 service_monitor_list =
170 g_slist_append(service_monitor_list, addr);
172 if (service_monitor_list == NULL) {
173 BT_ERR("There is NO watcher");
174 return BLUETOOTH_ERROR_NONE;
177 for (l = service_monitor_list; l != NULL; l = l->next) {
179 if (!memcmp(address, addr,
180 sizeof(bluetooth_device_address_t))) {
181 service_monitor_list =
182 g_slist_remove(service_monitor_list, addr);
188 if (service_monitor_list == NULL)
189 _bt_register_manager_subscribe_signal(FALSE);
192 return BLUETOOTH_ERROR_NONE;
195 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
196 bt_gatt_service_property_t *service)
198 GDBusProxy *properties_proxy = NULL;
199 GError *error = NULL;
200 GVariant *result = NULL;
201 GDBusConnection *g_conn;
203 char *char_handle = NULL;
204 GPtrArray *gp_array = NULL ;
205 GVariantIter *property_iter, *char_iter = NULL;
209 BT_CHECK_PARAMETER(service_handle, return);
210 BT_CHECK_PARAMETER(service, return);
211 BT_CHECK_ENABLED(return);
213 g_conn = _bt_gdbus_get_system_gconn();
214 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
216 properties_proxy = g_dbus_proxy_new_sync(g_conn,
217 G_DBUS_PROXY_FLAGS_NONE, NULL,
220 BT_PROPERTIES_INTERFACE,
223 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
225 result = g_dbus_proxy_call_sync(properties_proxy,
227 g_variant_new("(s)", GATT_SERV_INTERFACE),
228 G_DBUS_CALL_FLAGS_NONE,
235 BT_ERR("Fail to get properties (Error: %s)", error->message);
236 g_clear_error(&error);
238 BT_ERR("Fail to get properties");
239 g_object_unref(properties_proxy);
240 return BLUETOOTH_ERROR_INTERNAL;
243 g_variant_get(result, "(a{sv})", &property_iter);
245 memset(service, 0, sizeof(bt_gatt_service_property_t));
247 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
248 if (!g_strcmp0(key, "UUID")) {
250 service->uuid = g_variant_dup_string(value, &len);
251 _bt_get_uuid_specification_name(service->uuid, &name);
252 BT_INFO("======> Service : %s [%s]", service->uuid, name);
254 } else if (!g_strcmp0(key, "Primary")) {
255 service->primary = g_variant_get_boolean(value);
257 } else if (!g_strcmp0(key, "Includes")) {
258 g_variant_get(value, "ao", &char_iter);
259 gp_array = g_ptr_array_new();
260 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
261 g_ptr_array_add(gp_array, (gpointer)char_handle);
263 if (gp_array->len != 0) {
264 service->include_handles.count = gp_array->len;
265 service->include_handles.handle =
266 __get_string_array_from_gptr_array(gp_array);
268 g_ptr_array_free(gp_array, TRUE);
269 g_variant_iter_free(char_iter);
270 } else if (!g_strcmp0(key, "Characteristics")) {
271 g_variant_get(value, "ao", &char_iter);
272 gp_array = g_ptr_array_new();
273 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
274 g_ptr_array_add(gp_array, (gpointer)char_handle);
276 if (gp_array->len != 0) {
277 service->char_handle.count = gp_array->len;
278 service->char_handle.handle =
279 __get_string_array_from_gptr_array(gp_array);
281 BT_DBG("Characteristics count : %d", service->char_handle.count);
282 g_ptr_array_free(gp_array, TRUE);
283 g_variant_iter_free(char_iter);
287 service->handle = g_strdup(service_handle);
289 g_variant_iter_free(property_iter);
290 g_variant_unref(result);
291 g_object_unref(properties_proxy);
293 return BLUETOOTH_ERROR_NONE;
296 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
297 const bluetooth_device_address_t *address,
298 bt_gatt_handle_info_t *prim_svc)
300 GVariant *result = NULL;
302 GVariantIter *svc_iter;
303 GVariantIter *interface_iter;
304 char *object_path = NULL;
305 char *interface_str = NULL;
306 const gchar *key = NULL;
307 GVariant *value = NULL;
308 GPtrArray *gp_array = NULL;
309 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
310 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
311 int ret = BLUETOOTH_ERROR_INTERNAL;
314 BT_CHECK_PARAMETER(address, return);
315 BT_CHECK_PARAMETER(prim_svc, return);
316 BT_CHECK_ENABLED(return);
318 result = _bt_get_managed_objects();
322 _bt_convert_addr_type_to_string(device_address,
323 (unsigned char *)address->addr);
325 gp_array = g_ptr_array_new();
326 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
328 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
330 if (object_path == NULL)
333 _bt_convert_device_path_to_address(object_path, temp_address);
335 if (g_strcmp0(temp_address, device_address) != 0)
338 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
339 &interface_str, &svc_iter)) {
340 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
343 BT_DBG("Object Path: %s", object_path);
344 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
345 if (g_strcmp0(key, "Primary") == 0) {
346 if (g_variant_get_boolean(value))
347 g_ptr_array_add(gp_array, (gpointer)object_path);
353 if (gp_array->len == 0) {
354 BT_ERR("gp_array is NULL");
355 ret = BLUETOOTH_ERROR_NOT_FOUND;
357 ret = BLUETOOTH_ERROR_NONE;
358 prim_svc->count = gp_array->len;
359 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
362 g_ptr_array_free(gp_array, TRUE);
363 g_variant_iter_free(iter);
364 g_variant_unref(result);
369 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
370 const char *service_uuid,
371 bt_gatt_service_property_t *service)
373 GVariant *result = NULL;
375 GVariantIter *svc_iter;
376 GVariantIter *interface_iter;
377 char *object_path = NULL;
378 char *interface_str = NULL;
379 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
380 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
381 int ret = BLUETOOTH_ERROR_INTERNAL;
383 BT_CHECK_PARAMETER(address, return);
384 BT_CHECK_PARAMETER(service_uuid, return);
385 BT_CHECK_PARAMETER(service, return);
386 BT_CHECK_ENABLED(return);
388 result = _bt_get_managed_objects();
392 _bt_convert_addr_type_to_string(device_address,
393 (unsigned char *)address->addr);
395 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
397 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
399 if (object_path == NULL)
402 _bt_convert_device_path_to_address(object_path,
405 if (g_strcmp0(temp_address, device_address) != 0)
408 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
409 &interface_str, &svc_iter)) {
410 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
413 BT_DBG("Object Path: %s", object_path);
414 ret = bluetooth_gatt_get_service_property(object_path,
417 if (ret != BLUETOOTH_ERROR_NONE) {
418 BT_ERR("Get service property failed(0x%08x)", ret);
420 if (service->primary == TRUE &&
421 g_strstr_len(service->uuid, -1,
423 ret = BLUETOOTH_ERROR_NONE;
427 bluetooth_gatt_free_service_property(service);
432 g_variant_iter_free(iter);
433 g_variant_unref(result);
438 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
439 GAsyncResult *res, gpointer user_data)
442 GVariant *char_value;
443 GVariantIter *char_iter;
444 GPtrArray *gp_array = NULL;
445 bt_gatt_discovered_char_t svc_char = { 0, };
447 GError *error = NULL;
448 bt_user_info_t *user_info;
452 user_info = _bt_get_user_data(BT_COMMON);
453 svc_char.service_handle = user_data;
455 value = g_dbus_proxy_call_finish(proxy, res, &error);
459 BT_ERR("Get service characteristics failed\n errCode[%x],"
460 "message[%s]\n", error->code, error->message);
461 g_clear_error(&error);
463 BT_ERR("Get service characteristics failed\n");
466 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
467 BLUETOOTH_ERROR_INTERNAL, NULL,
468 user_info->cb, user_info->user_data);
470 g_free(svc_char.service_handle);
471 g_object_unref(proxy);
475 g_variant_get(value, "(v)", &char_value);
476 g_variant_get(char_value, "ao", &char_iter);
478 gp_array = g_ptr_array_new();
479 while (g_variant_iter_loop(char_iter, "&o", &char_handle));
480 g_ptr_array_add(gp_array, (gpointer)char_handle);
482 if (gp_array->len != 0) {
483 svc_char.handle_info.count = gp_array->len;
484 svc_char.handle_info.handle =
485 __get_string_array_from_gptr_array(gp_array);
487 g_ptr_array_free(gp_array, TRUE);
490 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
491 BLUETOOTH_ERROR_NONE, &svc_char,
492 user_info->cb, user_info->user_data);
495 g_strfreev(svc_char.handle_info.handle);
496 g_free(svc_char.service_handle);
497 g_variant_iter_free(char_iter);
498 g_variant_unref(value);
499 g_object_unref(proxy);
502 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
503 const char *service_handle)
505 GDBusProxy *properties_proxy = NULL;
506 GDBusConnection *g_conn;
507 GError *error = NULL;
512 BT_CHECK_PARAMETER(service_handle, return);
513 BT_CHECK_ENABLED(return);
515 g_conn = _bt_gdbus_get_system_gconn();
516 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
518 properties_proxy = g_dbus_proxy_new_sync(g_conn,
519 G_DBUS_PROXY_FLAGS_NONE, NULL,
522 BT_PROPERTIES_INTERFACE,
525 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
527 handle = g_strdup(service_handle);
528 g_dbus_proxy_call(properties_proxy,
530 g_variant_new("(ss)",
531 GATT_SERV_INTERFACE, "Characteristics"),
532 G_DBUS_CALL_FLAGS_NONE,
535 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
539 return BLUETOOTH_ERROR_NONE;
543 static int __get_permission_flag(char *permission)
547 retv_if(permission == NULL, ret);
549 BT_INFO("permission = %s", permission);
551 if (!g_strcmp0(permission, "broadcast"))
552 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
553 else if (!g_strcmp0(permission, "read"))
554 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
555 else if (!g_strcmp0(permission, "write-without-response"))
556 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
557 else if (!g_strcmp0(permission, "write"))
558 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
559 else if (!g_strcmp0(permission, "notify"))
560 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
561 else if (!g_strcmp0(permission, "indicate"))
562 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
563 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
564 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
565 else if (!g_strcmp0(permission, "reliable-write"))
566 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
567 else if (!g_strcmp0(permission, "writable-auxiliaries"))
568 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
569 else if (!g_strcmp0(permission, "encrypt-read"))
570 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
571 else if (!g_strcmp0(permission, "encrypt-write"))
572 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
573 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
574 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
575 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
576 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
581 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
582 const char *char_handle, bt_gatt_char_property_t *characteristic)
584 GDBusProxy *properties_proxy = NULL;
585 GError *error = NULL;
586 GVariant *value = NULL;
587 GVariant *result = NULL;
588 GByteArray *gb_array = NULL;
589 GPtrArray *gp_array = NULL ;
590 GDBusConnection *g_conn;
594 char *char_desc_handle = NULL;
596 GVariantIter *property_iter;
597 GVariantIter *char_value_iter;
598 GVariantIter *char_perm_iter;
599 GVariantIter *char_desc_iter;
601 BT_CHECK_PARAMETER(char_handle, return);
602 BT_CHECK_PARAMETER(characteristic, return);
604 BT_CHECK_ENABLED(return);
606 g_conn = _bt_gdbus_get_system_gconn();
607 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
609 properties_proxy = g_dbus_proxy_new_sync(g_conn,
610 G_DBUS_PROXY_FLAGS_NONE, NULL,
613 BT_PROPERTIES_INTERFACE,
616 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
618 result = g_dbus_proxy_call_sync(properties_proxy,
620 g_variant_new("(s)", GATT_CHAR_INTERFACE),
621 G_DBUS_CALL_FLAGS_NONE,
628 BT_ERR("Fail to get properties (Error: %s)", error->message);
629 g_clear_error(&error);
631 BT_ERR("Fail to get properties");
632 g_object_unref(properties_proxy);
633 return BLUETOOTH_ERROR_INTERNAL;
636 g_variant_get(result, "(a{sv})", &property_iter);
638 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
639 characteristic->handle = g_strdup(char_handle);
641 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
642 if (!g_strcmp0(key, "UUID")) {
644 characteristic->uuid = g_variant_dup_string(value, &len);
645 _bt_get_uuid_specification_name(characteristic->uuid, &name);
646 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
648 } else if (!g_strcmp0(key, "Value")) {
649 gb_array = g_byte_array_new();
650 g_variant_get(value, "ay", &char_value_iter);
651 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
652 // BT_DBG("value of char = %d",char_value);
653 g_byte_array_append(gb_array, &char_value, 1);
655 g_variant_iter_free(char_value_iter);
657 if (gb_array->len != 0) {
658 characteristic->val = g_malloc0(gb_array->len *
659 sizeof(unsigned char));
660 memcpy(characteristic->val, gb_array->data, gb_array->len);
662 characteristic->val_len = gb_array->len;
663 g_byte_array_free(gb_array, TRUE);
664 } else if (!g_strcmp0(key, "Flags")) {
665 g_variant_get(value, "as", &char_perm_iter);
666 characteristic->permission = 0x00;
667 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
668 characteristic->permission |= __get_permission_flag(permission);
670 g_variant_iter_free(char_perm_iter);
671 } else if (!g_strcmp0(key, "Descriptors")) {
672 g_variant_get(value, "ao", &char_desc_iter);
673 gp_array = g_ptr_array_new();
674 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
675 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
677 g_variant_iter_free(char_desc_iter);
678 if (gp_array->len != 0) {
679 characteristic->char_desc_handle.count = gp_array->len;
680 characteristic->char_desc_handle.handle =
681 __get_string_array_from_gptr_array(gp_array);
683 g_ptr_array_free(gp_array, TRUE);
687 g_variant_iter_free(property_iter);
688 g_variant_unref(result);
689 g_object_unref(properties_proxy);
691 return BLUETOOTH_ERROR_NONE;
694 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
695 GAsyncResult *res, gpointer user_data)
698 GVariantIter *char_iter;
700 GError *error = NULL;
701 bt_user_info_t *user_info;
702 int ret = BLUETOOTH_ERROR_INTERNAL;
703 bt_gatt_char_property_t characteristic;
705 user_info = _bt_get_user_data(BT_COMMON);
707 value = g_dbus_proxy_call_finish(proxy, res, &error);
711 BT_ERR("Get service characteristics failed\n errCode[%x],"
712 "message[%s]\n", error->code, error->message);
713 g_clear_error(&error);
715 BT_ERR("Get service characteristics failed\n");
718 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
719 BLUETOOTH_ERROR_INTERNAL, NULL,
720 user_info->cb, user_info->user_data);
722 g_object_unref(proxy);
727 g_variant_get(value, "(ao)", &char_iter);
729 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
732 ret = bluetooth_gatt_get_characteristics_property(char_handle,
735 if (ret != BLUETOOTH_ERROR_NONE) {
736 BT_ERR("Get characteristic property failed(0x%08x)", ret);
738 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
739 ret = BLUETOOTH_ERROR_NONE;
743 bluetooth_gatt_free_char_property(&characteristic);
747 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
748 &characteristic, user_info->cb, user_info->user_data);
751 bluetooth_gatt_free_char_property(&characteristic);
752 g_variant_iter_free(char_iter);
753 g_variant_unref(value);
757 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
758 const char *char_uuid)
760 GDBusProxy *properties_proxy = NULL;
761 GDBusConnection *g_conn;
762 GError *error = NULL;
765 BT_CHECK_PARAMETER(service_handle, return);
766 BT_CHECK_PARAMETER(char_uuid, return);
767 BT_CHECK_ENABLED(return);
769 g_conn = _bt_gdbus_get_system_gconn();
770 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
772 properties_proxy = g_dbus_proxy_new_sync(g_conn,
773 G_DBUS_PROXY_FLAGS_NONE, NULL,
776 BT_PROPERTIES_INTERFACE,
779 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
781 uuid = g_strdup(char_uuid);
782 g_dbus_proxy_call(properties_proxy,
784 g_variant_new("(ss)",
785 GATT_SERV_INTERFACE, "Characteristics"),
786 G_DBUS_CALL_FLAGS_NONE,
789 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
792 return BLUETOOTH_ERROR_NONE;
795 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
796 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
798 GDBusProxy *properties_proxy = NULL;
799 GError *error = NULL;
800 GDBusConnection *g_conn;
801 GVariant *result = NULL;
802 GVariantIter *property_iter;
806 GVariant *value = NULL;
807 GByteArray *gb_array = NULL;
808 GVariantIter *desc_value_iter;
810 BT_CHECK_PARAMETER(descriptor_handle, return);
811 BT_CHECK_PARAMETER(descriptor, return);
813 BT_CHECK_ENABLED(return);
815 g_conn = _bt_gdbus_get_system_gconn();
816 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
818 properties_proxy = g_dbus_proxy_new_sync(g_conn,
819 G_DBUS_PROXY_FLAGS_NONE, NULL,
822 BT_PROPERTIES_INTERFACE,
825 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
827 result = g_dbus_proxy_call_sync(properties_proxy,
829 g_variant_new("(s)", GATT_DESC_INTERFACE),
830 G_DBUS_CALL_FLAGS_NONE,
837 BT_ERR("Fail to get properties (Error: %s)", error->message);
838 g_clear_error(&error);
840 BT_ERR("Fail to get properties");
841 g_object_unref(properties_proxy);
842 return BLUETOOTH_ERROR_INTERNAL;
845 g_variant_get(result, "(a{sv})", &property_iter);
847 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
848 descriptor->handle = g_strdup(descriptor_handle);
850 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
851 if (!g_strcmp0(key, "UUID")) {
853 descriptor->uuid = g_variant_dup_string(value, &len);
854 _bt_get_uuid_specification_name(descriptor->uuid, &name);
855 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
857 } else if (!g_strcmp0(key, "Value")) {
858 gb_array = g_byte_array_new();
859 g_variant_get(value, "ay", &desc_value_iter);
860 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
861 BT_DBG("value of descriptor = %d", char_value);
862 g_byte_array_append(gb_array, &char_value, 1);
864 g_variant_iter_free(desc_value_iter);
866 if (gb_array->len != 0) {
867 descriptor->val = g_malloc0(gb_array->len *
868 sizeof(unsigned char));
869 memcpy(descriptor->val, gb_array->data, gb_array->len);
871 descriptor->val_len = gb_array->len;
872 g_byte_array_free(gb_array, TRUE);
876 g_variant_iter_free(property_iter);
877 g_variant_unref(result);
878 g_object_unref(properties_proxy);
880 return BLUETOOTH_ERROR_NONE;
883 static void __bluetooth_internal_read_cb(GObject *source_object,
887 GError *error = NULL;
888 bt_user_info_t *user_info;
889 bt_gatt_char_value_t char_value = { 0, };
890 GDBusConnection *system_gconn = NULL;
892 GByteArray *gp_byte_array = NULL;
895 int ret = BLUETOOTH_ERROR_NONE;
898 user_info = _bt_get_user_data(BT_COMMON);
900 system_gconn = _bt_gdbus_get_system_gconn();
901 value = g_dbus_connection_call_finish(system_gconn, res, &error);
904 BT_ERR("Error : %s \n", error->message);
905 if (g_strrstr(error->message, "Not paired"))
906 ret = BLUETOOTH_ERROR_NOT_PAIRED;
908 ret = BLUETOOTH_ERROR_INTERNAL;
910 g_clear_error(&error);
912 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
914 user_info->cb, user_info->user_data);
920 char_value.char_handle = user_data;
921 gp_byte_array = g_byte_array_new();
922 g_variant_get(value, "(ay)", &iter);
924 while (g_variant_iter_loop(iter, "y", &g_byte))
925 g_byte_array_append(gp_byte_array, &g_byte, 1);
927 if (gp_byte_array->len != 0) {
928 char_value.val_len = gp_byte_array->len;
929 char_value.char_value = gp_byte_array->data;
933 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
934 BLUETOOTH_ERROR_NONE, &char_value,
935 user_info->cb, user_info->user_data);
938 g_free(char_value.char_handle);
939 g_byte_array_free(gp_byte_array, TRUE);
940 g_variant_unref(value);
941 g_variant_iter_free(iter);
946 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *characteristic)
948 GDBusConnection *conn;
951 BT_CHECK_PARAMETER(characteristic, return);
952 BT_CHECK_ENABLED(return);
954 conn = _bt_gdbus_get_system_gconn();
955 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
957 handle = g_strdup(characteristic);
959 g_dbus_connection_call(conn,
965 G_VARIANT_TYPE("(ay)"),
966 G_DBUS_CALL_FLAGS_NONE,
969 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
972 return BLUETOOTH_ERROR_NONE;
975 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
976 const char *char_handle, const guint8 *value, int length)
979 GVariantBuilder *builder;
980 GError *error = NULL;
981 GDBusConnection *conn;
985 BT_CHECK_PARAMETER(char_handle, return);
986 BT_CHECK_PARAMETER(value, return);
987 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
988 BT_CHECK_ENABLED(return);
990 conn = _bt_gdbus_get_system_gconn();
991 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
993 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
995 for (i = 0; i < length; i++)
996 g_variant_builder_add(builder, "y", value[i]);
998 val = g_variant_new("(ay)", builder);
1000 g_dbus_connection_call_sync(conn,
1003 GATT_CHAR_INTERFACE,
1007 G_DBUS_CALL_FLAGS_NONE,
1011 BT_ERR("Set value Failed: %s", error->message);
1012 g_clear_error(&error);
1013 g_variant_builder_unref(builder);
1014 return BLUETOOTH_ERROR_INTERNAL;
1017 g_variant_builder_unref(builder);
1020 return BLUETOOTH_ERROR_NONE;
1023 static void __bluetooth_internal_write_cb(GObject *source_object,
1027 GError *error = NULL;
1028 bt_user_info_t *user_info;
1029 GDBusConnection *system_gconn = NULL;
1031 int result = BLUETOOTH_ERROR_NONE;
1032 guint8 att_ecode = 0;
1034 user_info = _bt_get_user_data(BT_COMMON);
1036 system_gconn = _bt_gdbus_get_system_gconn();
1037 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1040 BT_ERR("Error : %s \n", error->message);
1041 g_clear_error(&error);
1042 result = BLUETOOTH_ERROR_INTERNAL;
1044 g_variant_get(value, "(y)", &att_ecode);
1047 BT_ERR("ATT Error code: %d \n", att_ecode);
1052 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1054 user_info->cb, user_info->user_data);
1056 BT_ERR("user info is null");
1060 g_variant_unref(value);
1065 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1066 const char *char_handle, const guint8 *value, int length, guint8 write_type)
1069 GVariantBuilder *builder;
1070 GDBusConnection *conn;
1072 int ret = BLUETOOTH_ERROR_NONE;
1074 BT_CHECK_PARAMETER(char_handle, return);
1075 BT_CHECK_PARAMETER(value, return);
1076 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1077 BT_CHECK_ENABLED_INTERNAL(return);
1079 conn = _bt_gdbus_get_system_gconn();
1080 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1082 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1084 for (i = 0; i < length; i++)
1085 g_variant_builder_add(builder, "y", value[i]);
1087 val = g_variant_new("ay", builder);
1088 g_dbus_connection_call(conn,
1091 GATT_CHAR_INTERFACE,
1093 g_variant_new("(y@ay)", write_type, val),
1094 G_VARIANT_TYPE("(y)"),
1095 G_DBUS_CALL_FLAGS_NONE,
1097 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1100 g_variant_builder_unref(builder);
1104 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1105 const char *char_handle, const guint8 *value, int length)
1108 GDBusConnection *conn;
1109 GVariantBuilder *builder;
1113 BT_CHECK_PARAMETER(char_handle, return);
1114 BT_CHECK_PARAMETER(value, return);
1115 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1116 BT_CHECK_ENABLED(return);
1118 conn = _bt_gdbus_get_system_gconn();
1119 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1121 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1123 for (i = 0; i < length; i++) {
1124 g_variant_builder_add(builder, "y", value[i]);
1125 BT_DBG("value [] = %d", value[i]);
1128 val = g_variant_new("(ay)", builder);
1130 g_dbus_connection_call(conn,
1133 GATT_CHAR_INTERFACE,
1137 G_DBUS_CALL_FLAGS_NONE,
1139 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1142 g_variant_builder_unref(builder);
1145 return BLUETOOTH_ERROR_NONE;
1148 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1149 bt_gatt_char_property_t *characteristic)
1152 GDBusProxy *properties_proxy = NULL;
1153 GError *error = NULL;
1154 GVariant *value = NULL;
1155 GVariant *result = NULL;
1156 GDBusConnection *g_conn;
1157 int i, ret = BLUETOOTH_ERROR_NONE;
1158 const char *uuid = NULL;
1160 GVariantIter *desc_value_iter, *property_iter;
1162 char_descriptor_type_t desc_type = TYPE_NONE;
1164 g_conn = _bt_gdbus_get_system_gconn();
1165 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1167 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1168 G_DBUS_PROXY_FLAGS_NONE, NULL,
1171 BT_PROPERTIES_INTERFACE,
1174 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1176 result = g_dbus_proxy_call_sync(properties_proxy,
1178 g_variant_new("(s)", GATT_DESC_INTERFACE),
1179 G_DBUS_CALL_FLAGS_NONE,
1185 if (error != NULL) {
1186 BT_ERR("Fail to get properties (Error: %s)", error->message);
1187 g_clear_error(&error);
1189 BT_ERR("Fail to get properties");
1190 g_object_unref(properties_proxy);
1191 return BLUETOOTH_ERROR_INTERNAL;
1193 g_variant_get(result, "(a{sv})", &property_iter);
1194 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1195 if (!g_strcmp0(key, "UUID")) {
1196 uuid = g_variant_get_string(value, &len);
1197 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1198 BT_DBG("GATT_USER_DESC_UUID");
1199 desc_type = USER_DESC;
1200 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1201 BT_DBG("GATT_CHAR_FORMAT");
1202 desc_type = CHAR_FORMAT;
1203 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1204 BT_DBG("GATT_CHAR_CLIENT_CONF");
1205 desc_type = CLIENT_CONF;
1206 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1207 BT_DBG("GATT_CHAR_SERVER_CONF");
1208 desc_type = SERVER_CONF;
1210 BT_DBG("descriptor uuid = %s", uuid);
1212 } else if (!g_strcmp0(key, "Value")) {
1213 switch (desc_type) {
1215 BT_DBG("Format descriptor");
1216 g_variant_get(value, "(yyqyq)",
1217 &(characteristic->format.format),
1218 &(characteristic->format.exponent),
1219 &(characteristic->format.unit),
1220 &(characteristic->format.name_space),
1221 &(characteristic->format.description));
1224 BT_DBG("User descriptor");
1225 g_variant_get(value, "ay", &desc_value_iter);
1226 len = g_variant_get_size((GVariant *)desc_value_iter);
1229 characteristic->description = (char *)g_malloc0(len + 1);
1231 for (i = 0; i < len; i++) {
1232 g_variant_iter_loop(desc_value_iter, "y",
1233 &characteristic->description[i]);
1234 BT_DBG("description = %s", characteristic->description);
1236 g_variant_iter_free(desc_value_iter);
1239 BT_DBG(" CLIENT_CONF");
1242 BT_DBG(" SERVER_CONF");
1250 g_variant_iter_free(property_iter);
1251 g_variant_unref(result);
1252 g_object_unref(properties_proxy);
1259 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1260 GAsyncResult *res, gpointer user_data)
1264 GVariant *char_value;
1265 GVariantIter *char_iter;
1267 GError *error = NULL;
1268 bt_user_info_t *user_info;
1269 bt_gatt_char_property_t characteristic = {0, };
1270 int ret = BLUETOOTH_ERROR_INTERNAL;
1272 user_info = _bt_get_user_data(BT_COMMON);
1274 value = g_dbus_proxy_call_finish(proxy, res, &error);
1276 if (value == NULL) {
1277 if (error != NULL) {
1278 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1279 "message[%s]\n", error->code, error->message);
1280 g_clear_error(&error);
1282 BT_ERR("Get characteristic descriptor failed\n");
1285 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1286 BLUETOOTH_ERROR_INTERNAL, NULL,
1287 user_info->cb, user_info->user_data);
1290 g_object_unref(proxy);
1294 g_variant_get(value, "(v)", &char_value);
1295 g_variant_get(char_value, "ao", &char_iter);
1297 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1298 BT_DBG("object path of descriptor = %s", char_handle);
1300 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1302 BT_DBG("Descriptor read status [%d]", ret);
1306 characteristic.handle = user_data;
1308 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1309 ret, &characteristic, user_info->cb, user_info->user_data);
1311 bluetooth_gatt_free_char_property(&characteristic);
1313 g_variant_iter_free(char_iter);
1314 g_variant_unref(value);
1318 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1319 const char *characteristic_handle)
1321 GDBusProxy *properties_proxy = NULL;
1322 GDBusConnection *g_conn;
1324 GError *error = NULL;
1326 BT_CHECK_PARAMETER(characteristic_handle, return);
1327 BT_CHECK_ENABLED(return);
1329 g_conn = _bt_gdbus_get_system_gconn();
1330 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1332 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1333 G_DBUS_PROXY_FLAGS_NONE, NULL,
1335 characteristic_handle,
1336 BT_PROPERTIES_INTERFACE,
1339 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1341 handle = g_strdup(characteristic_handle);
1342 g_dbus_proxy_call(properties_proxy,
1344 g_variant_new("(ss)",
1345 GATT_CHAR_INTERFACE, "Descriptors"),
1346 G_DBUS_CALL_FLAGS_NONE,
1348 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1351 return BLUETOOTH_ERROR_NONE;
1354 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1358 GError *error = NULL;
1359 bt_user_info_t *user_info;
1360 bt_gatt_char_property_t char_value = { 0, };
1361 GDBusConnection *system_gconn = NULL;
1363 GByteArray *gp_byte_array = NULL;
1368 user_info = _bt_get_user_data(BT_COMMON);
1369 system_gconn = _bt_gdbus_get_system_gconn();
1371 char_value.handle = user_data;
1372 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1375 BT_ERR("Error : %s \n", error->message);
1376 g_clear_error(&error);
1378 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1379 BLUETOOTH_ERROR_INTERNAL, NULL,
1380 user_info->cb, user_info->user_data);
1382 g_free(char_value.handle);
1386 gp_byte_array = g_byte_array_new();
1387 g_variant_get(value, "(ay)", &iter);
1389 while (g_variant_iter_loop(iter, "y", &g_byte))
1390 g_byte_array_append(gp_byte_array, &g_byte, 1);
1392 if (gp_byte_array->len != 0) {
1393 char_value.val_len = (unsigned int)gp_byte_array->len;
1394 char_value.description = (char *)gp_byte_array->data;
1398 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1399 BLUETOOTH_ERROR_NONE, &char_value,
1400 user_info->cb, user_info->user_data);
1403 g_byte_array_free(gp_byte_array, TRUE);
1404 g_free(char_value.handle);
1405 g_variant_unref(value);
1406 g_variant_iter_free(iter);
1411 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descriptor)
1413 GDBusConnection *conn;
1417 BT_CHECK_PARAMETER(char_descriptor, return);
1418 BT_CHECK_ENABLED(return);
1420 conn = _bt_gdbus_get_system_gconn();
1421 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1423 handle = g_strdup(char_descriptor);
1425 g_dbus_connection_call(conn,
1428 GATT_DESC_INTERFACE,
1431 G_VARIANT_TYPE("(ay)"),
1432 G_DBUS_CALL_FLAGS_NONE,
1435 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1439 return BLUETOOTH_ERROR_NONE;
1442 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1446 GError *error = NULL;
1447 bt_user_info_t *user_info;
1448 GDBusConnection *system_gconn = NULL;
1450 int result = BLUETOOTH_ERROR_NONE;
1451 guint8 att_ecode = 0;
1454 user_info = _bt_get_user_data(BT_COMMON);
1456 system_gconn = _bt_gdbus_get_system_gconn();
1457 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1460 BT_ERR("Error : %s \n", error->message);
1461 g_clear_error(&error);
1462 result = BLUETOOTH_ERROR_INTERNAL;
1464 g_variant_get(value, "(y)", &att_ecode);
1467 BT_ERR("ATT Error code: %d \n", att_ecode);
1472 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1474 user_info->cb, user_info->user_data);
1478 g_variant_unref(value);
1483 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
1484 const char *desc_handle, const guint8 *value, int length)
1487 GDBusConnection *conn;
1488 GVariantBuilder *builder;
1492 BT_CHECK_PARAMETER(desc_handle, return);
1493 BT_CHECK_PARAMETER(value, return);
1494 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1495 BT_CHECK_ENABLED(return);
1497 conn = _bt_gdbus_get_system_gconn();
1498 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1500 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1502 for (i = 0; i < length; i++)
1503 g_variant_builder_add(builder, "y", value[i]);
1505 val = g_variant_new("(ay)", builder);
1507 g_dbus_connection_call(conn,
1510 GATT_DESC_INTERFACE,
1513 G_VARIANT_TYPE("(y)"),
1514 G_DBUS_CALL_FLAGS_NONE,
1516 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1519 g_variant_builder_unref(builder);
1522 return BLUETOOTH_ERROR_NONE;
1525 #ifndef GATT_NO_RELAY
1526 static int __bluetooth_gatt_watch_characteristics(void)
1528 int result = BLUETOOTH_ERROR_NONE;
1531 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1533 result = _bt_send_request(BT_BLUEZ_SERVICE,
1534 BT_GATT_WATCH_CHARACTERISTIC,
1535 in_param1, in_param2, in_param3, in_param4, &out_param);
1537 if (result != BLUETOOTH_ERROR_NONE)
1538 BT_ERR("Watch Characteristic request failed !");
1540 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1546 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1548 GDBusConnection *conn;
1549 GError *error = NULL;
1550 int ret = BLUETOOTH_ERROR_NONE;
1552 BT_CHECK_PARAMETER(char_handle, return);
1553 BT_CHECK_ENABLED(return);
1555 BT_INFO_C("### Enable CCCD : %s", char_handle);
1557 conn = _bt_gdbus_get_system_gconn();
1558 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1560 g_dbus_connection_call_sync(conn,
1563 GATT_CHAR_INTERFACE,
1567 G_DBUS_CALL_FLAGS_NONE,
1568 GATT_DEFAULT_TIMEOUT, NULL, &error);
1571 g_dbus_error_strip_remote_error(error);
1572 BT_ERR_C("### Watch Failed: %s", error->message);
1573 if (g_strrstr(error->message, "Already notifying"))
1574 ret = BLUETOOTH_ERROR_NONE;
1575 else if (g_strrstr(error->message, "In Progress"))
1576 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1577 else if (g_strrstr(error->message, "Operation is not supported"))
1578 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1579 /*failed because of either Insufficient Authorization or Write Not Permitted */
1580 else if (g_strrstr(error->message, "Write not permitted") ||
1581 g_strrstr(error->message, "Operation Not Authorized"))
1582 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1583 /* failed because of either Insufficient Authentication,
1584 Insufficient Encryption Key Size, or Insufficient Encryption. */
1585 else if (g_strrstr(error->message, "Not paired"))
1586 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1588 ret = BLUETOOTH_ERROR_INTERNAL;
1590 g_clear_error(&error);
1592 #ifndef GATT_NO_RELAY
1594 /* Register the client sender to bt-service */
1595 ret = __bluetooth_gatt_watch_characteristics();
1602 #ifndef GATT_NO_RELAY
1603 static int __bluetooth_gatt_unwatch_characteristics(void)
1605 int result = BLUETOOTH_ERROR_NONE;
1608 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1610 result = _bt_send_request(BT_BLUEZ_SERVICE,
1611 BT_GATT_UNWATCH_CHARACTERISTIC,
1612 in_param1, in_param2, in_param3, in_param4, &out_param);
1614 if (result != BLUETOOTH_ERROR_NONE)
1615 BT_ERR("Unwatch Characteristic request failed !");
1617 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1623 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1626 GDBusConnection *conn;
1627 GError *error = NULL;
1628 int ret = BLUETOOTH_ERROR_NONE;
1629 BT_CHECK_PARAMETER(char_handle, return);
1631 BT_CHECK_ENABLED(return);
1633 BT_INFO("Disable CCCD : %s", char_handle);
1635 conn = _bt_gdbus_get_system_gconn();
1636 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1638 g_dbus_connection_call_sync(conn,
1641 GATT_CHAR_INTERFACE,
1645 G_DBUS_CALL_FLAGS_NONE,
1646 GATT_DEFAULT_TIMEOUT, NULL, &error);
1649 BT_ERR("Watch Failed: %s", error->message);
1650 g_clear_error(&error);
1651 ret = BLUETOOTH_ERROR_INTERNAL;
1653 #ifndef GATT_NO_RELAY
1655 /* Unregister the client sender to bt-service */
1656 ret = __bluetooth_gatt_unwatch_characteristics();