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 /* Fix : NULL_RETURNS */
101 for (i = 0; i < gp->len; i++) {
102 gp_path = g_ptr_array_index(gp, i);
103 path[i] = g_strdup(gp_path);
104 // BT_DBG("path[%d] : [%s]", i, path[i]);
110 gboolean _bluetooth_gatt_check_service_change_watcher_address(
111 const bluetooth_device_address_t *device_addr)
114 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
115 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
117 _bt_convert_addr_type_to_string(device_address,
118 (unsigned char *)device_addr->addr);
120 for (l = service_monitor_list; l != NULL; l = l->next) {
121 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
122 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
123 bluetooth_device_address_t *addr = l->data;
125 _bt_convert_addr_type_to_string(device_address2,
126 (unsigned char *)addr->addr);
127 _bt_convert_addr_string_to_secure_string(secure_address,
129 _bt_convert_addr_string_to_secure_string(secure_address2,
131 BT_INFO("service_monitor_list [%s] - Input [%s]",
132 secure_address2, secure_address);
134 if (!memcmp(device_addr, addr,
135 sizeof(bluetooth_device_address_t)))
142 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
143 const bluetooth_device_address_t *address, gboolean enable)
146 bluetooth_device_address_t *addr = NULL;
147 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
148 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
150 _bt_convert_addr_type_to_string(device_address,
151 (unsigned char *)address->addr);
152 _bt_convert_addr_string_to_secure_string(secure_address,
154 BT_INFO("Set watcher for %s with %d", secure_address, enable);
156 if (enable == TRUE) {
157 if (service_monitor_list == NULL)
158 _bt_register_manager_subscribe_signal(TRUE);
160 if (_bluetooth_gatt_check_service_change_watcher_address(address)
162 BT_INFO("The watcher is already set");
163 return BLUETOOTH_ERROR_NONE;
165 addr = g_malloc0(sizeof(bluetooth_device_address_t));
166 memcpy(addr, address, sizeof(bluetooth_device_address_t));
168 if (service_monitor_list == NULL) {
169 BT_ERR("There is NO watcher");
170 return BLUETOOTH_ERROR_NONE;
173 service_monitor_list =
174 g_slist_append(service_monitor_list, addr);
176 if (service_monitor_list == NULL) {
177 BT_ERR("There is NO watcher");
178 return BLUETOOTH_ERROR_NONE;
181 for (l = service_monitor_list; l != NULL; l = l->next) {
183 if (!memcmp(address, addr,
184 sizeof(bluetooth_device_address_t))) {
185 service_monitor_list =
186 g_slist_remove(service_monitor_list, addr);
192 if (service_monitor_list == NULL)
193 _bt_register_manager_subscribe_signal(FALSE);
196 return BLUETOOTH_ERROR_NONE;
199 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
200 bt_gatt_service_property_t *service)
202 GDBusProxy *properties_proxy = NULL;
203 GError *error = NULL;
204 GVariant *result = NULL;
205 GDBusConnection *g_conn;
207 char *char_handle = NULL;
208 GPtrArray *gp_array = NULL ;
209 GVariantIter *property_iter, *char_iter = NULL;
213 BT_CHECK_PARAMETER(service_handle, return);
214 BT_CHECK_PARAMETER(service, return);
215 BT_CHECK_ENABLED(return);
217 g_conn = _bt_gdbus_get_system_gconn();
218 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
220 properties_proxy = g_dbus_proxy_new_sync(g_conn,
221 G_DBUS_PROXY_FLAGS_NONE, NULL,
224 BT_PROPERTIES_INTERFACE,
227 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
229 result = g_dbus_proxy_call_sync(properties_proxy,
231 g_variant_new("(s)", GATT_SERV_INTERFACE),
232 G_DBUS_CALL_FLAGS_NONE,
239 BT_ERR("Fail to get properties (Error: %s)", error->message);
240 g_clear_error(&error);
242 BT_ERR("Fail to get properties");
243 g_object_unref(properties_proxy);
244 return BLUETOOTH_ERROR_INTERNAL;
247 g_variant_get(result, "(a{sv})", &property_iter);
249 memset(service, 0, sizeof(bt_gatt_service_property_t));
251 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
252 if (!g_strcmp0(key, "UUID")) {
254 service->uuid = g_variant_dup_string(value, &len);
255 _bt_get_uuid_specification_name(service->uuid, &name);
256 BT_INFO("======> Service : %s [%s]", service->uuid, name);
258 } else if (!g_strcmp0(key, "Primary")) {
259 service->primary = g_variant_get_boolean(value);
261 } else if (!g_strcmp0(key, "Includes")) {
262 g_variant_get(value, "ao", &char_iter);
263 gp_array = g_ptr_array_new();
264 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
265 g_ptr_array_add(gp_array, (gpointer)char_handle);
267 if (gp_array->len != 0) {
268 service->include_handles.count = gp_array->len;
269 service->include_handles.handle =
270 __get_string_array_from_gptr_array(gp_array);
272 g_ptr_array_free(gp_array, TRUE);
273 g_variant_iter_free(char_iter);
274 } else if (!g_strcmp0(key, "Characteristics")) {
275 g_variant_get(value, "ao", &char_iter);
276 gp_array = g_ptr_array_new();
277 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
278 g_ptr_array_add(gp_array, (gpointer)char_handle);
280 if (gp_array->len != 0) {
281 service->char_handle.count = gp_array->len;
282 service->char_handle.handle =
283 __get_string_array_from_gptr_array(gp_array);
285 BT_DBG("Characteristics count : %d", service->char_handle.count);
286 g_ptr_array_free(gp_array, TRUE);
287 g_variant_iter_free(char_iter);
291 service->handle = g_strdup(service_handle);
293 g_variant_iter_free(property_iter);
294 g_variant_unref(result);
295 g_object_unref(properties_proxy);
297 return BLUETOOTH_ERROR_NONE;
300 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
301 const bluetooth_device_address_t *address,
302 bt_gatt_handle_info_t *prim_svc)
304 GVariant *result = NULL;
306 GVariantIter *svc_iter;
307 GVariantIter *interface_iter;
308 char *object_path = NULL;
309 char *interface_str = NULL;
310 const gchar *key = NULL;
311 GVariant *value = NULL;
312 GPtrArray *gp_array = NULL;
313 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
314 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
315 int ret = BLUETOOTH_ERROR_INTERNAL;
318 BT_CHECK_PARAMETER(address, return);
319 BT_CHECK_PARAMETER(prim_svc, return);
320 BT_CHECK_ENABLED(return);
322 result = _bt_get_managed_objects();
326 _bt_convert_addr_type_to_string(device_address,
327 (unsigned char *)address->addr);
329 gp_array = g_ptr_array_new();
330 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
332 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
334 if (object_path == NULL)
337 _bt_convert_device_path_to_address(object_path, temp_address);
339 if (g_strcmp0(temp_address, device_address) != 0)
342 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
343 &interface_str, &svc_iter)) {
344 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
347 BT_DBG("Object Path: %s", object_path);
348 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
349 if (g_strcmp0(key, "Primary") == 0) {
350 if (g_variant_get_boolean(value))
351 g_ptr_array_add(gp_array, (gpointer)object_path);
357 if (gp_array->len == 0) {
358 BT_ERR("gp_array is NULL");
359 ret = BLUETOOTH_ERROR_NOT_FOUND;
361 ret = BLUETOOTH_ERROR_NONE;
362 prim_svc->count = gp_array->len;
363 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
366 g_ptr_array_free(gp_array, TRUE);
367 g_variant_iter_free(iter);
368 g_variant_unref(result);
373 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
374 const char *service_uuid,
375 bt_gatt_service_property_t *service)
377 GVariant *result = NULL;
379 GVariantIter *svc_iter;
380 GVariantIter *interface_iter;
381 char *object_path = NULL;
382 char *interface_str = NULL;
383 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
384 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
385 int ret = BLUETOOTH_ERROR_INTERNAL;
387 BT_CHECK_PARAMETER(address, return);
388 BT_CHECK_PARAMETER(service_uuid, return);
389 BT_CHECK_PARAMETER(service, return);
390 BT_CHECK_ENABLED(return);
392 result = _bt_get_managed_objects();
396 _bt_convert_addr_type_to_string(device_address,
397 (unsigned char *)address->addr);
399 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
401 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
403 if (object_path == NULL)
406 _bt_convert_device_path_to_address(object_path,
409 if (g_strcmp0(temp_address, device_address) != 0)
412 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
413 &interface_str, &svc_iter)) {
414 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
417 BT_DBG("Object Path: %s", object_path);
418 ret = bluetooth_gatt_get_service_property(object_path,
421 if (ret != BLUETOOTH_ERROR_NONE) {
422 BT_ERR("Get service property failed(0x%08x)", ret);
424 if (service->primary == TRUE &&
425 g_strstr_len(service->uuid, -1,
427 ret = BLUETOOTH_ERROR_NONE;
431 bluetooth_gatt_free_service_property(service);
436 g_variant_iter_free(iter);
437 g_variant_unref(result);
442 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
443 GAsyncResult *res, gpointer user_data)
446 GVariant *char_value;
447 GVariantIter *char_iter;
448 GPtrArray *gp_array = NULL;
449 bt_gatt_discovered_char_t svc_char = { 0, };
451 GError *error = NULL;
452 bt_user_info_t *user_info;
456 user_info = _bt_get_user_data(BT_COMMON);
457 svc_char.service_handle = user_data;
459 value = g_dbus_proxy_call_finish(proxy, res, &error);
463 BT_ERR("Get service characteristics failed\n errCode[%x],"
464 "message[%s]\n", error->code, error->message);
465 g_clear_error(&error);
467 BT_ERR("Get service characteristics failed\n");
470 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
471 BLUETOOTH_ERROR_INTERNAL, NULL,
472 user_info->cb, user_info->user_data);
474 g_free(svc_char.service_handle);
475 g_object_unref(proxy);
479 g_variant_get(value, "(v)", &char_value);
480 g_variant_get(char_value, "ao", &char_iter);
482 gp_array = g_ptr_array_new();
483 while (g_variant_iter_loop(char_iter, "&o", &char_handle));
484 g_ptr_array_add(gp_array, (gpointer)char_handle);
486 if (gp_array->len != 0) {
487 svc_char.handle_info.count = gp_array->len;
488 svc_char.handle_info.handle =
489 __get_string_array_from_gptr_array(gp_array);
491 g_ptr_array_free(gp_array, TRUE);
494 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
495 BLUETOOTH_ERROR_NONE, &svc_char,
496 user_info->cb, user_info->user_data);
499 g_strfreev(svc_char.handle_info.handle);
500 g_free(svc_char.service_handle);
501 g_variant_iter_free(char_iter);
502 g_variant_unref(value);
503 g_object_unref(proxy);
506 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
507 const char *service_handle)
509 GDBusProxy *properties_proxy = NULL;
510 GDBusConnection *g_conn;
511 GError *error = NULL;
516 BT_CHECK_PARAMETER(service_handle, return);
517 BT_CHECK_ENABLED(return);
519 g_conn = _bt_gdbus_get_system_gconn();
520 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
522 properties_proxy = g_dbus_proxy_new_sync(g_conn,
523 G_DBUS_PROXY_FLAGS_NONE, NULL,
526 BT_PROPERTIES_INTERFACE,
529 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
531 handle = g_strdup(service_handle);
532 g_dbus_proxy_call(properties_proxy,
534 g_variant_new("(ss)",
535 GATT_SERV_INTERFACE, "Characteristics"),
536 G_DBUS_CALL_FLAGS_NONE,
539 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
543 return BLUETOOTH_ERROR_NONE;
547 static int __get_permission_flag(char *permission)
551 retv_if(permission == NULL, ret);
553 BT_INFO("permission = %s", permission);
555 if (!g_strcmp0(permission, "broadcast"))
556 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
557 else if (!g_strcmp0(permission, "read"))
558 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
559 else if (!g_strcmp0(permission, "write-without-response"))
560 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
561 else if (!g_strcmp0(permission, "write"))
562 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
563 else if (!g_strcmp0(permission, "notify"))
564 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
565 else if (!g_strcmp0(permission, "indicate"))
566 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
567 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
568 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
569 else if (!g_strcmp0(permission, "reliable-write"))
570 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
571 else if (!g_strcmp0(permission, "writable-auxiliaries"))
572 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
573 else if (!g_strcmp0(permission, "encrypt-read"))
574 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
575 else if (!g_strcmp0(permission, "encrypt-write"))
576 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
577 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
578 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
579 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
580 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
585 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
586 const char *char_handle, bt_gatt_char_property_t *characteristic)
588 GDBusProxy *properties_proxy = NULL;
589 GError *error = NULL;
590 GVariant *value = NULL;
591 GVariant *result = NULL;
592 GByteArray *gb_array = NULL;
593 GPtrArray *gp_array = NULL ;
594 GDBusConnection *g_conn;
598 char *char_desc_handle = NULL;
600 GVariantIter *property_iter;
601 GVariantIter *char_value_iter;
602 GVariantIter *char_perm_iter;
603 GVariantIter *char_desc_iter;
605 BT_CHECK_PARAMETER(char_handle, return);
606 BT_CHECK_PARAMETER(characteristic, return);
608 BT_CHECK_ENABLED(return);
610 g_conn = _bt_gdbus_get_system_gconn();
611 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
613 properties_proxy = g_dbus_proxy_new_sync(g_conn,
614 G_DBUS_PROXY_FLAGS_NONE, NULL,
617 BT_PROPERTIES_INTERFACE,
620 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
622 result = g_dbus_proxy_call_sync(properties_proxy,
624 g_variant_new("(s)", GATT_CHAR_INTERFACE),
625 G_DBUS_CALL_FLAGS_NONE,
632 BT_ERR("Fail to get properties (Error: %s)", error->message);
633 g_clear_error(&error);
635 BT_ERR("Fail to get properties");
636 g_object_unref(properties_proxy);
637 return BLUETOOTH_ERROR_INTERNAL;
640 g_variant_get(result, "(a{sv})", &property_iter);
642 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
643 characteristic->handle = g_strdup(char_handle);
645 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
646 if (!g_strcmp0(key, "UUID")) {
648 characteristic->uuid = g_variant_dup_string(value, &len);
649 _bt_get_uuid_specification_name(characteristic->uuid, &name);
650 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
652 } else if (!g_strcmp0(key, "Value")) {
653 gb_array = g_byte_array_new();
654 g_variant_get(value, "ay", &char_value_iter);
655 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
656 // BT_DBG("value of char = %d",char_value);
657 g_byte_array_append(gb_array, &char_value, 1);
659 g_variant_iter_free(char_value_iter);
661 if (gb_array->len != 0) {
662 characteristic->val = g_malloc0(gb_array->len *
663 sizeof(unsigned char));
664 memcpy(characteristic->val, gb_array->data, gb_array->len);
666 characteristic->val_len = gb_array->len;
667 g_byte_array_free(gb_array, TRUE);
668 } else if (!g_strcmp0(key, "Flags")) {
669 g_variant_get(value, "as", &char_perm_iter);
670 characteristic->permission = 0x00;
671 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
672 characteristic->permission |= __get_permission_flag(permission);
674 g_variant_iter_free(char_perm_iter);
675 } else if (!g_strcmp0(key, "Descriptors")) {
676 g_variant_get(value, "ao", &char_desc_iter);
677 gp_array = g_ptr_array_new();
678 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
679 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
681 g_variant_iter_free(char_desc_iter);
682 if (gp_array->len != 0) {
683 characteristic->char_desc_handle.count = gp_array->len;
684 characteristic->char_desc_handle.handle =
685 __get_string_array_from_gptr_array(gp_array);
687 g_ptr_array_free(gp_array, TRUE);
691 g_variant_iter_free(property_iter);
692 g_variant_unref(result);
693 g_object_unref(properties_proxy);
695 return BLUETOOTH_ERROR_NONE;
698 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
699 GAsyncResult *res, gpointer user_data)
702 GVariantIter *char_iter;
704 GError *error = NULL;
705 bt_user_info_t *user_info;
706 int ret = BLUETOOTH_ERROR_INTERNAL;
707 bt_gatt_char_property_t characteristic;
709 user_info = _bt_get_user_data(BT_COMMON);
711 value = g_dbus_proxy_call_finish(proxy, res, &error);
715 BT_ERR("Get service characteristics failed\n errCode[%x],"
716 "message[%s]\n", error->code, error->message);
717 g_clear_error(&error);
719 BT_ERR("Get service characteristics failed\n");
722 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
723 BLUETOOTH_ERROR_INTERNAL, NULL,
724 user_info->cb, user_info->user_data);
726 g_object_unref(proxy);
731 g_variant_get(value, "(ao)", &char_iter);
733 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
736 ret = bluetooth_gatt_get_characteristics_property(char_handle,
739 if (ret != BLUETOOTH_ERROR_NONE) {
740 BT_ERR("Get characteristic property failed(0x%08x)", ret);
742 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
743 ret = BLUETOOTH_ERROR_NONE;
747 bluetooth_gatt_free_char_property(&characteristic);
751 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
752 &characteristic, user_info->cb, user_info->user_data);
755 bluetooth_gatt_free_char_property(&characteristic);
756 g_variant_iter_free(char_iter);
757 g_variant_unref(value);
761 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
762 const char *char_uuid)
764 GDBusProxy *properties_proxy = NULL;
765 GDBusConnection *g_conn;
766 GError *error = NULL;
769 BT_CHECK_PARAMETER(service_handle, return);
770 BT_CHECK_PARAMETER(char_uuid, return);
771 BT_CHECK_ENABLED(return);
773 g_conn = _bt_gdbus_get_system_gconn();
774 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
776 properties_proxy = g_dbus_proxy_new_sync(g_conn,
777 G_DBUS_PROXY_FLAGS_NONE, NULL,
780 BT_PROPERTIES_INTERFACE,
783 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
785 uuid = g_strdup(char_uuid);
786 g_dbus_proxy_call(properties_proxy,
788 g_variant_new("(ss)",
789 GATT_SERV_INTERFACE, "Characteristics"),
790 G_DBUS_CALL_FLAGS_NONE,
793 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
796 return BLUETOOTH_ERROR_NONE;
799 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
800 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
802 GDBusProxy *properties_proxy = NULL;
803 GError *error = NULL;
804 GDBusConnection *g_conn;
805 GVariant *result = NULL;
806 GVariantIter *property_iter;
810 GVariant *value = NULL;
811 GByteArray *gb_array = NULL;
812 GVariantIter *desc_value_iter;
814 BT_CHECK_PARAMETER(descriptor_handle, return);
815 BT_CHECK_PARAMETER(descriptor, return);
817 BT_CHECK_ENABLED(return);
819 g_conn = _bt_gdbus_get_system_gconn();
820 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
822 properties_proxy = g_dbus_proxy_new_sync(g_conn,
823 G_DBUS_PROXY_FLAGS_NONE, NULL,
826 BT_PROPERTIES_INTERFACE,
829 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
831 result = g_dbus_proxy_call_sync(properties_proxy,
833 g_variant_new("(s)", GATT_DESC_INTERFACE),
834 G_DBUS_CALL_FLAGS_NONE,
841 BT_ERR("Fail to get properties (Error: %s)", error->message);
842 g_clear_error(&error);
844 BT_ERR("Fail to get properties");
845 g_object_unref(properties_proxy);
846 return BLUETOOTH_ERROR_INTERNAL;
849 g_variant_get(result, "(a{sv})", &property_iter);
851 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
852 descriptor->handle = g_strdup(descriptor_handle);
854 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
855 if (!g_strcmp0(key, "UUID")) {
857 descriptor->uuid = g_variant_dup_string(value, &len);
858 _bt_get_uuid_specification_name(descriptor->uuid, &name);
859 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
861 } else if (!g_strcmp0(key, "Value")) {
862 gb_array = g_byte_array_new();
863 g_variant_get(value, "ay", &desc_value_iter);
864 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
865 BT_DBG("value of descriptor = %d", char_value);
866 g_byte_array_append(gb_array, &char_value, 1);
868 g_variant_iter_free(desc_value_iter);
870 if (gb_array->len != 0) {
871 descriptor->val = g_malloc0(gb_array->len *
872 sizeof(unsigned char));
873 memcpy(descriptor->val, gb_array->data, gb_array->len);
875 descriptor->val_len = gb_array->len;
876 g_byte_array_free(gb_array, TRUE);
880 g_variant_iter_free(property_iter);
881 g_variant_unref(result);
882 g_object_unref(properties_proxy);
884 return BLUETOOTH_ERROR_NONE;
887 static void __bluetooth_internal_read_cb(GObject *source_object,
891 GError *error = NULL;
892 bt_user_info_t *user_info;
893 bt_gatt_char_value_t char_value = { 0, };
894 GDBusConnection *system_gconn = NULL;
896 GByteArray *gp_byte_array = NULL;
899 int ret = BLUETOOTH_ERROR_NONE;
902 user_info = _bt_get_user_data(BT_COMMON);
904 system_gconn = _bt_gdbus_get_system_gconn();
905 value = g_dbus_connection_call_finish(system_gconn, res, &error);
908 BT_ERR("Error : %s \n", error->message);
909 if (g_strrstr(error->message, "Not paired"))
910 ret = BLUETOOTH_ERROR_NOT_PAIRED;
912 ret = BLUETOOTH_ERROR_INTERNAL;
914 g_clear_error(&error);
916 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
918 user_info->cb, user_info->user_data);
924 char_value.char_handle = user_data;
925 gp_byte_array = g_byte_array_new();
926 g_variant_get(value, "(ay)", &iter);
928 while (g_variant_iter_loop(iter, "y", &g_byte))
929 g_byte_array_append(gp_byte_array, &g_byte, 1);
931 if (gp_byte_array->len != 0) {
932 char_value.val_len = gp_byte_array->len;
933 char_value.char_value = gp_byte_array->data;
937 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
938 BLUETOOTH_ERROR_NONE, &char_value,
939 user_info->cb, user_info->user_data);
942 g_free(char_value.char_handle);
943 g_byte_array_free(gp_byte_array, TRUE);
944 g_variant_unref(value);
945 g_variant_iter_free(iter);
950 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *characteristic)
952 GDBusConnection *conn;
955 BT_CHECK_PARAMETER(characteristic, return);
956 BT_CHECK_ENABLED(return);
958 conn = _bt_gdbus_get_system_gconn();
959 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
961 handle = g_strdup(characteristic);
963 g_dbus_connection_call(conn,
969 G_VARIANT_TYPE("(ay)"),
970 G_DBUS_CALL_FLAGS_NONE,
973 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
976 return BLUETOOTH_ERROR_NONE;
979 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
980 const char *char_handle, const guint8 *value, int length)
983 GVariantBuilder *builder;
984 GError *error = NULL;
985 GDBusConnection *conn;
989 BT_CHECK_PARAMETER(char_handle, return);
990 BT_CHECK_PARAMETER(value, return);
991 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
992 BT_CHECK_ENABLED(return);
994 conn = _bt_gdbus_get_system_gconn();
995 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
997 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
999 for (i = 0; i < length; i++)
1000 g_variant_builder_add(builder, "y", value[i]);
1002 val = g_variant_new("(ay)", builder);
1004 g_dbus_connection_call_sync(conn,
1007 GATT_CHAR_INTERFACE,
1011 G_DBUS_CALL_FLAGS_NONE,
1015 BT_ERR("Set value Failed: %s", error->message);
1016 g_clear_error(&error);
1017 g_variant_builder_unref(builder);
1018 return BLUETOOTH_ERROR_INTERNAL;
1021 g_variant_builder_unref(builder);
1024 return BLUETOOTH_ERROR_NONE;
1027 static void __bluetooth_internal_write_cb(GObject *source_object,
1031 GError *error = NULL;
1032 bt_user_info_t *user_info;
1033 GDBusConnection *system_gconn = NULL;
1035 int result = BLUETOOTH_ERROR_NONE;
1036 guint8 att_ecode = 0;
1038 user_info = _bt_get_user_data(BT_COMMON);
1040 system_gconn = _bt_gdbus_get_system_gconn();
1041 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1044 BT_ERR("Error : %s \n", error->message);
1045 g_clear_error(&error);
1046 result = BLUETOOTH_ERROR_INTERNAL;
1048 g_variant_get(value, "(y)", &att_ecode);
1051 BT_ERR("ATT Error code: %d \n", att_ecode);
1056 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1058 user_info->cb, user_info->user_data);
1060 BT_ERR("user info is null");
1064 g_variant_unref(value);
1069 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1070 const char *char_handle, const guint8 *value, int length, guint8 write_type)
1073 GVariantBuilder *builder;
1074 GDBusConnection *conn;
1076 int ret = BLUETOOTH_ERROR_NONE;
1078 BT_CHECK_PARAMETER(char_handle, return);
1079 BT_CHECK_PARAMETER(value, return);
1080 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1081 BT_CHECK_ENABLED_INTERNAL(return);
1083 conn = _bt_gdbus_get_system_gconn();
1084 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1086 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1088 for (i = 0; i < length; i++)
1089 g_variant_builder_add(builder, "y", value[i]);
1091 val = g_variant_new("ay", builder);
1092 g_dbus_connection_call(conn,
1095 GATT_CHAR_INTERFACE,
1097 g_variant_new("(y@ay)", write_type, val),
1098 G_VARIANT_TYPE("(y)"),
1099 G_DBUS_CALL_FLAGS_NONE,
1101 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1104 g_variant_builder_unref(builder);
1108 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1109 const char *char_handle, const guint8 *value, int length)
1112 GDBusConnection *conn;
1113 GVariantBuilder *builder;
1117 BT_CHECK_PARAMETER(char_handle, return);
1118 BT_CHECK_PARAMETER(value, return);
1119 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1120 BT_CHECK_ENABLED(return);
1122 conn = _bt_gdbus_get_system_gconn();
1123 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1125 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1127 for (i = 0; i < length; i++) {
1128 g_variant_builder_add(builder, "y", value[i]);
1129 BT_DBG("value [] = %d", value[i]);
1132 val = g_variant_new("(ay)", builder);
1134 g_dbus_connection_call(conn,
1137 GATT_CHAR_INTERFACE,
1141 G_DBUS_CALL_FLAGS_NONE,
1143 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1146 g_variant_builder_unref(builder);
1149 return BLUETOOTH_ERROR_NONE;
1152 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1153 bt_gatt_char_property_t *characteristic)
1156 GDBusProxy *properties_proxy = NULL;
1157 GError *error = NULL;
1158 GVariant *value = NULL;
1159 GVariant *result = NULL;
1160 GDBusConnection *g_conn;
1161 int i, ret = BLUETOOTH_ERROR_NONE;
1162 const char *uuid = NULL;
1164 GVariantIter *desc_value_iter, *property_iter;
1166 char_descriptor_type_t desc_type = TYPE_NONE;
1168 g_conn = _bt_gdbus_get_system_gconn();
1169 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1171 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1172 G_DBUS_PROXY_FLAGS_NONE, NULL,
1175 BT_PROPERTIES_INTERFACE,
1178 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1180 result = g_dbus_proxy_call_sync(properties_proxy,
1182 g_variant_new("(s)", GATT_DESC_INTERFACE),
1183 G_DBUS_CALL_FLAGS_NONE,
1189 if (error != NULL) {
1190 BT_ERR("Fail to get properties (Error: %s)", error->message);
1191 g_clear_error(&error);
1193 BT_ERR("Fail to get properties");
1194 g_object_unref(properties_proxy);
1195 return BLUETOOTH_ERROR_INTERNAL;
1197 g_variant_get(result, "(a{sv})", &property_iter);
1198 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1199 if (!g_strcmp0(key, "UUID")) {
1200 uuid = g_variant_get_string(value, &len);
1201 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1202 BT_DBG("GATT_USER_DESC_UUID");
1203 desc_type = USER_DESC;
1204 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1205 BT_DBG("GATT_CHAR_FORMAT");
1206 desc_type = CHAR_FORMAT;
1207 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1208 BT_DBG("GATT_CHAR_CLIENT_CONF");
1209 desc_type = CLIENT_CONF;
1210 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1211 BT_DBG("GATT_CHAR_SERVER_CONF");
1212 desc_type = SERVER_CONF;
1214 BT_DBG("descriptor uuid = %s", uuid);
1216 } else if (!g_strcmp0(key, "Value")) {
1217 switch (desc_type) {
1219 BT_DBG("Format descriptor");
1220 g_variant_get(value, "(yyqyq)",
1221 &(characteristic->format.format),
1222 &(characteristic->format.exponent),
1223 &(characteristic->format.unit),
1224 &(characteristic->format.name_space),
1225 &(characteristic->format.description));
1228 BT_DBG("User descriptor");
1229 g_variant_get(value, "ay", &desc_value_iter);
1230 len = g_variant_get_size((GVariant *)desc_value_iter);
1233 characteristic->description = (char *)g_malloc0(len + 1);
1234 if (!characteristic->description) {
1235 ret = BLUETOOTH_ERROR_OUT_OF_MEMORY;
1239 for (i = 0; i < len; i++) {
1240 g_variant_iter_loop(desc_value_iter, "y",
1241 &characteristic->description[i]);
1242 BT_DBG("description = %s", characteristic->description);
1244 g_variant_iter_free(desc_value_iter);
1247 BT_DBG(" CLIENT_CONF");
1250 BT_DBG(" SERVER_CONF");
1259 g_variant_iter_free(property_iter);
1260 g_variant_unref(result);
1261 g_object_unref(properties_proxy);
1268 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1269 GAsyncResult *res, gpointer user_data)
1273 GVariant *char_value;
1274 GVariantIter *char_iter;
1276 GError *error = NULL;
1277 bt_user_info_t *user_info;
1278 bt_gatt_char_property_t characteristic = {0, };
1279 int ret = BLUETOOTH_ERROR_INTERNAL;
1281 user_info = _bt_get_user_data(BT_COMMON);
1283 value = g_dbus_proxy_call_finish(proxy, res, &error);
1285 if (value == NULL) {
1286 if (error != NULL) {
1287 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1288 "message[%s]\n", error->code, error->message);
1289 g_clear_error(&error);
1291 BT_ERR("Get characteristic descriptor failed\n");
1294 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1295 BLUETOOTH_ERROR_INTERNAL, NULL,
1296 user_info->cb, user_info->user_data);
1299 g_object_unref(proxy);
1303 g_variant_get(value, "(v)", &char_value);
1304 g_variant_get(char_value, "ao", &char_iter);
1306 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1307 BT_DBG("object path of descriptor = %s", char_handle);
1309 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1311 BT_DBG("Descriptor read status [%d]", ret);
1315 characteristic.handle = user_data;
1317 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1318 ret, &characteristic, user_info->cb, user_info->user_data);
1320 bluetooth_gatt_free_char_property(&characteristic);
1322 g_variant_iter_free(char_iter);
1323 g_variant_unref(value);
1327 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1328 const char *characteristic_handle)
1330 GDBusProxy *properties_proxy = NULL;
1331 GDBusConnection *g_conn;
1333 GError *error = NULL;
1335 BT_CHECK_PARAMETER(characteristic_handle, return);
1336 BT_CHECK_ENABLED(return);
1338 g_conn = _bt_gdbus_get_system_gconn();
1339 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1341 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1342 G_DBUS_PROXY_FLAGS_NONE, NULL,
1344 characteristic_handle,
1345 BT_PROPERTIES_INTERFACE,
1348 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1350 handle = g_strdup(characteristic_handle);
1351 g_dbus_proxy_call(properties_proxy,
1353 g_variant_new("(ss)",
1354 GATT_CHAR_INTERFACE, "Descriptors"),
1355 G_DBUS_CALL_FLAGS_NONE,
1357 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1360 return BLUETOOTH_ERROR_NONE;
1363 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1367 GError *error = NULL;
1368 bt_user_info_t *user_info;
1369 bt_gatt_char_property_t char_value = { 0, };
1370 GDBusConnection *system_gconn = NULL;
1372 GByteArray *gp_byte_array = NULL;
1377 user_info = _bt_get_user_data(BT_COMMON);
1378 system_gconn = _bt_gdbus_get_system_gconn();
1380 char_value.handle = user_data;
1381 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1384 BT_ERR("Error : %s \n", error->message);
1385 g_clear_error(&error);
1387 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1388 BLUETOOTH_ERROR_INTERNAL, NULL,
1389 user_info->cb, user_info->user_data);
1391 g_free(char_value.handle);
1395 gp_byte_array = g_byte_array_new();
1396 g_variant_get(value, "(ay)", &iter);
1398 while (g_variant_iter_loop(iter, "y", &g_byte))
1399 g_byte_array_append(gp_byte_array, &g_byte, 1);
1401 if (gp_byte_array->len != 0) {
1402 char_value.val_len = (unsigned int)gp_byte_array->len;
1403 char_value.description = (char *)gp_byte_array->data;
1407 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1408 BLUETOOTH_ERROR_NONE, &char_value,
1409 user_info->cb, user_info->user_data);
1412 g_byte_array_free(gp_byte_array, TRUE);
1413 g_free(char_value.handle);
1414 g_variant_unref(value);
1415 g_variant_iter_free(iter);
1420 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descriptor)
1422 GDBusConnection *conn;
1426 BT_CHECK_PARAMETER(char_descriptor, return);
1427 BT_CHECK_ENABLED(return);
1429 conn = _bt_gdbus_get_system_gconn();
1430 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1432 handle = g_strdup(char_descriptor);
1434 g_dbus_connection_call(conn,
1437 GATT_DESC_INTERFACE,
1440 G_VARIANT_TYPE("(ay)"),
1441 G_DBUS_CALL_FLAGS_NONE,
1444 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1448 return BLUETOOTH_ERROR_NONE;
1451 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1455 GError *error = NULL;
1456 bt_user_info_t *user_info;
1457 GDBusConnection *system_gconn = NULL;
1459 int result = BLUETOOTH_ERROR_NONE;
1460 guint8 att_ecode = 0;
1463 user_info = _bt_get_user_data(BT_COMMON);
1465 system_gconn = _bt_gdbus_get_system_gconn();
1466 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1469 BT_ERR("Error : %s \n", error->message);
1470 g_clear_error(&error);
1471 result = BLUETOOTH_ERROR_INTERNAL;
1473 g_variant_get(value, "(y)", &att_ecode);
1476 BT_ERR("ATT Error code: %d \n", att_ecode);
1481 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1483 user_info->cb, user_info->user_data);
1487 g_variant_unref(value);
1492 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
1493 const char *desc_handle, const guint8 *value, int length)
1496 GDBusConnection *conn;
1497 GVariantBuilder *builder;
1501 BT_CHECK_PARAMETER(desc_handle, return);
1502 BT_CHECK_PARAMETER(value, return);
1503 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1504 BT_CHECK_ENABLED(return);
1506 conn = _bt_gdbus_get_system_gconn();
1507 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1509 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1511 for (i = 0; i < length; i++)
1512 g_variant_builder_add(builder, "y", value[i]);
1514 val = g_variant_new("(ay)", builder);
1516 g_dbus_connection_call(conn,
1519 GATT_DESC_INTERFACE,
1522 G_VARIANT_TYPE("(y)"),
1523 G_DBUS_CALL_FLAGS_NONE,
1525 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1528 g_variant_builder_unref(builder);
1531 return BLUETOOTH_ERROR_NONE;
1534 #ifndef GATT_NO_RELAY
1535 static int __bluetooth_gatt_watch_characteristics(void)
1537 int result = BLUETOOTH_ERROR_NONE;
1540 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1542 result = _bt_send_request(BT_BLUEZ_SERVICE,
1543 BT_GATT_WATCH_CHARACTERISTIC,
1544 in_param1, in_param2, in_param3, in_param4, &out_param);
1546 if (result != BLUETOOTH_ERROR_NONE)
1547 BT_ERR("Watch Characteristic request failed !");
1549 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1555 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1557 GDBusConnection *conn;
1558 GError *error = NULL;
1559 int ret = BLUETOOTH_ERROR_NONE;
1561 BT_CHECK_PARAMETER(char_handle, return);
1562 BT_CHECK_ENABLED(return);
1564 BT_INFO_C("### Enable CCCD : %s", char_handle);
1566 conn = _bt_gdbus_get_system_gconn();
1567 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1569 g_dbus_connection_call_sync(conn,
1572 GATT_CHAR_INTERFACE,
1576 G_DBUS_CALL_FLAGS_NONE,
1577 GATT_DEFAULT_TIMEOUT, NULL, &error);
1580 g_dbus_error_strip_remote_error(error);
1581 BT_ERR_C("### Watch Failed: %s", error->message);
1582 if (g_strrstr(error->message, "Already notifying"))
1583 ret = BLUETOOTH_ERROR_NONE;
1584 else if (g_strrstr(error->message, "In Progress"))
1585 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1586 else if (g_strrstr(error->message, "Operation is not supported"))
1587 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1588 /*failed because of either Insufficient Authorization or Write Not Permitted */
1589 else if (g_strrstr(error->message, "Write not permitted") ||
1590 g_strrstr(error->message, "Operation Not Authorized"))
1591 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1592 /* failed because of either Insufficient Authentication,
1593 Insufficient Encryption Key Size, or Insufficient Encryption. */
1594 else if (g_strrstr(error->message, "Not paired"))
1595 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1597 ret = BLUETOOTH_ERROR_INTERNAL;
1599 g_clear_error(&error);
1601 #ifndef GATT_NO_RELAY
1603 /* Register the client sender to bt-service */
1604 ret = __bluetooth_gatt_watch_characteristics();
1611 #ifndef GATT_NO_RELAY
1612 static int __bluetooth_gatt_unwatch_characteristics(void)
1614 int result = BLUETOOTH_ERROR_NONE;
1617 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1619 result = _bt_send_request(BT_BLUEZ_SERVICE,
1620 BT_GATT_UNWATCH_CHARACTERISTIC,
1621 in_param1, in_param2, in_param3, in_param4, &out_param);
1623 if (result != BLUETOOTH_ERROR_NONE)
1624 BT_ERR("Unwatch Characteristic request failed !");
1626 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1632 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1635 GDBusConnection *conn;
1636 GError *error = NULL;
1637 int ret = BLUETOOTH_ERROR_NONE;
1638 BT_CHECK_PARAMETER(char_handle, return);
1640 BT_CHECK_ENABLED(return);
1642 BT_INFO("Disable CCCD : %s", char_handle);
1644 conn = _bt_gdbus_get_system_gconn();
1645 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1647 g_dbus_connection_call_sync(conn,
1650 GATT_CHAR_INTERFACE,
1654 G_DBUS_CALL_FLAGS_NONE,
1655 GATT_DEFAULT_TIMEOUT, NULL, &error);
1658 BT_ERR("Watch Failed: %s", error->message);
1659 g_clear_error(&error);
1660 ret = BLUETOOTH_ERROR_INTERNAL;
1662 #ifndef GATT_NO_RELAY
1664 /* Unregister the client sender to bt-service */
1665 ret = __bluetooth_gatt_unwatch_characteristics();