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);
169 if (_bluetooth_gatt_check_service_change_watcher_address(address)
171 BT_INFO("The watcher is already set");
172 return BLUETOOTH_ERROR_NONE;
174 addr = g_malloc0(sizeof(bluetooth_device_address_t));
175 memcpy(addr, address, sizeof(bluetooth_device_address_t));
177 if (service_monitor_list == NULL) {
178 BT_ERR("There is NO watcher");
179 return BLUETOOTH_ERROR_NONE;
182 service_monitor_list =
183 g_slist_append(service_monitor_list, addr);
185 if (service_monitor_list == NULL) {
186 BT_ERR("There is NO watcher");
187 return BLUETOOTH_ERROR_NONE;
190 for (l = service_monitor_list; l != NULL; l = l->next) {
192 if (!memcmp(address, addr,
193 sizeof(bluetooth_device_address_t))) {
194 service_monitor_list =
195 g_slist_remove(service_monitor_list, addr);
201 if (service_monitor_list == NULL)
202 _bt_register_manager_subscribe_signal(FALSE);
205 return BLUETOOTH_ERROR_NONE;
208 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
209 bt_gatt_service_property_t *service)
211 GDBusProxy *properties_proxy = NULL;
212 GError *error = NULL;
213 GVariant *result = NULL;
214 GDBusConnection *g_conn;
216 char *char_handle = NULL;
217 GPtrArray *gp_array = NULL ;
218 GVariantIter *property_iter, *char_iter = NULL;
222 BT_CHECK_PARAMETER(service_handle, return);
223 BT_CHECK_PARAMETER(service, return);
224 BT_CHECK_ENABLED(return);
226 g_conn = _bt_gdbus_get_system_gconn();
227 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
229 properties_proxy = g_dbus_proxy_new_sync(g_conn,
230 G_DBUS_PROXY_FLAGS_NONE, NULL,
233 BT_PROPERTIES_INTERFACE,
236 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
238 result = g_dbus_proxy_call_sync(properties_proxy,
240 g_variant_new("(s)", GATT_SERV_INTERFACE),
241 G_DBUS_CALL_FLAGS_NONE,
248 BT_ERR("Fail to get properties (Error: %s)", error->message);
249 g_clear_error(&error);
251 BT_ERR("Fail to get properties");
252 g_object_unref(properties_proxy);
253 return BLUETOOTH_ERROR_INTERNAL;
256 g_variant_get(result, "(a{sv})", &property_iter);
258 memset(service, 0, sizeof(bt_gatt_service_property_t));
260 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
261 if (!g_strcmp0(key, "UUID")) {
263 service->uuid = g_variant_dup_string(value, &len);
264 _bt_get_uuid_specification_name(service->uuid, &name);
265 BT_INFO("======> Service : %s [%s]", service->uuid, name);
267 } else if (!g_strcmp0(key, "Primary")) {
268 service->primary = g_variant_get_boolean(value);
270 } else if (!g_strcmp0(key, "Includes")) {
271 g_variant_get(value, "ao", &char_iter);
272 gp_array = g_ptr_array_new();
273 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
274 g_ptr_array_add(gp_array, (gpointer)char_handle);
276 if (gp_array->len != 0) {
277 service->include_handles.count = gp_array->len;
278 service->include_handles.handle =
279 __get_string_array_from_gptr_array(gp_array);
281 g_ptr_array_free(gp_array, TRUE);
282 g_variant_iter_free(char_iter);
283 } else if (!g_strcmp0(key, "Characteristics")) {
284 g_variant_get(value, "ao", &char_iter);
285 gp_array = g_ptr_array_new();
286 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
287 g_ptr_array_add(gp_array, (gpointer)char_handle);
289 if (gp_array->len != 0) {
290 service->char_handle.count = gp_array->len;
291 service->char_handle.handle =
292 __get_string_array_from_gptr_array(gp_array);
294 BT_DBG("Characteristics count : %d", service->char_handle.count);
295 g_ptr_array_free(gp_array, TRUE);
296 g_variant_iter_free(char_iter);
300 service->handle = g_strdup(service_handle);
302 g_variant_iter_free(property_iter);
303 g_variant_unref(result);
304 g_object_unref(properties_proxy);
306 return BLUETOOTH_ERROR_NONE;
309 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
310 const bluetooth_device_address_t *address,
311 bt_gatt_handle_info_t *prim_svc)
313 GVariant *result = NULL;
315 GVariantIter *svc_iter;
316 GVariantIter *interface_iter;
317 char *object_path = NULL;
318 char *interface_str = NULL;
319 const gchar *key = NULL;
320 GVariant *value = NULL;
321 GPtrArray *gp_array = NULL;
322 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
323 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
324 int ret = BLUETOOTH_ERROR_INTERNAL;
327 BT_CHECK_PARAMETER(address, return);
328 BT_CHECK_PARAMETER(prim_svc, return);
329 BT_CHECK_ENABLED(return);
331 result = _bt_get_managed_objects();
335 _bt_convert_addr_type_to_string(device_address,
336 (unsigned char *)address->addr);
338 gp_array = g_ptr_array_new();
339 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
341 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
343 if (object_path == NULL)
346 _bt_convert_device_path_to_address(object_path, temp_address);
348 if (g_strcmp0(temp_address, device_address) != 0)
351 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
352 &interface_str, &svc_iter)) {
353 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
356 BT_DBG("Object Path: %s", object_path);
357 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
358 if (g_strcmp0(key, "Primary") == 0) {
359 if (g_variant_get_boolean(value))
360 g_ptr_array_add(gp_array, (gpointer)object_path);
366 if (gp_array->len == 0) {
367 BT_ERR("gp_array is NULL");
368 ret = BLUETOOTH_ERROR_NOT_FOUND;
370 ret = BLUETOOTH_ERROR_NONE;
371 prim_svc->count = gp_array->len;
372 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
375 g_ptr_array_free(gp_array, TRUE);
376 g_variant_iter_free(iter);
377 g_variant_unref(result);
382 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
383 const char *service_uuid,
384 bt_gatt_service_property_t *service)
386 GVariant *result = NULL;
388 GVariantIter *svc_iter;
389 GVariantIter *interface_iter;
390 char *object_path = NULL;
391 char *interface_str = NULL;
392 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
393 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
394 int ret = BLUETOOTH_ERROR_INTERNAL;
396 BT_CHECK_PARAMETER(address, return);
397 BT_CHECK_PARAMETER(service_uuid, return);
398 BT_CHECK_PARAMETER(service, return);
399 BT_CHECK_ENABLED(return);
401 result = _bt_get_managed_objects();
405 _bt_convert_addr_type_to_string(device_address,
406 (unsigned char *)address->addr);
408 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
410 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
412 if (object_path == NULL)
415 _bt_convert_device_path_to_address(object_path,
418 if (g_strcmp0(temp_address, device_address) != 0)
421 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
422 &interface_str, &svc_iter)) {
423 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
426 BT_DBG("Object Path: %s", object_path);
427 ret = bluetooth_gatt_get_service_property(object_path,
430 if (ret != BLUETOOTH_ERROR_NONE) {
431 BT_ERR("Get service property failed(0x%08x)", ret);
433 if (service->primary == TRUE &&
434 g_strstr_len(service->uuid, -1,
436 ret = BLUETOOTH_ERROR_NONE;
440 bluetooth_gatt_free_service_property(service);
445 g_variant_iter_free(iter);
446 g_variant_unref(result);
451 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
452 GAsyncResult *res, gpointer user_data)
455 GVariant *char_value;
456 GVariantIter *char_iter;
457 GPtrArray *gp_array = NULL;
458 bt_gatt_discovered_char_t svc_char = { 0, };
460 GError *error = NULL;
461 bt_user_info_t *user_info;
465 user_info = _bt_get_user_data(BT_COMMON);
466 svc_char.service_handle = user_data;
468 value = g_dbus_proxy_call_finish(proxy, res, &error);
472 BT_ERR("Get service characteristics failed\n errCode[%x],"
473 "message[%s]\n", error->code, error->message);
474 g_clear_error(&error);
476 BT_ERR("Get service characteristics failed\n");
479 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
480 BLUETOOTH_ERROR_INTERNAL, NULL,
481 user_info->cb, user_info->user_data);
483 g_free(svc_char.service_handle);
484 g_object_unref(proxy);
488 g_variant_get(value, "(v)", &char_value);
489 g_variant_get(char_value, "ao", &char_iter);
491 gp_array = g_ptr_array_new();
492 while (g_variant_iter_loop(char_iter, "&o", &char_handle));
493 g_ptr_array_add(gp_array, (gpointer)char_handle);
495 if (gp_array->len != 0) {
496 svc_char.handle_info.count = gp_array->len;
497 svc_char.handle_info.handle =
498 __get_string_array_from_gptr_array(gp_array);
500 g_ptr_array_free(gp_array, TRUE);
503 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
504 BLUETOOTH_ERROR_NONE, &svc_char,
505 user_info->cb, user_info->user_data);
508 g_strfreev(svc_char.handle_info.handle);
509 g_free(svc_char.service_handle);
510 g_variant_iter_free(char_iter);
511 g_variant_unref(value);
512 g_object_unref(proxy);
515 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
516 const char *service_handle)
518 GDBusProxy *properties_proxy = NULL;
519 GDBusConnection *g_conn;
520 GError *error = NULL;
525 BT_CHECK_PARAMETER(service_handle, return);
526 BT_CHECK_ENABLED(return);
528 g_conn = _bt_gdbus_get_system_gconn();
529 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
531 properties_proxy = g_dbus_proxy_new_sync(g_conn,
532 G_DBUS_PROXY_FLAGS_NONE, NULL,
535 BT_PROPERTIES_INTERFACE,
538 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
540 handle = g_strdup(service_handle);
541 g_dbus_proxy_call(properties_proxy,
543 g_variant_new("(ss)",
544 GATT_SERV_INTERFACE, "Characteristics"),
545 G_DBUS_CALL_FLAGS_NONE,
548 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
552 return BLUETOOTH_ERROR_NONE;
556 static int __get_permission_flag(char *permission)
560 retv_if(permission == NULL, ret);
562 BT_INFO("permission = %s", permission);
564 if (!g_strcmp0(permission, "broadcast"))
565 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
566 else if (!g_strcmp0(permission, "read"))
567 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
568 else if (!g_strcmp0(permission, "write-without-response"))
569 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
570 else if (!g_strcmp0(permission, "write"))
571 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
572 else if (!g_strcmp0(permission, "notify"))
573 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
574 else if (!g_strcmp0(permission, "indicate"))
575 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
576 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
577 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
578 else if (!g_strcmp0(permission, "reliable-write"))
579 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
580 else if (!g_strcmp0(permission, "writable-auxiliaries"))
581 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
582 else if (!g_strcmp0(permission, "encrypt-read"))
583 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
584 else if (!g_strcmp0(permission, "encrypt-write"))
585 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
586 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
587 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
588 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
589 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
594 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
595 const char *char_handle, bt_gatt_char_property_t *characteristic)
597 GDBusProxy *properties_proxy = NULL;
598 GError *error = NULL;
599 GVariant *value = NULL;
600 GVariant *result = NULL;
601 GByteArray *gb_array = NULL;
602 GPtrArray *gp_array = NULL ;
603 GDBusConnection *g_conn;
607 char *char_desc_handle = NULL;
609 GVariantIter *property_iter;
610 GVariantIter *char_value_iter;
611 GVariantIter *char_perm_iter;
612 GVariantIter *char_desc_iter;
615 BT_CHECK_PARAMETER(char_handle, return);
616 BT_CHECK_PARAMETER(characteristic, return);
618 BT_CHECK_ENABLED(return);
620 g_conn = _bt_gdbus_get_system_gconn();
621 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
623 properties_proxy = g_dbus_proxy_new_sync(g_conn,
624 G_DBUS_PROXY_FLAGS_NONE, NULL,
627 BT_PROPERTIES_INTERFACE,
630 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
632 result = g_dbus_proxy_call_sync(properties_proxy,
634 g_variant_new("(s)", GATT_CHAR_INTERFACE),
635 G_DBUS_CALL_FLAGS_NONE,
642 BT_ERR("Fail to get properties (Error: %s)", error->message);
643 g_clear_error(&error);
645 BT_ERR("Fail to get properties");
646 g_object_unref(properties_proxy);
647 return BLUETOOTH_ERROR_INTERNAL;
650 g_variant_get(result, "(a{sv})", &property_iter);
652 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
653 characteristic->handle = g_strdup(char_handle);
655 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
656 if (!g_strcmp0(key, "UUID")) {
658 characteristic->uuid = g_variant_dup_string(value, &len);
659 _bt_get_uuid_specification_name(characteristic->uuid, &name);
660 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
662 } else if (!g_strcmp0(key, "Value")) {
663 gb_array = g_byte_array_new();
664 g_variant_get(value, "ay", &char_value_iter);
665 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
666 // BT_DBG("value of char = %d",char_value);
667 g_byte_array_append(gb_array, &char_value, 1);
669 g_variant_iter_free(char_value_iter);
671 if (gb_array->len != 0) {
672 characteristic->val = g_malloc0(gb_array->len *
673 sizeof(unsigned char));
674 memcpy(characteristic->val, gb_array->data, gb_array->len);
676 characteristic->val_len = gb_array->len;
677 g_byte_array_free(gb_array, TRUE);
678 } else if (!g_strcmp0(key, "Flags")) {
679 g_variant_get(value, "as", &char_perm_iter);
680 characteristic->permission = 0x00;
681 while (g_variant_iter_loop(char_perm_iter, "s", &permission)) {
682 BT_DBG("permission = %s", permission);
683 characteristic->permission |= __get_permission_flag(permission);
684 BT_DBG("permission check = %d", characteristic->permission);
686 g_variant_iter_free(char_perm_iter);
687 } else if (!g_strcmp0(key, "Descriptors")) {
688 g_variant_get(value, "ao", &char_desc_iter);
689 gp_array = g_ptr_array_new();
690 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
691 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
693 g_variant_iter_free(char_desc_iter);
694 if (gp_array->len != 0) {
695 characteristic->char_desc_handle.count = gp_array->len;
696 characteristic->char_desc_handle.handle =
697 __get_string_array_from_gptr_array(gp_array);
699 g_ptr_array_free(gp_array, TRUE);
703 g_variant_iter_free(property_iter);
704 g_variant_unref(result);
705 g_object_unref(properties_proxy);
708 return BLUETOOTH_ERROR_NONE;
711 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
712 GAsyncResult *res, gpointer user_data)
715 GVariantIter *char_iter;
717 GError *error = NULL;
718 bt_user_info_t *user_info;
719 int ret = BLUETOOTH_ERROR_INTERNAL;
720 bt_gatt_char_property_t characteristic;
722 user_info = _bt_get_user_data(BT_COMMON);
724 value = g_dbus_proxy_call_finish(proxy, res, &error);
728 BT_ERR("Get service characteristics failed\n errCode[%x],"
729 "message[%s]\n", error->code, error->message);
730 g_clear_error(&error);
732 BT_ERR("Get service characteristics failed\n");
735 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
736 BLUETOOTH_ERROR_INTERNAL, NULL,
737 user_info->cb, user_info->user_data);
739 g_object_unref(proxy);
744 g_variant_get(value, "(ao)", &char_iter);
746 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
749 ret = bluetooth_gatt_get_characteristics_property(char_handle,
752 if (ret != BLUETOOTH_ERROR_NONE) {
753 BT_ERR("Get characteristic property failed(0x%08x)", ret);
755 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
756 ret = BLUETOOTH_ERROR_NONE;
760 bluetooth_gatt_free_char_property(&characteristic);
764 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
765 &characteristic, user_info->cb, user_info->user_data);
768 bluetooth_gatt_free_char_property(&characteristic);
769 g_variant_iter_free(char_iter);
770 g_variant_unref(value);
774 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
775 const char *char_uuid)
777 GDBusProxy *properties_proxy = NULL;
778 GDBusConnection *g_conn;
779 GError *error = NULL;
782 BT_CHECK_PARAMETER(service_handle, return);
783 BT_CHECK_PARAMETER(char_uuid, return);
784 BT_CHECK_ENABLED(return);
786 g_conn = _bt_gdbus_get_system_gconn();
787 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
789 properties_proxy = g_dbus_proxy_new_sync(g_conn,
790 G_DBUS_PROXY_FLAGS_NONE, NULL,
793 BT_PROPERTIES_INTERFACE,
796 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
798 uuid = g_strdup(char_uuid);
799 g_dbus_proxy_call(properties_proxy,
801 g_variant_new("(ss)",
802 GATT_SERV_INTERFACE, "Characteristics"),
803 G_DBUS_CALL_FLAGS_NONE,
806 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
809 return BLUETOOTH_ERROR_NONE;
812 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
813 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
815 GDBusProxy *properties_proxy = NULL;
816 GError *error = NULL;
817 GDBusConnection *g_conn;
818 GVariant *result = NULL;
819 GVariantIter *property_iter;
823 GVariant *value = NULL;
824 GByteArray *gb_array = NULL;
825 GVariantIter *desc_value_iter;
828 BT_CHECK_PARAMETER(descriptor_handle, return);
829 BT_CHECK_PARAMETER(descriptor, return);
831 BT_CHECK_ENABLED(return);
833 g_conn = _bt_gdbus_get_system_gconn();
834 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
836 properties_proxy = g_dbus_proxy_new_sync(g_conn,
837 G_DBUS_PROXY_FLAGS_NONE, NULL,
840 BT_PROPERTIES_INTERFACE,
843 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
845 result = g_dbus_proxy_call_sync(properties_proxy,
847 g_variant_new("(s)", GATT_DESC_INTERFACE),
848 G_DBUS_CALL_FLAGS_NONE,
855 BT_ERR("Fail to get properties (Error: %s)", error->message);
856 g_clear_error(&error);
858 BT_ERR("Fail to get properties");
859 g_object_unref(properties_proxy);
860 return BLUETOOTH_ERROR_INTERNAL;
863 g_variant_get(result, "(a{sv})", &property_iter);
865 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
866 descriptor->handle = g_strdup(descriptor_handle);
868 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
869 if (!g_strcmp0(key, "UUID")) {
871 descriptor->uuid = g_variant_dup_string(value, &len);
872 _bt_get_uuid_specification_name(descriptor->uuid, &name);
873 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
875 } else if (!g_strcmp0(key, "Value")) {
876 gb_array = g_byte_array_new();
877 g_variant_get(value, "ay", &desc_value_iter);
878 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
879 BT_DBG("value of descriptor = %d", char_value);
880 g_byte_array_append(gb_array, &char_value, 1);
882 g_variant_iter_free(desc_value_iter);
884 if (gb_array->len != 0) {
885 descriptor->val = g_malloc0(gb_array->len *
886 sizeof(unsigned char));
887 memcpy(descriptor->val, gb_array->data, gb_array->len);
889 descriptor->val_len = gb_array->len;
890 g_byte_array_free(gb_array, TRUE);
894 g_variant_iter_free(property_iter);
895 g_variant_unref(result);
896 g_object_unref(properties_proxy);
899 return BLUETOOTH_ERROR_NONE;
902 static void __bluetooth_internal_read_cb(GObject *source_object,
906 GError *error = NULL;
907 bt_user_info_t *user_info;
908 bt_gatt_char_value_t char_value = { 0, };
909 GDBusConnection *system_gconn = NULL;
911 GByteArray *gp_byte_array = NULL;
914 int ret = BLUETOOTH_ERROR_NONE;
917 user_info = _bt_get_user_data(BT_COMMON);
919 system_gconn = _bt_gdbus_get_system_gconn();
920 value = g_dbus_connection_call_finish(system_gconn, res, &error);
923 BT_ERR("Error : %s \n", error->message);
924 if (g_strrstr(error->message, "Not paired"))
925 ret = BLUETOOTH_ERROR_NOT_PAIRED;
927 ret = BLUETOOTH_ERROR_INTERNAL;
929 g_clear_error(&error);
931 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
933 user_info->cb, user_info->user_data);
939 char_value.char_handle = user_data;
940 gp_byte_array = g_byte_array_new();
941 g_variant_get(value, "(ay)", &iter);
943 while (g_variant_iter_loop(iter, "y", &g_byte))
944 g_byte_array_append(gp_byte_array, &g_byte, 1);
946 if (gp_byte_array->len != 0) {
947 char_value.val_len = gp_byte_array->len;
948 char_value.char_value = gp_byte_array->data;
952 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
953 BLUETOOTH_ERROR_NONE, &char_value,
954 user_info->cb, user_info->user_data);
957 g_free(char_value.char_handle);
958 g_byte_array_free(gp_byte_array, TRUE);
959 g_variant_unref(value);
960 g_variant_iter_free(iter);
965 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *characteristic)
967 GDBusConnection *conn;
970 BT_CHECK_PARAMETER(characteristic, return);
971 BT_CHECK_ENABLED(return);
973 conn = _bt_gdbus_get_system_gconn();
974 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
976 handle = g_strdup(characteristic);
978 g_dbus_connection_call(conn,
984 G_VARIANT_TYPE("(ay)"),
985 G_DBUS_CALL_FLAGS_NONE,
988 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
991 return BLUETOOTH_ERROR_NONE;
994 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
995 const char *char_handle, const guint8 *value, int length)
998 GVariantBuilder *builder;
999 GError *error = NULL;
1000 GDBusConnection *conn;
1004 BT_CHECK_PARAMETER(char_handle, return);
1005 BT_CHECK_PARAMETER(value, return);
1006 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1007 BT_CHECK_ENABLED(return);
1009 conn = _bt_gdbus_get_system_gconn();
1010 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1012 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1014 for (i = 0; i < length; i++)
1015 g_variant_builder_add(builder, "y", value[i]);
1017 val = g_variant_new("(ay)", builder);
1019 g_dbus_connection_call_sync(conn,
1022 GATT_CHAR_INTERFACE,
1026 G_DBUS_CALL_FLAGS_NONE,
1030 BT_ERR("Set value Failed: %s", error->message);
1031 g_clear_error(&error);
1032 g_variant_builder_unref(builder);
1033 return BLUETOOTH_ERROR_INTERNAL;
1036 g_variant_builder_unref(builder);
1039 return BLUETOOTH_ERROR_NONE;
1042 static void __bluetooth_internal_write_cb(GObject *source_object,
1047 GError *error = NULL;
1048 bt_user_info_t *user_info;
1049 GDBusConnection *system_gconn = NULL;
1051 int result = BLUETOOTH_ERROR_NONE;
1052 guint8 att_ecode = 0;
1054 user_info = _bt_get_user_data(BT_COMMON);
1056 system_gconn = _bt_gdbus_get_system_gconn();
1057 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1060 BT_ERR("Error : %s \n", error->message);
1061 g_clear_error(&error);
1062 result = BLUETOOTH_ERROR_INTERNAL;
1064 g_variant_get(value, "(y)", &att_ecode);
1067 BT_ERR("ATT Error code: %d \n", att_ecode);
1072 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1074 user_info->cb, user_info->user_data);
1076 BT_ERR("user info is null");
1080 g_variant_unref(value);
1085 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1086 const char *char_handle, const guint8 *value, int length, guint8 write_type)
1089 GVariantBuilder *builder;
1090 GDBusConnection *conn;
1092 int ret = BLUETOOTH_ERROR_NONE;
1094 BT_CHECK_PARAMETER(char_handle, return);
1095 BT_CHECK_PARAMETER(value, return);
1096 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1097 BT_CHECK_ENABLED_INTERNAL(return);
1099 conn = _bt_gdbus_get_system_gconn();
1100 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1102 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1104 for (i = 0; i < length; i++)
1105 g_variant_builder_add(builder, "y", value[i]);
1107 val = g_variant_new("ay", builder);
1108 g_dbus_connection_call(conn,
1111 GATT_CHAR_INTERFACE,
1113 g_variant_new("(y@ay)", write_type, val),
1114 G_VARIANT_TYPE("(y)"),
1115 G_DBUS_CALL_FLAGS_NONE,
1117 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1120 g_variant_builder_unref(builder);
1124 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1125 const char *char_handle, const guint8 *value, int length)
1128 GDBusConnection *conn;
1129 GVariantBuilder *builder;
1133 BT_CHECK_PARAMETER(char_handle, return);
1134 BT_CHECK_PARAMETER(value, return);
1135 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1136 BT_CHECK_ENABLED(return);
1138 conn = _bt_gdbus_get_system_gconn();
1139 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1141 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1143 for (i = 0; i < length; i++) {
1144 g_variant_builder_add(builder, "y", value[i]);
1145 BT_DBG("value [] = %d", value[i]);
1148 val = g_variant_new("(ay)", builder);
1150 g_dbus_connection_call(conn,
1153 GATT_CHAR_INTERFACE,
1157 G_DBUS_CALL_FLAGS_NONE,
1159 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1162 g_variant_builder_unref(builder);
1165 return BLUETOOTH_ERROR_NONE;
1168 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1169 bt_gatt_char_property_t *characteristic)
1172 GDBusProxy *properties_proxy = NULL;
1173 GError *error = NULL;
1174 GVariant *value = NULL;
1175 GVariant *result = NULL;
1176 GDBusConnection *g_conn;
1177 int i, ret = BLUETOOTH_ERROR_NONE;
1178 const char *uuid = NULL;
1180 GVariantIter *desc_value_iter, *property_iter;
1182 char_descriptor_type_t desc_type = TYPE_NONE;
1184 g_conn = _bt_gdbus_get_system_gconn();
1185 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1187 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1188 G_DBUS_PROXY_FLAGS_NONE, NULL,
1191 BT_PROPERTIES_INTERFACE,
1194 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1196 result = g_dbus_proxy_call_sync(properties_proxy,
1198 g_variant_new("(s)", GATT_DESC_INTERFACE),
1199 G_DBUS_CALL_FLAGS_NONE,
1205 if (error != NULL) {
1206 BT_ERR("Fail to get properties (Error: %s)", error->message);
1207 g_clear_error(&error);
1209 BT_ERR("Fail to get properties");
1210 g_object_unref(properties_proxy);
1211 return BLUETOOTH_ERROR_INTERNAL;
1213 g_variant_get(result, "(a{sv})", &property_iter);
1214 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1215 if (!g_strcmp0(key, "UUID")) {
1216 uuid = g_variant_get_string(value, &len);
1217 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1218 BT_DBG("GATT_USER_DESC_UUID");
1219 desc_type = USER_DESC;
1220 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1221 BT_DBG("GATT_CHAR_FORMAT");
1222 desc_type = CHAR_FORMAT;
1223 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1224 BT_DBG("GATT_CHAR_CLIENT_CONF");
1225 desc_type = CLIENT_CONF;
1226 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1227 BT_DBG("GATT_CHAR_SERVER_CONF");
1228 desc_type = SERVER_CONF;
1230 BT_DBG("descriptor uuid = %s", uuid);
1232 } else if (!g_strcmp0(key, "Value")) {
1233 switch (desc_type) {
1235 BT_DBG("Format descriptor");
1236 g_variant_get(value, "(yyqyq)",
1237 &(characteristic->format.format),
1238 &(characteristic->format.exponent),
1239 &(characteristic->format.unit),
1240 &(characteristic->format.name_space),
1241 &(characteristic->format.description));
1244 BT_DBG("User descriptor");
1245 g_variant_get(value, "ay", &desc_value_iter);
1246 len = g_variant_get_size((GVariant *)desc_value_iter);
1249 characteristic->description = (char *)g_malloc0(len + 1);
1250 if (!characteristic->description) {
1251 ret = BLUETOOTH_ERROR_OUT_OF_MEMORY;
1255 for (i = 0; i < len; i++) {
1256 g_variant_iter_loop(desc_value_iter, "y",
1257 &characteristic->description[i]);
1258 BT_DBG("description = %s", characteristic->description);
1260 g_variant_iter_free(desc_value_iter);
1263 BT_DBG(" CLIENT_CONF");
1266 BT_DBG(" SERVER_CONF");
1275 g_variant_iter_free(property_iter);
1276 g_variant_unref(result);
1277 g_object_unref(properties_proxy);
1284 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1285 GAsyncResult *res, gpointer user_data)
1289 GVariant *char_value;
1290 GVariantIter *char_iter;
1292 GError *error = NULL;
1293 bt_user_info_t *user_info;
1294 bt_gatt_char_property_t characteristic = {0, };
1295 int ret = BLUETOOTH_ERROR_INTERNAL;
1297 user_info = _bt_get_user_data(BT_COMMON);
1299 value = g_dbus_proxy_call_finish(proxy, res, &error);
1301 if (value == NULL) {
1302 if (error != NULL) {
1303 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1304 "message[%s]\n", error->code, error->message);
1305 g_clear_error(&error);
1307 BT_ERR("Get characteristic descriptor failed\n");
1310 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1311 BLUETOOTH_ERROR_INTERNAL, NULL,
1312 user_info->cb, user_info->user_data);
1315 g_object_unref(proxy);
1319 g_variant_get(value, "(v)", &char_value);
1320 g_variant_get(char_value, "ao", &char_iter);
1322 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1323 BT_DBG("object path of descriptor = %s", char_handle);
1325 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1327 BT_DBG("Descriptor read status [%d]", ret);
1331 characteristic.handle = user_data;
1333 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1334 ret, &characteristic, user_info->cb, user_info->user_data);
1336 bluetooth_gatt_free_char_property(&characteristic);
1338 g_variant_iter_free(char_iter);
1339 g_variant_unref(value);
1343 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1344 const char *characteristic_handle)
1346 GDBusProxy *properties_proxy = NULL;
1347 GDBusConnection *g_conn;
1349 GError *error = NULL;
1351 BT_CHECK_PARAMETER(characteristic_handle, return);
1352 BT_CHECK_ENABLED(return);
1354 g_conn = _bt_gdbus_get_system_gconn();
1355 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1357 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1358 G_DBUS_PROXY_FLAGS_NONE, NULL,
1360 characteristic_handle,
1361 BT_PROPERTIES_INTERFACE,
1364 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1366 handle = g_strdup(characteristic_handle);
1367 g_dbus_proxy_call(properties_proxy,
1369 g_variant_new("(ss)",
1370 GATT_CHAR_INTERFACE, "Descriptors"),
1371 G_DBUS_CALL_FLAGS_NONE,
1373 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1376 return BLUETOOTH_ERROR_NONE;
1379 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1383 GError *error = NULL;
1384 bt_user_info_t *user_info;
1385 bt_gatt_char_property_t char_value = { 0, };
1386 GDBusConnection *system_gconn = NULL;
1388 GByteArray *gp_byte_array = NULL;
1393 user_info = _bt_get_user_data(BT_COMMON);
1394 system_gconn = _bt_gdbus_get_system_gconn();
1396 char_value.handle = user_data;
1397 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1400 BT_ERR("Error : %s \n", error->message);
1401 g_clear_error(&error);
1403 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1404 BLUETOOTH_ERROR_INTERNAL, NULL,
1405 user_info->cb, user_info->user_data);
1407 g_free(char_value.handle);
1411 gp_byte_array = g_byte_array_new();
1412 g_variant_get(value, "(ay)", &iter);
1414 while (g_variant_iter_loop(iter, "y", &g_byte))
1415 g_byte_array_append(gp_byte_array, &g_byte, 1);
1417 if (gp_byte_array->len != 0) {
1418 char_value.val_len = (unsigned int)gp_byte_array->len;
1419 char_value.description = (char *)gp_byte_array->data;
1423 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1424 BLUETOOTH_ERROR_NONE, &char_value,
1425 user_info->cb, user_info->user_data);
1428 g_byte_array_free(gp_byte_array, TRUE);
1429 g_free(char_value.handle);
1430 g_variant_unref(value);
1431 g_variant_iter_free(iter);
1436 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *char_descriptor)
1438 GDBusConnection *conn;
1442 BT_CHECK_PARAMETER(char_descriptor, return);
1443 BT_CHECK_ENABLED(return);
1445 conn = _bt_gdbus_get_system_gconn();
1446 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1448 handle = g_strdup(char_descriptor);
1450 g_dbus_connection_call(conn,
1453 GATT_DESC_INTERFACE,
1456 G_VARIANT_TYPE("(ay)"),
1457 G_DBUS_CALL_FLAGS_NONE,
1460 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1464 return BLUETOOTH_ERROR_NONE;
1467 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1471 GError *error = NULL;
1472 bt_user_info_t *user_info;
1473 GDBusConnection *system_gconn = NULL;
1475 int result = BLUETOOTH_ERROR_NONE;
1476 guint8 att_ecode = 0;
1479 user_info = _bt_get_user_data(BT_COMMON);
1481 system_gconn = _bt_gdbus_get_system_gconn();
1482 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1485 BT_ERR("Error : %s \n", error->message);
1486 g_clear_error(&error);
1487 result = BLUETOOTH_ERROR_INTERNAL;
1489 g_variant_get(value, "(y)", &att_ecode);
1492 BT_ERR("ATT Error code: %d \n", att_ecode);
1497 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1499 user_info->cb, user_info->user_data);
1503 g_variant_unref(value);
1508 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(
1509 const char *desc_handle, const guint8 *value, int length)
1512 GDBusConnection *conn;
1513 GVariantBuilder *builder;
1517 BT_CHECK_PARAMETER(desc_handle, return);
1518 BT_CHECK_PARAMETER(value, return);
1519 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1520 BT_CHECK_ENABLED(return);
1522 conn = _bt_gdbus_get_system_gconn();
1523 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1525 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1527 for (i = 0; i < length; i++)
1528 g_variant_builder_add(builder, "y", value[i]);
1530 val = g_variant_new("(ay)", builder);
1532 g_dbus_connection_call(conn,
1535 GATT_DESC_INTERFACE,
1538 G_VARIANT_TYPE("(y)"),
1539 G_DBUS_CALL_FLAGS_NONE,
1541 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1544 g_variant_builder_unref(builder);
1547 return BLUETOOTH_ERROR_NONE;
1550 #ifndef GATT_NO_RELAY
1551 static int __bluetooth_gatt_watch_characteristics(void)
1553 int result = BLUETOOTH_ERROR_NONE;
1556 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1558 result = _bt_send_request(BT_BLUEZ_SERVICE,
1559 BT_GATT_WATCH_CHARACTERISTIC,
1560 in_param1, in_param2, in_param3, in_param4, &out_param);
1562 if (result != BLUETOOTH_ERROR_NONE)
1563 BT_ERR("Watch Characteristic request failed !");
1565 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1571 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1573 GDBusConnection *conn;
1574 GError *error = NULL;
1575 int ret = BLUETOOTH_ERROR_NONE;
1577 BT_CHECK_PARAMETER(char_handle, return);
1578 BT_CHECK_ENABLED(return);
1580 BT_INFO_C("### Enable CCCD : %s", char_handle);
1582 conn = _bt_gdbus_get_system_gconn();
1583 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1585 g_dbus_connection_call_sync(conn,
1588 GATT_CHAR_INTERFACE,
1592 G_DBUS_CALL_FLAGS_NONE,
1593 GATT_DEFAULT_TIMEOUT, NULL, &error);
1596 g_dbus_error_strip_remote_error(error);
1597 BT_ERR_C("### Watch Failed: %s", error->message);
1598 if (g_strrstr(error->message, "Already notifying"))
1599 ret = BLUETOOTH_ERROR_NONE;
1600 else if (g_strrstr(error->message, "In Progress"))
1601 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1602 else if (g_strrstr(error->message, "Operation is not supported"))
1603 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1604 /*failed because of either Insufficient Authorization or Write Not Permitted */
1605 else if (g_strrstr(error->message, "Write not permitted") ||
1606 g_strrstr(error->message, "Operation Not Authorized"))
1607 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1608 /* failed because of either Insufficient Authentication,
1609 Insufficient Encryption Key Size, or Insufficient Encryption. */
1610 else if (g_strrstr(error->message, "Not paired"))
1611 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1613 ret = BLUETOOTH_ERROR_INTERNAL;
1615 g_clear_error(&error);
1617 #ifndef GATT_NO_RELAY
1619 /* Register the client sender to bt-service */
1620 ret = __bluetooth_gatt_watch_characteristics();
1627 #ifndef GATT_NO_RELAY
1628 static int __bluetooth_gatt_unwatch_characteristics(void)
1630 int result = BLUETOOTH_ERROR_NONE;
1633 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1635 result = _bt_send_request(BT_BLUEZ_SERVICE,
1636 BT_GATT_UNWATCH_CHARACTERISTIC,
1637 in_param1, in_param2, in_param3, in_param4, &out_param);
1639 if (result != BLUETOOTH_ERROR_NONE)
1640 BT_ERR("Unwatch Characteristic request failed !");
1642 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1648 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1651 GDBusConnection *conn;
1652 GError *error = NULL;
1653 int ret = BLUETOOTH_ERROR_NONE;
1655 BT_CHECK_PARAMETER(char_handle, return);
1657 BT_CHECK_ENABLED(return);
1659 BT_INFO("Disable CCCD : %s", char_handle);
1661 conn = _bt_gdbus_get_system_gconn();
1662 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1664 g_dbus_connection_call_sync(conn,
1667 GATT_CHAR_INTERFACE,
1671 G_DBUS_CALL_FLAGS_NONE,
1672 GATT_DEFAULT_TIMEOUT, NULL, &error);
1675 BT_ERR("Watch Failed: %s", error->message);
1676 g_clear_error(&error);
1677 ret = BLUETOOTH_ERROR_INTERNAL;
1679 #ifndef GATT_NO_RELAY
1681 /* Unregister the client sender to bt-service */
1682 ret = __bluetooth_gatt_unwatch_characteristics();