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 (30 * 1000) /* ATT transaction timeout */
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)
111 for (l = service_monitor_list; l != NULL; l = l->next) {
112 bluetooth_device_address_t *addr = l->data;
114 if (!memcmp(device_addr, addr,
115 sizeof(bluetooth_device_address_t)))
122 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
123 const bluetooth_device_address_t *address, gboolean enable)
126 bluetooth_device_address_t *addr = NULL;
127 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
129 _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
130 BT_INFO("Set watcher for %s with %d", secure_address, enable);
132 if (enable == TRUE) {
133 if (_bluetooth_gatt_check_service_change_watcher_address(address)
135 BT_INFO("The watcher is already set");
136 return BLUETOOTH_ERROR_NONE;
139 if (service_monitor_list == NULL) {
140 _bt_register_manager_subscribe_signal(TRUE);
143 addr = g_malloc0(sizeof(bluetooth_device_address_t));
144 memcpy(addr, address, sizeof(bluetooth_device_address_t));
146 service_monitor_list =
147 g_slist_append(service_monitor_list, addr);
149 for (l = service_monitor_list; l != NULL; l = l->next) {
152 if (!memcmp(address, addr,
153 sizeof(bluetooth_device_address_t))) {
154 service_monitor_list =
155 g_slist_remove(service_monitor_list, addr);
161 if (service_monitor_list == NULL)
162 _bt_register_manager_subscribe_signal(FALSE);
165 return BLUETOOTH_ERROR_NONE;
168 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
169 bt_gatt_service_property_t *service)
171 GDBusProxy *properties_proxy = NULL;
172 GError *error = NULL;
173 GVariant *result = NULL;
174 GDBusConnection *g_conn;
176 char *char_handle = NULL;
177 GPtrArray *gp_array = NULL ;
178 GVariantIter *property_iter, *char_iter = NULL;
182 BT_CHECK_PARAMETER(service_handle, return);
183 BT_CHECK_PARAMETER(service, return);
184 BT_CHECK_ENABLED(return);
186 g_conn = _bt_gdbus_get_system_gconn();
187 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
189 properties_proxy = g_dbus_proxy_new_sync(g_conn,
190 G_DBUS_PROXY_FLAGS_NONE, NULL,
193 BT_PROPERTIES_INTERFACE,
196 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
198 result = g_dbus_proxy_call_sync(properties_proxy,
200 g_variant_new("(s)", GATT_SERV_INTERFACE),
201 G_DBUS_CALL_FLAGS_NONE,
208 BT_ERR("Fail to get properties (Error: %s)", error->message);
209 g_clear_error(&error);
211 BT_ERR("Fail to get properties");
212 g_object_unref(properties_proxy);
213 return BLUETOOTH_ERROR_INTERNAL;
216 g_variant_get(result, "(a{sv})", &property_iter);
218 memset(service, 0, sizeof(bt_gatt_service_property_t));
220 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
221 if (!g_strcmp0(key, "UUID")) {
223 service->uuid = g_variant_dup_string(value, &len);
224 _bt_get_uuid_specification_name(service->uuid, &name);
225 BT_INFO("======> Service : %s [%s]", service->uuid, name);
227 } else if (!g_strcmp0(key, "Primary")) {
228 service->primary = g_variant_get_boolean(value);
230 } else if (!g_strcmp0(key, "Includes")) {
231 g_variant_get(value, "ao", &char_iter);
232 if (char_iter != NULL) {
233 gp_array = g_ptr_array_new();
234 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
235 g_ptr_array_add(gp_array, (gpointer)char_handle);
237 if (gp_array->len != 0) {
238 service->include_handles.count = gp_array->len;
239 service->include_handles.handle =
240 __get_string_array_from_gptr_array(gp_array);
242 g_ptr_array_free(gp_array, TRUE);
243 g_variant_iter_free(char_iter);
245 } else if (!g_strcmp0(key, "Characteristics")) {
246 g_variant_get(value, "ao", &char_iter);
247 if (char_iter != NULL) {
248 gp_array = g_ptr_array_new();
249 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
250 g_ptr_array_add(gp_array, (gpointer)char_handle);
252 if (gp_array->len != 0) {
253 service->char_handle.count = gp_array->len;
254 service->char_handle.handle =
255 __get_string_array_from_gptr_array(gp_array);
257 g_ptr_array_free(gp_array, TRUE);
258 g_variant_iter_free(char_iter);
260 BT_DBG("Characteristics count : %d", service->char_handle.count);
264 service->handle = g_strdup(service_handle);
266 g_variant_iter_free(property_iter);
267 g_variant_unref(result);
268 g_object_unref(properties_proxy);
270 return BLUETOOTH_ERROR_NONE;
273 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
274 const bluetooth_device_address_t *address,
275 bt_gatt_handle_info_t *prim_svc)
277 GVariant *result = NULL;
279 GVariantIter *svc_iter;
280 GVariantIter *interface_iter;
281 char *object_path = NULL;
282 char *interface_str = NULL;
283 const gchar *key = NULL;
284 GVariant *value = NULL;
285 GPtrArray *gp_array = NULL;
286 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
287 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
288 int ret = BLUETOOTH_ERROR_INTERNAL;
291 BT_CHECK_PARAMETER(address, return);
292 BT_CHECK_PARAMETER(prim_svc, return);
293 BT_CHECK_ENABLED(return);
295 result = _bt_get_managed_objects();
299 _bt_convert_addr_type_to_string(device_address,
300 (unsigned char *)address->addr);
302 gp_array = g_ptr_array_new();
303 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
305 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
307 if (object_path == NULL)
310 _bt_convert_device_path_to_address(object_path, temp_address);
312 if (g_strcmp0(temp_address, device_address) != 0)
315 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
316 &interface_str, &svc_iter)) {
317 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
320 BT_DBG("Object Path: %s", object_path);
321 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
322 if (g_strcmp0(key, "Primary") == 0) {
323 if (g_variant_get_boolean(value))
324 g_ptr_array_add(gp_array, (gpointer)object_path);
330 if (gp_array->len == 0) {
331 BT_ERR("gp_array is NULL");
332 ret = BLUETOOTH_ERROR_NOT_FOUND;
334 ret = BLUETOOTH_ERROR_NONE;
335 prim_svc->count = gp_array->len;
336 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
339 g_ptr_array_free(gp_array, TRUE);
340 g_variant_iter_free(iter);
341 g_variant_unref(result);
346 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
347 const char *service_uuid,
348 bt_gatt_service_property_t *service)
350 GVariant *result = NULL;
352 GVariantIter *svc_iter;
353 GVariantIter *interface_iter;
354 char *object_path = NULL;
355 char *interface_str = NULL;
356 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
357 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
358 int ret = BLUETOOTH_ERROR_INTERNAL;
360 BT_CHECK_PARAMETER(address, return);
361 BT_CHECK_PARAMETER(service_uuid, return);
362 BT_CHECK_PARAMETER(service, return);
363 BT_CHECK_ENABLED(return);
365 result = _bt_get_managed_objects();
369 _bt_convert_addr_type_to_string(device_address,
370 (unsigned char *)address->addr);
372 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
374 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
376 if (object_path == NULL)
379 _bt_convert_device_path_to_address(object_path,
382 if (g_strcmp0(temp_address, device_address) != 0)
385 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
386 &interface_str, &svc_iter)) {
387 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
390 BT_DBG("Object Path: %s", object_path);
391 ret = bluetooth_gatt_get_service_property(object_path,
394 if (ret != BLUETOOTH_ERROR_NONE) {
395 BT_ERR("Get service property failed(0x%08x)", ret);
397 if (service->primary == TRUE &&
398 g_strstr_len(service->uuid, -1,
400 ret = BLUETOOTH_ERROR_NONE;
404 bluetooth_gatt_free_service_property(service);
409 g_variant_iter_free(iter);
410 g_variant_unref(result);
415 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
416 GAsyncResult *res, gpointer user_data)
419 GVariant *char_value;
420 GVariantIter *char_iter;
421 GPtrArray *gp_array = NULL;
422 bt_gatt_discovered_char_t svc_char = { 0, };
424 GError *error = NULL;
425 bt_user_info_t *user_info;
429 user_info = _bt_get_user_data(BT_COMMON);
430 svc_char.service_handle = user_data;
432 value = g_dbus_proxy_call_finish(proxy, res, &error);
436 BT_ERR("Get service characteristics failed\n errCode[%x],"
437 "message[%s]\n", error->code, error->message);
438 g_clear_error(&error);
440 BT_ERR("Get service characteristics failed\n");
443 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
444 BLUETOOTH_ERROR_INTERNAL, NULL,
445 user_info->cb, user_info->user_data);
447 g_free(svc_char.service_handle);
448 g_object_unref(proxy);
452 g_variant_get(value, "(v)", &char_value);
453 g_variant_get(char_value, "ao", &char_iter);
455 gp_array = g_ptr_array_new();
456 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
457 g_ptr_array_add(gp_array, (gpointer)char_handle);
459 if (gp_array->len != 0) {
460 svc_char.handle_info.count = gp_array->len;
461 svc_char.handle_info.handle =
462 __get_string_array_from_gptr_array(gp_array);
464 g_ptr_array_free(gp_array, TRUE);
467 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
468 BLUETOOTH_ERROR_NONE, &svc_char,
469 user_info->cb, user_info->user_data);
472 g_strfreev(svc_char.handle_info.handle);
473 g_free(svc_char.service_handle);
474 g_variant_iter_free(char_iter);
475 g_variant_unref(value);
476 g_object_unref(proxy);
479 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
480 const char *service_handle)
482 GDBusProxy *properties_proxy = NULL;
483 GDBusConnection *g_conn;
484 GError *error = NULL;
489 BT_CHECK_PARAMETER(service_handle, return);
490 BT_CHECK_ENABLED(return);
492 g_conn = _bt_gdbus_get_system_gconn();
493 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
495 properties_proxy = g_dbus_proxy_new_sync(g_conn,
496 G_DBUS_PROXY_FLAGS_NONE, NULL,
499 BT_PROPERTIES_INTERFACE,
502 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
504 handle = g_strdup(service_handle);
505 g_dbus_proxy_call(properties_proxy,
507 g_variant_new("(ss)",
508 GATT_SERV_INTERFACE, "Characteristics"),
509 G_DBUS_CALL_FLAGS_NONE,
512 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
516 return BLUETOOTH_ERROR_NONE;
520 static int __get_permission_flag(char *permission)
524 retv_if(permission == NULL, ret);
526 BT_INFO("permission = %s", permission);
528 if (!g_strcmp0(permission, "broadcast"))
529 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
530 else if (!g_strcmp0(permission, "read"))
531 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
532 else if (!g_strcmp0(permission, "write-without-response"))
533 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
534 else if (!g_strcmp0(permission, "write"))
535 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
536 else if (!g_strcmp0(permission, "notify"))
537 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
538 else if (!g_strcmp0(permission, "indicate"))
539 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
540 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
541 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
542 else if (!g_strcmp0(permission, "reliable-write"))
543 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
544 else if (!g_strcmp0(permission, "writable-auxiliaries"))
545 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
546 else if (!g_strcmp0(permission, "encrypt-read"))
547 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
548 else if (!g_strcmp0(permission, "encrypt-write"))
549 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
550 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
551 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
552 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
553 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
558 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
559 const char *char_handle, bt_gatt_char_property_t *characteristic)
561 GDBusProxy *properties_proxy = NULL;
562 GError *error = NULL;
563 GVariant *value = NULL;
564 GVariant *result = NULL;
565 GByteArray *gb_array = NULL;
566 GPtrArray *gp_array = NULL ;
567 GDBusConnection *g_conn;
571 char *char_desc_handle = NULL;
573 GVariantIter *property_iter;
574 GVariantIter *char_value_iter;
575 GVariantIter *char_perm_iter;
576 GVariantIter *char_desc_iter;
578 BT_CHECK_PARAMETER(char_handle, return);
579 BT_CHECK_PARAMETER(characteristic, return);
581 BT_CHECK_ENABLED(return);
583 g_conn = _bt_gdbus_get_system_gconn();
584 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
586 properties_proxy = g_dbus_proxy_new_sync(g_conn,
587 G_DBUS_PROXY_FLAGS_NONE, NULL,
590 BT_PROPERTIES_INTERFACE,
593 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
595 result = g_dbus_proxy_call_sync(properties_proxy,
597 g_variant_new("(s)", GATT_CHAR_INTERFACE),
598 G_DBUS_CALL_FLAGS_NONE,
605 BT_ERR("Fail to get properties (Error: %s)", error->message);
606 g_clear_error(&error);
608 BT_ERR("Fail to get properties");
609 g_object_unref(properties_proxy);
610 return BLUETOOTH_ERROR_INTERNAL;
613 g_variant_get(result, "(a{sv})", &property_iter);
615 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
616 characteristic->handle = g_strdup(char_handle);
618 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
619 if (!g_strcmp0(key, "UUID")) {
621 characteristic->uuid = g_variant_dup_string(value, &len);
622 _bt_get_uuid_specification_name(characteristic->uuid, &name);
623 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
625 } else if (!g_strcmp0(key, "Value")) {
626 gb_array = g_byte_array_new();
627 g_variant_get(value, "ay", &char_value_iter);
628 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
629 // BT_DBG("value of char = %d",char_value);
630 g_byte_array_append(gb_array, &char_value, 1);
632 g_variant_iter_free(char_value_iter);
634 if (gb_array->len != 0) {
635 characteristic->val = g_malloc0(gb_array->len *
636 sizeof(unsigned char));
637 memcpy(characteristic->val, gb_array->data, gb_array->len);
639 characteristic->val_len = gb_array->len;
640 g_byte_array_free(gb_array, TRUE);
641 } else if (!g_strcmp0(key, "Flags")) {
642 g_variant_get(value, "as", &char_perm_iter);
643 characteristic->permission = 0x00;
645 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
646 characteristic->permission |= __get_permission_flag(permission);
648 g_variant_iter_free(char_perm_iter);
649 } else if (!g_strcmp0(key, "Descriptors")) {
650 g_variant_get(value, "ao", &char_desc_iter);
651 gp_array = g_ptr_array_new();
652 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
653 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
655 g_variant_iter_free(char_desc_iter);
656 if (gp_array->len != 0) {
657 characteristic->char_desc_handle.count = gp_array->len;
658 characteristic->char_desc_handle.handle =
659 __get_string_array_from_gptr_array(gp_array);
661 g_ptr_array_free(gp_array, TRUE);
665 g_variant_iter_free(property_iter);
666 g_variant_unref(result);
667 g_object_unref(properties_proxy);
669 return BLUETOOTH_ERROR_NONE;
672 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
673 GAsyncResult *res, gpointer user_data)
676 GVariantIter *char_iter;
678 GError *error = NULL;
679 bt_user_info_t *user_info;
680 int ret = BLUETOOTH_ERROR_INTERNAL;
681 bt_gatt_char_property_t characteristic;
683 user_info = _bt_get_user_data(BT_COMMON);
685 value = g_dbus_proxy_call_finish(proxy, res, &error);
689 BT_ERR("Get service characteristics failed\n errCode[%x],"
690 "message[%s]\n", error->code, error->message);
691 g_clear_error(&error);
693 BT_ERR("Get service characteristics failed\n");
696 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
697 BLUETOOTH_ERROR_INTERNAL, NULL,
698 user_info->cb, user_info->user_data);
700 g_object_unref(proxy);
705 g_variant_get(value, "(ao)", &char_iter);
707 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
710 ret = bluetooth_gatt_get_characteristics_property(char_handle,
713 if (ret != BLUETOOTH_ERROR_NONE) {
714 BT_ERR("Get characteristic property failed(0x%08x)", ret);
716 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
717 ret = BLUETOOTH_ERROR_NONE;
721 bluetooth_gatt_free_char_property(&characteristic);
725 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
726 &characteristic, user_info->cb, user_info->user_data);
729 bluetooth_gatt_free_char_property(&characteristic);
730 g_variant_iter_free(char_iter);
731 g_variant_unref(value);
735 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
736 const char *char_uuid)
738 GDBusProxy *properties_proxy = NULL;
739 GDBusConnection *g_conn;
740 GError *error = NULL;
743 BT_CHECK_PARAMETER(service_handle, return);
744 BT_CHECK_PARAMETER(char_uuid, return);
745 BT_CHECK_ENABLED(return);
747 g_conn = _bt_gdbus_get_system_gconn();
748 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
750 properties_proxy = g_dbus_proxy_new_sync(g_conn,
751 G_DBUS_PROXY_FLAGS_NONE, NULL,
754 BT_PROPERTIES_INTERFACE,
757 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
759 uuid = g_strdup(char_uuid);
760 g_dbus_proxy_call(properties_proxy,
762 g_variant_new("(ss)",
763 GATT_SERV_INTERFACE, "Characteristics"),
764 G_DBUS_CALL_FLAGS_NONE,
767 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
770 return BLUETOOTH_ERROR_NONE;
773 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
774 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
776 GDBusProxy *properties_proxy = NULL;
777 GError *error = NULL;
778 GDBusConnection *g_conn;
779 GVariant *result = NULL;
780 GVariantIter *property_iter;
784 GVariant *value = NULL;
785 GByteArray *gb_array = NULL;
786 GVariantIter *desc_value_iter;
788 BT_CHECK_PARAMETER(descriptor_handle, return);
789 BT_CHECK_PARAMETER(descriptor, return);
791 BT_CHECK_ENABLED(return);
793 g_conn = _bt_gdbus_get_system_gconn();
794 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
796 properties_proxy = g_dbus_proxy_new_sync(g_conn,
797 G_DBUS_PROXY_FLAGS_NONE, NULL,
800 BT_PROPERTIES_INTERFACE,
803 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
805 result = g_dbus_proxy_call_sync(properties_proxy,
807 g_variant_new("(s)", GATT_DESC_INTERFACE),
808 G_DBUS_CALL_FLAGS_NONE,
815 BT_ERR("Fail to get properties (Error: %s)", error->message);
816 g_clear_error(&error);
818 BT_ERR("Fail to get properties");
819 g_object_unref(properties_proxy);
820 return BLUETOOTH_ERROR_INTERNAL;
823 g_variant_get(result, "(a{sv})", &property_iter);
825 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
826 descriptor->handle = g_strdup(descriptor_handle);
828 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
829 if (!g_strcmp0(key, "UUID")) {
831 descriptor->uuid = g_variant_dup_string(value, &len);
832 _bt_get_uuid_specification_name(descriptor->uuid, &name);
833 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
835 } else if (!g_strcmp0(key, "Value")) {
836 gb_array = g_byte_array_new();
837 g_variant_get(value, "ay", &desc_value_iter);
838 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
839 BT_DBG("value of descriptor = %d", char_value);
840 g_byte_array_append(gb_array, &char_value, 1);
842 g_variant_iter_free(desc_value_iter);
844 if (gb_array->len != 0) {
845 descriptor->val = g_malloc0(gb_array->len *
846 sizeof(unsigned char));
847 memcpy(descriptor->val, gb_array->data, gb_array->len);
849 descriptor->val_len = gb_array->len;
850 g_byte_array_free(gb_array, TRUE);
854 g_variant_iter_free(property_iter);
855 g_variant_unref(result);
856 g_object_unref(properties_proxy);
858 return BLUETOOTH_ERROR_NONE;
861 static void __bluetooth_internal_read_cb(GObject *source_object,
862 GAsyncResult *res, gpointer user_data)
864 GError *error = NULL;
865 GDBusConnection *system_gconn = NULL;
867 bt_user_info_t *user_info;
869 GByteArray *gp_byte_array = NULL;
871 int ret = BLUETOOTH_ERROR_NONE;
872 bt_gatt_resp_data_t *resp_data = user_data;
876 system_gconn = _bt_gdbus_get_system_gconn();
877 value = g_dbus_connection_call_finish(system_gconn, res, &error);
879 user_info = _bt_get_user_data(BT_COMMON);
883 BT_ERR("Error : %s", error->message);
884 g_clear_error(&error);
887 g_variant_unref(value);
892 BT_ERR("Error : %s", error->message);
893 if (g_strrstr(error->message, "Not paired"))
894 ret = BLUETOOTH_ERROR_NOT_PAIRED;
896 ret = BLUETOOTH_ERROR_INTERNAL;
897 g_clear_error(&error);
899 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
901 user_info->cb, user_info->user_data);
906 gp_byte_array = g_byte_array_new();
907 g_variant_get(value, "(ay)", &iter);
909 while (g_variant_iter_loop(iter, "y", &g_byte))
910 g_byte_array_append(gp_byte_array, &g_byte, 1);
912 if (gp_byte_array->len != 0) {
913 resp_data->len = gp_byte_array->len;
914 resp_data->value = gp_byte_array->data;
917 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
918 BLUETOOTH_ERROR_NONE, resp_data,
919 user_info->cb, user_info->user_data);
922 g_byte_array_free(gp_byte_array, TRUE);
923 g_variant_iter_free(iter);
924 g_variant_unref(value);
929 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
932 GDBusConnection *conn;
933 bt_gatt_resp_data_t *resp_data;
935 BT_CHECK_PARAMETER(chr, return);
936 BT_CHECK_ENABLED(return);
938 conn = _bt_gdbus_get_system_gconn();
939 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
941 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
942 resp_data->user_data = user_data;
944 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
945 "ReadValue", NULL, G_VARIANT_TYPE("(ay)"),
946 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
947 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
948 (gpointer)resp_data);
950 return BLUETOOTH_ERROR_NONE;
953 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
954 const char *char_handle, const guint8 *value, int length)
957 GVariantBuilder *builder;
958 GError *error = NULL;
959 GDBusConnection *conn;
963 BT_CHECK_PARAMETER(char_handle, return);
964 BT_CHECK_PARAMETER(value, return);
965 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
966 BT_CHECK_ENABLED(return);
968 conn = _bt_gdbus_get_system_gconn();
969 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
971 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
973 for (i = 0; i < length; i++)
974 g_variant_builder_add(builder, "y", value[i]);
976 val = g_variant_new("(ay)", builder);
978 g_dbus_connection_call_sync(conn,
985 G_DBUS_CALL_FLAGS_NONE,
989 BT_ERR("Set value Failed: %s", error->message);
990 g_clear_error(&error);
991 g_variant_builder_unref(builder);
992 return BLUETOOTH_ERROR_INTERNAL;
995 g_variant_builder_unref(builder);
998 return BLUETOOTH_ERROR_NONE;
1001 static void __bluetooth_internal_write_cb(GObject *source_object,
1002 GAsyncResult *res, gpointer user_data)
1004 GError *error = NULL;
1005 GDBusConnection *system_gconn = NULL;
1006 bt_user_info_t *user_info;
1008 int result = BLUETOOTH_ERROR_NONE;
1009 guint8 att_ecode = 0;
1010 bt_gatt_resp_data_t *resp_data = user_data;
1012 system_gconn = _bt_gdbus_get_system_gconn();
1013 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1015 user_info = _bt_get_user_data(BT_COMMON);
1019 BT_ERR("Error : %s", error->message);
1020 g_clear_error(&error);
1023 g_variant_unref(value);
1028 BT_ERR("Error : %s", error->message);
1029 g_clear_error(&error);
1031 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1032 BLUETOOTH_ERROR_INTERNAL, resp_data,
1033 user_info->cb, user_info->user_data);
1038 g_variant_get(value, "(y)", &att_ecode);
1040 BT_ERR("ATT Error code: %d", att_ecode);
1044 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1046 user_info->cb, user_info->user_data);
1049 g_variant_unref(value);
1053 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1054 const char *chr, const guint8 *value, int length,
1055 guint8 write_type, gpointer user_data)
1058 GVariantBuilder *builder;
1059 GDBusConnection *conn;
1061 bt_gatt_resp_data_t *resp_data;
1063 BT_CHECK_PARAMETER(chr, return);
1064 BT_CHECK_PARAMETER(value, return);
1065 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1066 BT_CHECK_ENABLED_INTERNAL(return);
1068 conn = _bt_gdbus_get_system_gconn();
1069 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1071 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1072 for (i = 0; i < length; i++)
1073 g_variant_builder_add(builder, "y", value[i]);
1074 val = g_variant_new("ay", builder);
1076 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1077 resp_data->user_data = user_data;
1079 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1081 g_variant_new("(y@ay)", write_type, val),
1082 G_VARIANT_TYPE("(y)"),
1083 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1084 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1085 (gpointer)resp_data);
1087 g_variant_builder_unref(builder);
1089 return BLUETOOTH_ERROR_NONE;
1092 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1093 const char *char_handle, const guint8 *value, int length)
1096 GDBusConnection *conn;
1097 GVariantBuilder *builder;
1101 BT_CHECK_PARAMETER(char_handle, return);
1102 BT_CHECK_PARAMETER(value, return);
1103 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1104 BT_CHECK_ENABLED(return);
1106 conn = _bt_gdbus_get_system_gconn();
1107 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1109 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1111 for (i = 0; i < length; i++) {
1112 g_variant_builder_add(builder, "y", value[i]);
1113 BT_DBG("value [] = %d", value[i]);
1116 val = g_variant_new("(ay)", builder);
1118 g_dbus_connection_call(conn,
1121 GATT_CHAR_INTERFACE,
1125 G_DBUS_CALL_FLAGS_NONE,
1127 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1130 g_variant_builder_unref(builder);
1133 return BLUETOOTH_ERROR_NONE;
1136 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1137 bt_gatt_char_property_t *characteristic)
1140 GDBusProxy *properties_proxy = NULL;
1141 GError *error = NULL;
1142 GVariant *value = NULL;
1143 GVariant *result = NULL;
1144 GDBusConnection *g_conn;
1145 int i, ret = BLUETOOTH_ERROR_NONE;
1146 const char *uuid = NULL;
1148 GVariantIter *desc_value_iter, *property_iter;
1150 char_descriptor_type_t desc_type = TYPE_NONE;
1152 g_conn = _bt_gdbus_get_system_gconn();
1153 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1155 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1156 G_DBUS_PROXY_FLAGS_NONE, NULL,
1159 BT_PROPERTIES_INTERFACE,
1162 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1164 result = g_dbus_proxy_call_sync(properties_proxy,
1166 g_variant_new("(s)", GATT_DESC_INTERFACE),
1167 G_DBUS_CALL_FLAGS_NONE,
1173 if (error != NULL) {
1174 BT_ERR("Fail to get properties (Error: %s)", error->message);
1175 g_clear_error(&error);
1177 BT_ERR("Fail to get properties");
1178 g_object_unref(properties_proxy);
1179 return BLUETOOTH_ERROR_INTERNAL;
1181 g_variant_get(result, "(a{sv})", &property_iter);
1182 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1183 if (!g_strcmp0(key, "UUID")) {
1184 uuid = g_variant_get_string(value, &len);
1185 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1186 BT_DBG("GATT_USER_DESC_UUID");
1187 desc_type = USER_DESC;
1188 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1189 BT_DBG("GATT_CHAR_FORMAT");
1190 desc_type = CHAR_FORMAT;
1191 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1192 BT_DBG("GATT_CHAR_CLIENT_CONF");
1193 desc_type = CLIENT_CONF;
1194 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1195 BT_DBG("GATT_CHAR_SERVER_CONF");
1196 desc_type = SERVER_CONF;
1198 BT_DBG("descriptor uuid = %s", uuid);
1200 } else if (!g_strcmp0(key, "Value")) {
1201 switch (desc_type) {
1203 BT_DBG("Format descriptor");
1204 g_variant_get(value, "(yyqyq)",
1205 &(characteristic->format.format),
1206 &(characteristic->format.exponent),
1207 &(characteristic->format.unit),
1208 &(characteristic->format.name_space),
1209 &(characteristic->format.description));
1212 BT_DBG("User descriptor");
1213 g_variant_get(value, "ay", &desc_value_iter);
1214 len = g_variant_get_size((GVariant *)desc_value_iter);
1217 characteristic->description = (char *)g_malloc0(len + 1);
1219 for (i = 0; i < len; i++) {
1220 g_variant_iter_loop(desc_value_iter, "y",
1221 &characteristic->description[i]);
1222 BT_DBG("description = %s", characteristic->description);
1224 g_variant_iter_free(desc_value_iter);
1227 BT_DBG(" CLIENT_CONF");
1230 BT_DBG(" SERVER_CONF");
1238 g_variant_iter_free(property_iter);
1239 g_variant_unref(result);
1240 g_object_unref(properties_proxy);
1247 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1248 GAsyncResult *res, gpointer user_data)
1252 GVariant *char_value;
1253 GVariantIter *char_iter;
1255 GError *error = NULL;
1256 bt_user_info_t *user_info;
1257 bt_gatt_char_property_t characteristic = {0, };
1258 int ret = BLUETOOTH_ERROR_INTERNAL;
1260 user_info = _bt_get_user_data(BT_COMMON);
1262 value = g_dbus_proxy_call_finish(proxy, res, &error);
1264 if (value == NULL) {
1265 if (error != NULL) {
1266 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1267 "message[%s]\n", error->code, error->message);
1268 g_clear_error(&error);
1270 BT_ERR("Get characteristic descriptor failed\n");
1273 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1274 BLUETOOTH_ERROR_INTERNAL, NULL,
1275 user_info->cb, user_info->user_data);
1278 g_object_unref(proxy);
1282 g_variant_get(value, "(v)", &char_value);
1283 g_variant_get(char_value, "ao", &char_iter);
1285 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1286 BT_DBG("object path of descriptor = %s", char_handle);
1288 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1290 BT_DBG("Descriptor read status [%d]", ret);
1294 characteristic.handle = user_data;
1296 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1297 ret, &characteristic, user_info->cb, user_info->user_data);
1299 bluetooth_gatt_free_char_property(&characteristic);
1301 g_variant_iter_free(char_iter);
1302 g_variant_unref(value);
1306 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1307 const char *characteristic_handle)
1309 GDBusProxy *properties_proxy = NULL;
1310 GDBusConnection *g_conn;
1312 GError *error = NULL;
1314 BT_CHECK_PARAMETER(characteristic_handle, return);
1315 BT_CHECK_ENABLED(return);
1317 g_conn = _bt_gdbus_get_system_gconn();
1318 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1320 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1321 G_DBUS_PROXY_FLAGS_NONE, NULL,
1323 characteristic_handle,
1324 BT_PROPERTIES_INTERFACE,
1327 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1329 handle = g_strdup(characteristic_handle);
1330 g_dbus_proxy_call(properties_proxy,
1332 g_variant_new("(ss)",
1333 GATT_CHAR_INTERFACE, "Descriptors"),
1334 G_DBUS_CALL_FLAGS_NONE,
1336 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1339 return BLUETOOTH_ERROR_NONE;
1342 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1346 GError *error = NULL;
1347 GDBusConnection *system_gconn = NULL;
1349 bt_user_info_t *user_info;
1350 GByteArray *gp_byte_array = NULL;
1353 bt_gatt_resp_data_t *resp_data = user_data;
1357 system_gconn = _bt_gdbus_get_system_gconn();
1358 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1360 user_info = _bt_get_user_data(BT_COMMON);
1364 BT_ERR("Error : %s", error->message);
1365 g_clear_error(&error);
1368 g_variant_unref(value);
1373 BT_ERR("Error : %s", error->message);
1374 g_clear_error(&error);
1376 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1377 BLUETOOTH_ERROR_INTERNAL, resp_data,
1378 user_info->cb, user_info->user_data);
1383 gp_byte_array = g_byte_array_new();
1384 g_variant_get(value, "(ay)", &iter);
1386 while (g_variant_iter_loop(iter, "y", &g_byte))
1387 g_byte_array_append(gp_byte_array, &g_byte, 1);
1389 if (gp_byte_array->len != 0) {
1390 resp_data->len = gp_byte_array->len;
1391 resp_data->value = gp_byte_array->data;
1394 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1395 BLUETOOTH_ERROR_NONE, resp_data,
1396 user_info->cb, user_info->user_data);
1400 g_byte_array_free(gp_byte_array, TRUE);
1401 g_variant_iter_free(iter);
1402 g_variant_unref(value);
1407 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1410 GDBusConnection *conn;
1411 bt_gatt_resp_data_t *resp_data;
1415 BT_CHECK_PARAMETER(desc, return);
1416 BT_CHECK_ENABLED(return);
1418 conn = _bt_gdbus_get_system_gconn();
1419 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1421 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1422 resp_data->user_data = user_data;
1424 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1425 "ReadValue", NULL, G_VARIANT_TYPE("(ay)"),
1426 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1427 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1428 (gpointer)resp_data);
1431 return BLUETOOTH_ERROR_NONE;
1434 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1435 GAsyncResult *res, gpointer user_data)
1437 GError *error = NULL;
1438 bt_user_info_t *user_info;
1439 GDBusConnection *system_gconn = NULL;
1441 int result = BLUETOOTH_ERROR_NONE;
1442 guint8 att_ecode = 0;
1443 bt_gatt_resp_data_t *resp_data = user_data;
1447 system_gconn = _bt_gdbus_get_system_gconn();
1448 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1450 user_info = _bt_get_user_data(BT_COMMON);
1454 BT_ERR("Error : %s", error->message);
1455 g_clear_error(&error);
1458 g_variant_unref(value);
1463 BT_ERR("Error : %s", error->message);
1464 g_clear_error(&error);
1466 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1467 BLUETOOTH_ERROR_INTERNAL, resp_data,
1468 user_info->cb, user_info->user_data);
1472 g_variant_get(value, "(y)", &att_ecode);
1474 BT_ERR("ATT Error code: %d", att_ecode);
1478 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC, result, resp_data,
1479 user_info->cb, user_info->user_data);
1482 g_variant_unref(value);
1486 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1487 const guint8 *value, int length, gpointer user_data)
1490 GDBusConnection *conn;
1491 GVariantBuilder *builder;
1493 bt_gatt_resp_data_t *resp_data;
1497 BT_CHECK_PARAMETER(desc, return);
1498 BT_CHECK_PARAMETER(value, return);
1499 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1500 BT_CHECK_ENABLED(return);
1502 conn = _bt_gdbus_get_system_gconn();
1503 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1505 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1506 for (i = 0; i < length; i++)
1507 g_variant_builder_add(builder, "y", value[i]);
1508 val = g_variant_new("(ay)", builder);
1510 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1511 resp_data->user_data = user_data;
1513 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1514 "WriteValue", val, G_VARIANT_TYPE("(y)"),
1515 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1516 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1517 (gpointer)resp_data);
1518 g_variant_builder_unref(builder);
1521 return BLUETOOTH_ERROR_NONE;
1524 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1526 GDBusConnection *conn;
1527 GError *error = NULL;
1528 int ret = BLUETOOTH_ERROR_NONE;
1530 BT_CHECK_PARAMETER(char_handle, return);
1531 BT_CHECK_ENABLED(return);
1533 BT_INFO_C("### Enable CCCD : %s", char_handle);
1535 conn = _bt_gdbus_get_system_gconn();
1536 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1538 g_dbus_connection_call_sync(conn,
1541 GATT_CHAR_INTERFACE,
1545 G_DBUS_CALL_FLAGS_NONE,
1546 GATT_DEFAULT_TIMEOUT, NULL, &error);
1549 g_dbus_error_strip_remote_error(error);
1550 BT_ERR_C("### Watch Failed: %s", error->message);
1551 if (g_strrstr(error->message, "Already notifying"))
1552 ret = BLUETOOTH_ERROR_NONE;
1553 else if (g_strrstr(error->message, "In Progress"))
1554 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1555 else if (g_strrstr(error->message, "Operation is not supported"))
1556 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1557 /*failed because of either Insufficient Authorization or Write Not Permitted */
1558 else if (g_strrstr(error->message, "Write not permitted") ||
1559 g_strrstr(error->message, "Operation Not Authorized"))
1560 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1561 /* failed because of either Insufficient Authentication,
1562 Insufficient Encryption Key Size, or Insufficient Encryption. */
1563 else if (g_strrstr(error->message, "Not paired"))
1564 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1566 ret = BLUETOOTH_ERROR_INTERNAL;
1568 g_clear_error(&error);
1574 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1577 GDBusConnection *conn;
1578 GError *error = NULL;
1579 int ret = BLUETOOTH_ERROR_NONE;
1580 BT_CHECK_PARAMETER(char_handle, return);
1582 BT_CHECK_ENABLED(return);
1584 BT_INFO("Disable CCCD : %s", char_handle);
1586 conn = _bt_gdbus_get_system_gconn();
1587 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1589 g_dbus_connection_call_sync(conn,
1592 GATT_CHAR_INTERFACE,
1596 G_DBUS_CALL_FLAGS_NONE,
1597 GATT_DEFAULT_TIMEOUT, NULL, &error);
1600 BT_ERR("Watch Failed: %s", error->message);
1601 g_clear_error(&error);
1602 ret = BLUETOOTH_ERROR_INTERNAL;