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)
47 BT_CHECK_PARAMETER(svc_pty, return);
49 g_free(svc_pty->uuid);
50 g_free(svc_pty->handle);
51 g_strfreev(svc_pty->include_handles.handle);
52 g_strfreev(svc_pty->char_handle.handle);
54 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
57 return BLUETOOTH_ERROR_NONE;
60 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
64 BT_CHECK_PARAMETER(char_pty, return);
66 g_free(char_pty->uuid);
67 g_free(char_pty->name);
68 g_free(char_pty->description);
69 g_free(char_pty->val);
70 g_free(char_pty->handle);
71 g_strfreev(char_pty->char_desc_handle.handle);
73 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
76 return BLUETOOTH_ERROR_NONE;
79 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
83 BT_CHECK_PARAMETER(desc_pty, return);
85 g_free(desc_pty->uuid);
86 g_free(desc_pty->val);
87 g_free(desc_pty->handle);
89 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
92 return BLUETOOTH_ERROR_NONE;
95 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
97 gchar *gp_path = NULL;
104 path = g_malloc0((gp->len + 1) * sizeof(char *));
106 /* Fix : NULL_RETURNS */
110 for (i = 0; i < gp->len; i++) {
111 gp_path = g_ptr_array_index(gp, i);
112 path[i] = g_strdup(gp_path);
113 BT_DBG("path[%d] : [%s]", i, path[i]);
119 gboolean _bluetooth_gatt_check_service_change_watcher_address(
120 const bluetooth_device_address_t *device_addr)
123 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
124 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
126 _bt_convert_addr_type_to_string(device_address,
127 (unsigned char *)device_addr->addr);
129 for (l = service_monitor_list; l != NULL; l = l->next) {
130 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
131 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
132 bluetooth_device_address_t *addr = l->data;
134 _bt_convert_addr_type_to_string(device_address2,
135 (unsigned char *)addr->addr);
136 _bt_convert_addr_string_to_secure_string(secure_address,
138 _bt_convert_addr_string_to_secure_string(secure_address2,
140 BT_INFO("service_monitor_list [%s] - Input [%s]",
141 secure_address2, secure_address);
143 if (!memcmp(device_addr, addr,
144 sizeof(bluetooth_device_address_t)))
151 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
152 const bluetooth_device_address_t *address, gboolean enable)
155 bluetooth_device_address_t *addr = NULL;
156 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
157 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
159 _bt_convert_addr_type_to_string(device_address,
160 (unsigned char *)address->addr);
161 _bt_convert_addr_string_to_secure_string(secure_address,
163 BT_INFO("Set watcher for %s with %d", secure_address, enable);
165 if (enable == TRUE) {
166 if (service_monitor_list == NULL) {
167 _bt_register_manager_subscribe_signal(TRUE);
170 if (_bluetooth_gatt_check_service_change_watcher_address(address)
172 BT_INFO("The watcher is already set");
173 return BLUETOOTH_ERROR_NONE;
175 addr = g_malloc0(sizeof(bluetooth_device_address_t));
176 memcpy(addr, address, sizeof(bluetooth_device_address_t));
178 if (service_monitor_list == NULL) {
179 BT_ERR("There is NO watcher");
180 return BLUETOOTH_ERROR_NONE;
183 service_monitor_list =
184 g_slist_append(service_monitor_list, addr);
186 if (service_monitor_list == NULL) {
187 BT_ERR("There is NO watcher");
188 return BLUETOOTH_ERROR_NONE;
191 for (l = service_monitor_list; l != NULL; l = l->next) {
193 if (!memcmp(address, addr,
194 sizeof(bluetooth_device_address_t))) {
195 service_monitor_list =
196 g_slist_remove(service_monitor_list, addr);
202 if (service_monitor_list == NULL) {
203 _bt_register_manager_subscribe_signal(FALSE);
207 return BLUETOOTH_ERROR_NONE;
210 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
211 bt_gatt_service_property_t *service)
213 GDBusProxy *properties_proxy = NULL;
214 GError *error = NULL;
215 GVariant *result = NULL;
216 GDBusConnection *g_conn;
218 char *char_handle = NULL;
219 GPtrArray *gp_array = NULL ;
220 GVariantIter *property_iter, *char_iter = NULL;
224 BT_CHECK_PARAMETER(service_handle, return);
225 BT_CHECK_PARAMETER(service, return);
226 BT_CHECK_ENABLED(return);
228 g_conn = _bt_gdbus_get_system_gconn();
229 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
231 properties_proxy = g_dbus_proxy_new_sync(g_conn,
232 G_DBUS_PROXY_FLAGS_NONE, NULL,
235 BT_PROPERTIES_INTERFACE,
238 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
240 result = g_dbus_proxy_call_sync(properties_proxy,
242 g_variant_new("(s)", GATT_SERV_INTERFACE),
243 G_DBUS_CALL_FLAGS_NONE,
250 BT_ERR("Fail to get properties (Error: %s)", error->message);
251 g_clear_error(&error);
253 BT_ERR("Fail to get properties");
254 g_object_unref(properties_proxy);
255 return BLUETOOTH_ERROR_INTERNAL;
258 g_variant_get(result, "(a{sv})", &property_iter);
260 memset(service, 0, sizeof(bt_gatt_service_property_t));
262 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
263 if (!g_strcmp0(key, "UUID")) {
265 service->uuid = g_variant_dup_string(value, &len);
266 _bt_get_uuid_specification_name(service->uuid, &name);
267 BT_INFO("======> Service : %s [%s]", service->uuid, name);
269 } else if (!g_strcmp0(key, "Primary")) {
270 service->primary = g_variant_get_boolean(value);
272 } else if (!g_strcmp0(key, "Includes")) {
273 g_variant_get(value, "ao", &char_iter);
274 gp_array = g_ptr_array_new();
275 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
276 g_ptr_array_add(gp_array, (gpointer)char_handle);
278 if (gp_array->len != 0) {
279 service->include_handles.count = gp_array->len;
280 service->include_handles.handle =
281 __get_string_array_from_gptr_array(gp_array);
283 g_ptr_array_free(gp_array, TRUE);
284 g_variant_iter_free(char_iter);
285 } else if (!g_strcmp0(key, "Characteristics")) {
286 g_variant_get(value, "ao", &char_iter);
287 gp_array = g_ptr_array_new();
288 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
289 g_ptr_array_add(gp_array, (gpointer)char_handle);
291 if (gp_array->len != 0) {
292 service->char_handle.count = gp_array->len;
293 service->char_handle.handle =
294 __get_string_array_from_gptr_array(gp_array);
296 BT_DBG("Characteristics count : %d", service->char_handle.count);
297 g_ptr_array_free(gp_array, TRUE);
298 g_variant_iter_free(char_iter);
302 service->handle = g_strdup(service_handle);
304 g_variant_iter_free(property_iter);
305 g_variant_unref(result);
306 g_object_unref(properties_proxy);
308 return BLUETOOTH_ERROR_NONE;
311 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
312 const bluetooth_device_address_t *address,
313 bt_gatt_handle_info_t *prim_svc)
315 GVariant *result = NULL;
317 GVariantIter *svc_iter;
318 GVariantIter *interface_iter;
319 char *object_path = NULL;
320 char *interface_str = NULL;
321 const gchar *key = NULL;
322 GVariant *value = NULL;
323 GPtrArray *gp_array = NULL;
324 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
325 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
326 int ret = BLUETOOTH_ERROR_INTERNAL;
329 BT_CHECK_PARAMETER(address, return);
330 BT_CHECK_PARAMETER(prim_svc, return);
331 BT_CHECK_ENABLED(return);
333 result = _bt_get_managed_objects();
337 _bt_convert_addr_type_to_string(device_address,
338 (unsigned char *)address->addr);
340 gp_array = g_ptr_array_new();
341 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
343 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
345 if (object_path == NULL)
348 _bt_convert_device_path_to_address(object_path, temp_address);
350 if (g_strcmp0(temp_address, device_address) != 0)
353 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
354 &interface_str, &svc_iter)) {
355 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
358 BT_DBG("Object Path: %s", object_path);
359 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
360 if (g_strcmp0(key, "Primary") == 0) {
361 if (g_variant_get_boolean(value))
362 g_ptr_array_add(gp_array, (gpointer)object_path);
368 if (gp_array->len == 0) {
369 BT_ERR("gp_array is NULL");
370 ret = BLUETOOTH_ERROR_NOT_FOUND;
372 ret = BLUETOOTH_ERROR_NONE;
373 prim_svc->count = gp_array->len;
374 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
377 g_ptr_array_free(gp_array, TRUE);
378 g_variant_iter_free(iter);
379 g_variant_unref(result);
384 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
385 const char *service_uuid,
386 bt_gatt_service_property_t *service)
388 GVariant *result = NULL;
390 GVariantIter *svc_iter;
391 GVariantIter *interface_iter;
392 char *object_path = NULL;
393 char *interface_str = NULL;
394 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
395 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
396 int ret = BLUETOOTH_ERROR_INTERNAL;
398 BT_CHECK_PARAMETER(address, return);
399 BT_CHECK_PARAMETER(service_uuid, return);
400 BT_CHECK_PARAMETER(service, return);
401 BT_CHECK_ENABLED(return);
403 result = _bt_get_managed_objects();
407 _bt_convert_addr_type_to_string(device_address,
408 (unsigned char *)address->addr);
410 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
412 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
414 if (object_path == NULL)
417 _bt_convert_device_path_to_address(object_path,
420 if (g_strcmp0(temp_address, device_address) != 0)
423 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
424 &interface_str, &svc_iter)) {
425 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
428 BT_DBG("Object Path: %s", object_path);
429 ret = bluetooth_gatt_get_service_property(object_path,
432 if (ret != BLUETOOTH_ERROR_NONE) {
433 BT_ERR("Get service property failed(0x%08x)", ret);
435 if (service->primary == TRUE &&
436 g_strstr_len(service->uuid, -1,
438 ret = BLUETOOTH_ERROR_NONE;
442 bluetooth_gatt_free_service_property(service);
447 g_variant_iter_free(iter);
448 g_variant_unref(result);
453 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
454 GAsyncResult *res, gpointer user_data)
457 GVariant *char_value;
458 GVariantIter *char_iter;
459 GPtrArray *gp_array = NULL;
460 bt_gatt_discovered_char_t svc_char = { 0, };
462 GError *error = NULL;
463 bt_user_info_t *user_info;
467 user_info = _bt_get_user_data(BT_COMMON);
468 svc_char.service_handle = user_data;
470 value = g_dbus_proxy_call_finish(proxy, res, &error);
474 BT_ERR("Get service characteristics failed\n errCode[%x],"
475 "message[%s]\n", error->code, error->message);
476 g_clear_error(&error);
478 BT_ERR("Get service characteristics failed\n");
481 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
482 BLUETOOTH_ERROR_INTERNAL, NULL,
483 user_info->cb, user_info->user_data);
485 g_free(svc_char.service_handle);
486 g_object_unref(proxy);
490 g_variant_get(value, "(v)", &char_value);
491 g_variant_get(char_value, "ao", &char_iter);
493 gp_array = g_ptr_array_new();
494 while (g_variant_iter_loop(char_iter, "&o", &char_handle));
495 g_ptr_array_add(gp_array, (gpointer)char_handle);
497 if (gp_array->len != 0) {
498 svc_char.handle_info.count = gp_array->len;
499 svc_char.handle_info.handle =
500 __get_string_array_from_gptr_array(gp_array);
502 g_ptr_array_free(gp_array, TRUE);
505 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
506 BLUETOOTH_ERROR_NONE, &svc_char,
507 user_info->cb, user_info->user_data);
510 g_strfreev(svc_char.handle_info.handle);
511 g_free(svc_char.service_handle);
512 g_variant_iter_free(char_iter);
513 g_variant_unref(value);
514 g_object_unref(proxy);
517 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
518 const char *service_handle)
520 GDBusProxy *properties_proxy = NULL;
521 GDBusConnection *g_conn;
522 GError *error = NULL;
527 BT_CHECK_PARAMETER(service_handle, return);
528 BT_CHECK_ENABLED(return);
530 g_conn = _bt_gdbus_get_system_gconn();
531 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
533 properties_proxy = g_dbus_proxy_new_sync(g_conn,
534 G_DBUS_PROXY_FLAGS_NONE, NULL,
537 BT_PROPERTIES_INTERFACE,
540 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
542 handle = g_strdup(service_handle);
543 g_dbus_proxy_call(properties_proxy,
545 g_variant_new("(ss)",
546 GATT_SERV_INTERFACE, "Characteristics"),
547 G_DBUS_CALL_FLAGS_NONE,
550 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
554 return BLUETOOTH_ERROR_NONE;
558 static int __get_permission_flag(char *permission)
562 retv_if(permission == NULL, ret);
564 BT_INFO("permission = %s", permission);
566 if (!g_strcmp0(permission, "broadcast")) {
567 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
568 } else if (!g_strcmp0(permission, "read")) {
569 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
570 } else if (!g_strcmp0(permission, "write-without-response")) {
571 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
572 } else if (!g_strcmp0(permission, "write")) {
573 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
574 } else if (!g_strcmp0(permission, "notify")) {
575 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
576 } else if (!g_strcmp0(permission, "indicate")) {
577 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
578 } else if (!g_strcmp0(permission, "authenticated-signed-writes")) {
579 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
580 } else if (!g_strcmp0(permission, "reliable-write")) {
581 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
582 } else if (!g_strcmp0(permission, "writable-auxiliaries")) {
583 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
584 } else if (!g_strcmp0(permission, "encrypt-read")) {
585 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
586 } else if (!g_strcmp0(permission, "encrypt-write")) {
587 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
588 } else if (!g_strcmp0(permission, "encrypt-authenticated-read")) {
589 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
590 } else if (!g_strcmp0(permission, "encrypt-authenticated-write")) {
591 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
597 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
598 const char *char_handle, bt_gatt_char_property_t *characteristic)
600 GDBusProxy *properties_proxy = NULL;
601 GError *error = NULL;
602 GVariant *value = NULL;
603 GVariant *result = NULL;
604 GByteArray *gb_array = NULL;
605 GPtrArray *gp_array = NULL ;
606 GDBusConnection *g_conn;
610 char *char_desc_handle = NULL;
612 GVariantIter *property_iter;
613 GVariantIter *char_value_iter;
614 GVariantIter *char_perm_iter;
615 GVariantIter *char_desc_iter;
618 BT_CHECK_PARAMETER(char_handle, return);
619 BT_CHECK_PARAMETER(characteristic, return);
621 BT_CHECK_ENABLED(return);
623 g_conn = _bt_gdbus_get_system_gconn();
624 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
626 properties_proxy = g_dbus_proxy_new_sync(g_conn,
627 G_DBUS_PROXY_FLAGS_NONE, NULL,
630 BT_PROPERTIES_INTERFACE,
633 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
635 result = g_dbus_proxy_call_sync(properties_proxy,
637 g_variant_new("(s)", GATT_CHAR_INTERFACE),
638 G_DBUS_CALL_FLAGS_NONE,
645 BT_ERR("Fail to get properties (Error: %s)", error->message);
646 g_clear_error(&error);
648 BT_ERR("Fail to get properties");
649 g_object_unref(properties_proxy);
650 return BLUETOOTH_ERROR_INTERNAL;
653 g_variant_get(result, "(a{sv})", &property_iter);
655 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
656 characteristic->handle = g_strdup(char_handle);
658 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
659 if (!g_strcmp0(key, "UUID")) {
661 characteristic->uuid = g_variant_dup_string(value, &len);
662 _bt_get_uuid_specification_name(characteristic->uuid, &name);
663 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
665 } else if (!g_strcmp0(key, "Value")) {
666 gb_array = g_byte_array_new();
667 g_variant_get(value, "ay", &char_value_iter);
668 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
669 // BT_DBG("value of char = %d",char_value);
670 g_byte_array_append(gb_array, &char_value, 1);
672 g_variant_iter_free(char_value_iter);
674 if (gb_array->len != 0) {
675 characteristic->val = g_malloc0(gb_array->len *
676 sizeof(unsigned char));
677 memcpy(characteristic->val, gb_array->data, gb_array->len);
679 characteristic->val_len = gb_array->len;
680 g_byte_array_free(gb_array, TRUE);
681 } else if (!g_strcmp0(key, "Flags")) {
682 g_variant_get(value, "as", &char_perm_iter);
683 characteristic->permission = 0x00;
684 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
685 BT_DBG("permission = %s", permission);
686 characteristic->permission |= __get_permission_flag(permission);
687 BT_DBG("permission check = %d", characteristic->permission);
689 g_variant_iter_free(char_perm_iter);
690 } else if (!g_strcmp0(key, "Descriptors")) {
691 g_variant_get(value, "ao", &char_desc_iter);
692 gp_array = g_ptr_array_new();
693 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle)) {
694 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
696 g_variant_iter_free(char_desc_iter);
697 if (gp_array->len != 0) {
698 characteristic->char_desc_handle.count = gp_array->len;
699 characteristic->char_desc_handle.handle =
700 __get_string_array_from_gptr_array(gp_array);
702 g_ptr_array_free(gp_array, TRUE);
706 g_variant_iter_free(property_iter);
707 g_variant_unref(result);
708 g_object_unref(properties_proxy);
711 return BLUETOOTH_ERROR_NONE;
714 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
715 GAsyncResult *res, gpointer user_data)
718 GVariantIter *char_iter;
720 GError *error = NULL;
721 bt_user_info_t *user_info;
722 int ret = BLUETOOTH_ERROR_INTERNAL;
723 bt_gatt_char_property_t characteristic;
725 user_info = _bt_get_user_data(BT_COMMON);
727 value = g_dbus_proxy_call_finish(proxy, res, &error);
731 BT_ERR("Get service characteristics failed\n errCode[%x],"
732 "message[%s]\n", error->code, error->message);
733 g_clear_error(&error);
735 BT_ERR("Get service characteristics failed\n");
738 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
739 BLUETOOTH_ERROR_INTERNAL, NULL,
740 user_info->cb, user_info->user_data);
742 g_object_unref(proxy);
747 g_variant_get(value, "(ao)", &char_iter);
749 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
752 ret = bluetooth_gatt_get_characteristics_property(char_handle,
755 if (ret != BLUETOOTH_ERROR_NONE) {
756 BT_ERR("Get characteristic property failed(0x%08x)", ret);
758 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
759 ret = BLUETOOTH_ERROR_NONE;
763 bluetooth_gatt_free_char_property(&characteristic);
767 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
768 &characteristic, user_info->cb, user_info->user_data);
771 bluetooth_gatt_free_char_property(&characteristic);
772 g_variant_iter_free(char_iter);
773 g_variant_unref(value);
777 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
778 const char *char_uuid)
780 GDBusProxy *properties_proxy = NULL;
781 GDBusConnection *g_conn;
782 GError *error = NULL;
785 BT_CHECK_PARAMETER(service_handle, return);
786 BT_CHECK_PARAMETER(char_uuid, return);
787 BT_CHECK_ENABLED(return);
789 g_conn = _bt_gdbus_get_system_gconn();
790 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
792 properties_proxy = g_dbus_proxy_new_sync(g_conn,
793 G_DBUS_PROXY_FLAGS_NONE, NULL,
796 BT_PROPERTIES_INTERFACE,
799 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
801 uuid = g_strdup(char_uuid);
802 g_dbus_proxy_call(properties_proxy,
804 g_variant_new("(ss)",
805 GATT_SERV_INTERFACE, "Characteristics"),
806 G_DBUS_CALL_FLAGS_NONE,
809 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
812 return BLUETOOTH_ERROR_NONE;
815 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
816 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
818 GDBusProxy *properties_proxy = NULL;
819 GError *error = NULL;
820 GDBusConnection *g_conn;
821 GVariant *result = NULL;
822 GVariantIter *property_iter;
826 GVariant *value = NULL;
827 GByteArray *gb_array = NULL;
828 GVariantIter *desc_value_iter;
831 BT_CHECK_PARAMETER(descriptor_handle, return);
832 BT_CHECK_PARAMETER(descriptor, return);
834 BT_CHECK_ENABLED(return);
836 g_conn = _bt_gdbus_get_system_gconn();
837 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
839 properties_proxy = g_dbus_proxy_new_sync(g_conn,
840 G_DBUS_PROXY_FLAGS_NONE, NULL,
843 BT_PROPERTIES_INTERFACE,
846 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
848 result = g_dbus_proxy_call_sync(properties_proxy,
850 g_variant_new("(s)", GATT_DESC_INTERFACE),
851 G_DBUS_CALL_FLAGS_NONE,
858 BT_ERR("Fail to get properties (Error: %s)", error->message);
859 g_clear_error(&error);
861 BT_ERR("Fail to get properties");
862 g_object_unref(properties_proxy);
863 return BLUETOOTH_ERROR_INTERNAL;
866 g_variant_get(result, "(a{sv})", &property_iter);
868 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
869 descriptor->handle = g_strdup(descriptor_handle);
871 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
872 if (!g_strcmp0(key, "UUID")) {
874 descriptor->uuid = g_variant_dup_string(value, &len);
875 _bt_get_uuid_specification_name(descriptor->uuid, &name);
876 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
878 } else if (!g_strcmp0(key, "Value")) {
879 gb_array = g_byte_array_new();
880 g_variant_get(value, "ay", &desc_value_iter);
881 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
882 BT_DBG("value of descriptor = %d", char_value);
883 g_byte_array_append(gb_array, &char_value, 1);
885 g_variant_iter_free(desc_value_iter);
887 if (gb_array->len != 0) {
888 descriptor->val = g_malloc0(gb_array->len *
889 sizeof(unsigned char));
890 memcpy(descriptor->val, gb_array->data, gb_array->len);
892 descriptor->val_len = gb_array->len;
893 g_byte_array_free(gb_array, TRUE);
897 g_variant_iter_free(property_iter);
898 g_variant_unref(result);
899 g_object_unref(properties_proxy);
902 return BLUETOOTH_ERROR_NONE;
905 static void __bluetooth_internal_read_cb(GObject *source_object,
909 GError *error = NULL;
910 bt_user_info_t *user_info;
911 bt_gatt_char_value_t char_value = { 0, };
912 GDBusConnection *system_gconn = NULL;
914 GByteArray *gp_byte_array = NULL;
917 int ret = BLUETOOTH_ERROR_NONE;
920 user_info = _bt_get_user_data(BT_COMMON);
922 system_gconn = _bt_gdbus_get_system_gconn();
923 value = g_dbus_connection_call_finish(system_gconn, res, &error);
926 BT_ERR("Error : %s \n", error->message);
927 if (g_strrstr(error->message, "Not paired"))
928 ret = BLUETOOTH_ERROR_NOT_PAIRED;
930 ret = BLUETOOTH_ERROR_INTERNAL;
932 g_clear_error(&error);
934 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
936 user_info->cb, user_info->user_data);
942 char_value.char_handle = user_data;
943 gp_byte_array = g_byte_array_new();
944 g_variant_get(value, "(ay)", &iter);
946 while (g_variant_iter_loop(iter, "y", &g_byte)) {
947 g_byte_array_append(gp_byte_array, &g_byte, 1);
950 if (gp_byte_array->len != 0) {
951 char_value.val_len = gp_byte_array->len;
952 char_value.char_value = gp_byte_array->data;
956 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
957 BLUETOOTH_ERROR_NONE, &char_value,
958 user_info->cb, user_info->user_data);
961 g_free(char_value.char_handle);
962 g_byte_array_free(gp_byte_array, TRUE);
963 g_variant_unref(value);
964 g_variant_iter_free(iter);
969 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *characteristic)
971 GDBusConnection *conn;
974 BT_CHECK_PARAMETER(characteristic, return);
975 BT_CHECK_ENABLED(return);
977 conn = _bt_gdbus_get_system_gconn();
978 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
980 handle = g_strdup(characteristic);
982 g_dbus_connection_call(conn,
988 G_VARIANT_TYPE("(ay)"),
989 G_DBUS_CALL_FLAGS_NONE,
992 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
995 return BLUETOOTH_ERROR_NONE;
998 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
999 const char *char_handle, const guint8 *value, int length)
1002 GVariantBuilder *builder;
1003 GError *error = NULL;
1004 GDBusConnection *conn;
1008 BT_CHECK_PARAMETER(char_handle, return);
1009 BT_CHECK_PARAMETER(value, return);
1010 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1011 BT_CHECK_ENABLED(return);
1013 conn = _bt_gdbus_get_system_gconn();
1014 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1016 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1018 for (i = 0; i < length; i++) {
1019 g_variant_builder_add(builder, "y", value[i]);
1022 val = g_variant_new("(ay)", builder);
1024 g_dbus_connection_call_sync(conn,
1027 GATT_CHAR_INTERFACE,
1031 G_DBUS_CALL_FLAGS_NONE,
1035 BT_ERR("Set value Failed: %s", error->message);
1036 g_clear_error(&error);
1037 g_variant_builder_unref(builder);
1038 return BLUETOOTH_ERROR_INTERNAL;
1041 g_variant_builder_unref(builder);
1044 return BLUETOOTH_ERROR_NONE;
1047 static void __bluetooth_internal_write_cb(GObject *source_object,
1052 GError *error = NULL;
1053 bt_user_info_t *user_info;
1054 GDBusConnection *system_gconn = NULL;
1056 int result = BLUETOOTH_ERROR_NONE;
1057 guint8 att_ecode = 0;
1059 user_info = _bt_get_user_data(BT_COMMON);
1061 system_gconn = _bt_gdbus_get_system_gconn();
1062 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1065 BT_ERR("Error : %s \n", error->message);
1066 g_clear_error(&error);
1067 result = BLUETOOTH_ERROR_INTERNAL;
1069 g_variant_get(value, "(y)", &att_ecode);
1072 BT_ERR("ATT Error code: %d \n", att_ecode);
1077 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1079 user_info->cb, user_info->user_data);
1081 BT_ERR("user info is null");
1085 g_variant_unref(value);
1090 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1091 const char *char_handle, const guint8 *value, int length, guint8 write_type)
1094 GVariantBuilder *builder;
1095 GDBusConnection *conn;
1097 int ret = BLUETOOTH_ERROR_NONE;
1099 BT_CHECK_PARAMETER(char_handle, return);
1100 BT_CHECK_PARAMETER(value, return);
1101 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1102 BT_CHECK_ENABLED_INTERNAL(return);
1104 conn = _bt_gdbus_get_system_gconn();
1105 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1107 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1109 for (i = 0; i < length; i++) {
1110 g_variant_builder_add(builder, "y", value[i]);
1113 val = g_variant_new("ay", builder);
1114 g_dbus_connection_call(conn,
1117 GATT_CHAR_INTERFACE,
1119 g_variant_new("(y@ay)", write_type, val),
1120 G_VARIANT_TYPE("(y)"),
1121 G_DBUS_CALL_FLAGS_NONE,
1123 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1126 g_variant_builder_unref(builder);
1130 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1131 const char *char_handle, const guint8 *value, int length)
1134 GDBusConnection *conn;
1135 GVariantBuilder *builder;
1139 BT_CHECK_PARAMETER(char_handle, return);
1140 BT_CHECK_PARAMETER(value, return);
1141 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1142 BT_CHECK_ENABLED(return);
1144 conn = _bt_gdbus_get_system_gconn();
1145 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1147 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1149 for (i = 0; i < length; i++) {
1150 g_variant_builder_add(builder, "y", value[i]);
1151 BT_DBG("value [] = %d", value[i]);
1154 val = g_variant_new("(ay)", builder);
1156 g_dbus_connection_call(conn,
1159 GATT_CHAR_INTERFACE,
1163 G_DBUS_CALL_FLAGS_NONE,
1165 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1168 g_variant_builder_unref(builder);
1171 return BLUETOOTH_ERROR_NONE;
1174 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1175 bt_gatt_char_property_t *characteristic)
1178 GDBusProxy *properties_proxy = NULL;
1179 GError *error = NULL;
1180 GVariant *value = NULL;
1181 GVariant *result = NULL;
1182 GDBusConnection *g_conn;
1183 int i, ret = BLUETOOTH_ERROR_NONE;
1184 const char *uuid = NULL;
1186 GVariantIter *desc_value_iter, *property_iter;
1188 char_descriptor_type_t desc_type = TYPE_NONE;
1190 g_conn = _bt_gdbus_get_system_gconn();
1191 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1193 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1194 G_DBUS_PROXY_FLAGS_NONE, NULL,
1197 BT_PROPERTIES_INTERFACE,
1200 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1202 result = g_dbus_proxy_call_sync(properties_proxy,
1204 g_variant_new("(s)", GATT_DESC_INTERFACE),
1205 G_DBUS_CALL_FLAGS_NONE,
1211 if (error != NULL) {
1212 BT_ERR("Fail to get properties (Error: %s)", error->message);
1213 g_clear_error(&error);
1215 BT_ERR("Fail to get properties");
1216 g_object_unref(properties_proxy);
1217 return BLUETOOTH_ERROR_INTERNAL;
1219 g_variant_get(result, "(a{sv})", &property_iter);
1220 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1221 if (!g_strcmp0(key, "UUID")) {
1222 uuid = g_variant_get_string(value, &len);
1223 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1224 BT_DBG("GATT_USER_DESC_UUID");
1225 desc_type = USER_DESC;
1226 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1227 BT_DBG("GATT_CHAR_FORMAT");
1228 desc_type = CHAR_FORMAT;
1229 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1230 BT_DBG("GATT_CHAR_CLIENT_CONF");
1231 desc_type = CLIENT_CONF;
1232 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1233 BT_DBG("GATT_CHAR_SERVER_CONF");
1234 desc_type = SERVER_CONF;
1236 BT_DBG("descriptor uuid = %s", uuid);
1238 } else if (!g_strcmp0(key, "Value")) {
1239 switch (desc_type) {
1241 BT_DBG("Format descriptor");
1242 g_variant_get(value, "(yyqyq)",
1243 &(characteristic->format.format),
1244 &(characteristic->format.exponent),
1245 &(characteristic->format.unit),
1246 &(characteristic->format.name_space),
1247 &(characteristic->format.description));
1250 BT_DBG("User descriptor");
1251 g_variant_get(value, "ay", &desc_value_iter);
1252 len = g_variant_get_size((GVariant *)desc_value_iter);
1255 characteristic->description = (char *)g_malloc0(len + 1);
1256 if (!characteristic->description) {
1257 ret = BLUETOOTH_ERROR_OUT_OF_MEMORY;
1261 for (i = 0; i < len; i++) {
1262 g_variant_iter_loop(desc_value_iter, "y",
1263 &characteristic->description[i]);
1264 BT_DBG("description = %s", characteristic->description);
1266 g_variant_iter_free(desc_value_iter);
1269 BT_DBG(" CLIENT_CONF");
1272 BT_DBG(" SERVER_CONF");
1281 g_variant_iter_free(property_iter);
1282 g_variant_unref(result);
1283 g_object_unref(properties_proxy);
1290 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1291 GAsyncResult *res, gpointer user_data)
1295 GVariant *char_value;
1296 GVariantIter *char_iter;
1298 GError *error = NULL;
1299 bt_user_info_t *user_info;
1300 bt_gatt_char_property_t characteristic = {0, };
1301 int ret = BLUETOOTH_ERROR_INTERNAL;
1303 user_info = _bt_get_user_data(BT_COMMON);
1305 value = g_dbus_proxy_call_finish(proxy, res, &error);
1307 if (value == NULL) {
1308 if (error != NULL) {
1309 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1310 "message[%s]\n", error->code, error->message);
1311 g_clear_error(&error);
1313 BT_ERR("Get characteristic descriptor failed\n");
1316 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1317 BLUETOOTH_ERROR_INTERNAL, NULL,
1318 user_info->cb, user_info->user_data);
1321 g_object_unref(proxy);
1325 g_variant_get(value, "(v)", &char_value);
1326 g_variant_get(char_value, "ao", &char_iter);
1328 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1329 BT_DBG("object path of descriptor = %s", char_handle);
1331 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1333 BT_DBG("Descriptor read status [%d]", ret);
1337 characteristic.handle = user_data;
1339 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1340 ret, &characteristic, user_info->cb, user_info->user_data);
1342 bluetooth_gatt_free_char_property(&characteristic);
1344 g_variant_iter_free(char_iter);
1345 g_variant_unref(value);
1349 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1350 const char *characteristic_handle)
1352 GDBusProxy *properties_proxy = NULL;
1353 GDBusConnection *g_conn;
1355 GError *error = NULL;
1357 BT_CHECK_PARAMETER(characteristic_handle, return);
1358 BT_CHECK_ENABLED(return);
1360 g_conn = _bt_gdbus_get_system_gconn();
1361 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1363 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1364 G_DBUS_PROXY_FLAGS_NONE, NULL,
1366 characteristic_handle,
1367 BT_PROPERTIES_INTERFACE,
1370 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1372 handle = g_strdup(characteristic_handle);
1373 g_dbus_proxy_call(properties_proxy,
1375 g_variant_new("(ss)",
1376 GATT_CHAR_INTERFACE, "Descriptors"),
1377 G_DBUS_CALL_FLAGS_NONE,
1379 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1382 return BLUETOOTH_ERROR_NONE;
1385 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1389 GError *error = NULL;
1390 bt_user_info_t *user_info;
1391 bt_gatt_char_property_t char_value = { 0, };
1392 GDBusConnection *system_gconn = NULL;
1394 GByteArray *gp_byte_array = NULL;
1399 user_info = _bt_get_user_data(BT_COMMON);
1400 system_gconn = _bt_gdbus_get_system_gconn();
1402 char_value.handle = user_data;
1403 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1406 BT_ERR("Error : %s \n", error->message);
1407 g_clear_error(&error);
1409 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1410 BLUETOOTH_ERROR_INTERNAL, NULL,
1411 user_info->cb, user_info->user_data);
1413 g_free(char_value.handle);
1417 gp_byte_array = g_byte_array_new();
1418 g_variant_get(value, "(ay)", &iter);
1420 while (g_variant_iter_loop(iter, "y", &g_byte))
1421 g_byte_array_append(gp_byte_array, &g_byte, 1);
1423 if (gp_byte_array->len != 0) {
1424 char_value.val_len = (unsigned int)gp_byte_array->len;
1425 char_value.description = (char *)gp_byte_array->data;
1429 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1430 BLUETOOTH_ERROR_NONE, &char_value,
1431 user_info->cb, user_info->user_data);
1434 g_byte_array_free(gp_byte_array, TRUE);
1435 g_free(char_value.handle);
1436 g_variant_unref(value);
1437 g_variant_iter_free(iter);
1442 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descriptor)
1444 GDBusConnection *conn;
1448 BT_CHECK_PARAMETER(char_descriptor, return);
1449 BT_CHECK_ENABLED(return);
1451 conn = _bt_gdbus_get_system_gconn();
1452 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1454 handle = g_strdup(char_descriptor);
1456 g_dbus_connection_call(conn,
1459 GATT_DESC_INTERFACE,
1462 G_VARIANT_TYPE("(ay)"),
1463 G_DBUS_CALL_FLAGS_NONE,
1466 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1470 return BLUETOOTH_ERROR_NONE;
1473 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1477 GError *error = NULL;
1478 bt_user_info_t *user_info;
1479 GDBusConnection *system_gconn = NULL;
1481 int result = BLUETOOTH_ERROR_NONE;
1482 guint8 att_ecode = 0;
1485 user_info = _bt_get_user_data(BT_COMMON);
1487 system_gconn = _bt_gdbus_get_system_gconn();
1488 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1491 BT_ERR("Error : %s \n", error->message);
1492 g_clear_error(&error);
1493 result = BLUETOOTH_ERROR_INTERNAL;
1495 g_variant_get(value, "(y)", &att_ecode);
1498 BT_ERR("ATT Error code: %d \n", att_ecode);
1503 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1505 user_info->cb, user_info->user_data);
1509 g_variant_unref(value);
1514 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
1515 const char *desc_handle, const guint8 *value, int length)
1518 GDBusConnection *conn;
1519 GVariantBuilder *builder;
1523 BT_CHECK_PARAMETER(desc_handle, return);
1524 BT_CHECK_PARAMETER(value, return);
1525 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1526 BT_CHECK_ENABLED(return);
1528 conn = _bt_gdbus_get_system_gconn();
1529 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1531 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1533 for (i = 0; i < length; i++) {
1534 g_variant_builder_add(builder, "y", value[i]);
1537 val = g_variant_new("(ay)", builder);
1539 g_dbus_connection_call(conn,
1542 GATT_DESC_INTERFACE,
1545 G_VARIANT_TYPE("(y)"),
1546 G_DBUS_CALL_FLAGS_NONE,
1548 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1551 g_variant_builder_unref(builder);
1554 return BLUETOOTH_ERROR_NONE;
1557 #ifndef GATT_NO_RELAY
1558 static int __bluetooth_gatt_watch_characteristics(void)
1560 int result = BLUETOOTH_ERROR_NONE;
1563 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1565 result = _bt_send_request(BT_BLUEZ_SERVICE,
1566 BT_GATT_WATCH_CHARACTERISTIC,
1567 in_param1, in_param2, in_param3, in_param4, &out_param);
1569 if (result != BLUETOOTH_ERROR_NONE)
1570 BT_ERR("Watch Characteristic request failed !");
1572 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1578 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1580 GDBusConnection *conn;
1581 GError *error = NULL;
1582 int ret = BLUETOOTH_ERROR_NONE;
1584 BT_CHECK_PARAMETER(char_handle, return);
1585 BT_CHECK_ENABLED(return);
1587 BT_INFO_C("### Enable CCCD : %s", char_handle);
1589 conn = _bt_gdbus_get_system_gconn();
1590 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1592 g_dbus_connection_call_sync(conn,
1595 GATT_CHAR_INTERFACE,
1599 G_DBUS_CALL_FLAGS_NONE,
1600 GATT_DEFAULT_TIMEOUT, NULL, &error);
1603 g_dbus_error_strip_remote_error(error);
1604 BT_ERR_C("### Watch Failed: %s", error->message);
1605 if (g_strrstr(error->message, "Already notifying"))
1606 ret = BLUETOOTH_ERROR_NONE;
1607 else if (g_strrstr(error->message, "In Progress"))
1608 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1609 else if (g_strrstr(error->message, "Operation is not supported"))
1610 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1611 /*failed because of either Insufficient Authorization or Write Not Permitted */
1612 else if (g_strrstr(error->message, "Write not permitted") ||
1613 g_strrstr(error->message, "Operation Not Authorized"))
1614 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1615 /* failed because of either Insufficient Authentication,
1616 Insufficient Encryption Key Size, or Insufficient Encryption. */
1617 else if (g_strrstr(error->message, "Not paired"))
1618 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1620 ret = BLUETOOTH_ERROR_INTERNAL;
1622 g_clear_error(&error);
1624 #ifndef GATT_NO_RELAY
1626 /* Register the client sender to bt-service */
1627 ret = __bluetooth_gatt_watch_characteristics();
1634 #ifndef GATT_NO_RELAY
1635 static int __bluetooth_gatt_unwatch_characteristics(void)
1637 int result = BLUETOOTH_ERROR_NONE;
1640 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1642 result = _bt_send_request(BT_BLUEZ_SERVICE,
1643 BT_GATT_UNWATCH_CHARACTERISTIC,
1644 in_param1, in_param2, in_param3, in_param4, &out_param);
1646 if (result != BLUETOOTH_ERROR_NONE)
1647 BT_ERR("Unwatch Characteristic request failed !");
1649 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1655 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1658 GDBusConnection *conn;
1659 GError *error = NULL;
1660 int ret = BLUETOOTH_ERROR_NONE;
1662 BT_CHECK_PARAMETER(char_handle, return);
1664 BT_CHECK_ENABLED(return);
1666 BT_INFO("Disable CCCD : %s", char_handle);
1668 conn = _bt_gdbus_get_system_gconn();
1669 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1671 g_dbus_connection_call_sync(conn,
1674 GATT_CHAR_INTERFACE,
1678 G_DBUS_CALL_FLAGS_NONE,
1679 GATT_DEFAULT_TIMEOUT, NULL, &error);
1682 BT_ERR("Watch Failed: %s", error->message);
1683 g_clear_error(&error);
1684 ret = BLUETOOTH_ERROR_INTERNAL;
1686 #ifndef GATT_NO_RELAY
1688 /* Unregister the client sender to bt-service */
1689 ret = __bluetooth_gatt_unwatch_characteristics();