2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <glib/gprintf.h>
25 #include "bt-common.h"
26 #include "bt-event-handler.h"
27 #include "bt-gatt-client.h"
28 #include "bt-internal-types.h"
29 #include "bt-request-sender.h"
31 #define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
39 } char_descriptor_type_t;
41 static GSList *service_monitor_list = NULL;
43 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
45 BT_CHECK_PARAMETER(svc_pty, return);
47 g_free(svc_pty->uuid);
48 g_free(svc_pty->handle);
49 g_strfreev(svc_pty->include_handles.handle);
50 g_strfreev(svc_pty->char_handle.handle);
52 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
54 return BLUETOOTH_ERROR_NONE;
57 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
59 BT_CHECK_PARAMETER(char_pty, return);
61 g_free(char_pty->uuid);
62 g_free(char_pty->name);
63 g_free(char_pty->description);
64 g_free(char_pty->val);
65 g_free(char_pty->handle);
66 g_strfreev(char_pty->char_desc_handle.handle);
68 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
70 return BLUETOOTH_ERROR_NONE;
73 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
75 BT_CHECK_PARAMETER(desc_pty, return);
77 g_free(desc_pty->uuid);
78 g_free(desc_pty->val);
79 g_free(desc_pty->handle);
81 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
83 return BLUETOOTH_ERROR_NONE;
86 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
88 gchar *gp_path = NULL;
95 path = g_malloc0((gp->len + 1) * sizeof(char *));
97 for (i = 0; i < gp->len; i++) {
98 gp_path = g_ptr_array_index(gp, i);
99 path[i] = g_strdup(gp_path);
100 // BT_DBG("path[%d] : [%s]", i, path[i]);
106 gboolean _bluetooth_gatt_check_service_change_watcher_address(
107 const bluetooth_device_address_t *device_addr)
111 for (l = service_monitor_list; l != NULL; l = l->next) {
112 bluetooth_device_address_t *addr = l->data;
114 if (!memcmp(device_addr, addr,
115 sizeof(bluetooth_device_address_t)))
122 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
123 const bluetooth_device_address_t *address, gboolean enable)
126 bluetooth_device_address_t *addr = NULL;
127 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
129 _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
130 BT_INFO("Set watcher for %s with %d", secure_address, enable);
132 if (enable == TRUE) {
133 if (_bluetooth_gatt_check_service_change_watcher_address(address)
135 BT_INFO("The watcher is already set");
136 return BLUETOOTH_ERROR_NONE;
139 if (service_monitor_list == NULL) {
140 _bt_register_manager_subscribe_signal(TRUE);
143 addr = g_malloc0(sizeof(bluetooth_device_address_t));
144 memcpy(addr, address, sizeof(bluetooth_device_address_t));
146 service_monitor_list =
147 g_slist_append(service_monitor_list, addr);
149 for (l = service_monitor_list; l != NULL; l = l->next) {
152 if (!memcmp(address, addr,
153 sizeof(bluetooth_device_address_t))) {
154 service_monitor_list =
155 g_slist_remove(service_monitor_list, addr);
161 if (service_monitor_list == NULL)
162 _bt_register_manager_subscribe_signal(FALSE);
165 return BLUETOOTH_ERROR_NONE;
168 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
169 bt_gatt_service_property_t *service)
171 GDBusProxy *properties_proxy = NULL;
172 GError *error = NULL;
173 GVariant *result = NULL;
174 GDBusConnection *g_conn;
176 char *char_handle = NULL;
177 GPtrArray *gp_array = NULL ;
178 GVariantIter *property_iter, *char_iter = NULL;
182 BT_CHECK_PARAMETER(service_handle, return);
183 BT_CHECK_PARAMETER(service, return);
184 BT_CHECK_ENABLED(return);
186 g_conn = _bt_gdbus_get_system_gconn();
187 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
189 properties_proxy = g_dbus_proxy_new_sync(g_conn,
190 G_DBUS_PROXY_FLAGS_NONE, NULL,
193 BT_PROPERTIES_INTERFACE,
196 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
198 result = g_dbus_proxy_call_sync(properties_proxy,
200 g_variant_new("(s)", GATT_SERV_INTERFACE),
201 G_DBUS_CALL_FLAGS_NONE,
208 BT_ERR("Fail to get properties (Error: %s)", error->message);
209 g_clear_error(&error);
211 BT_ERR("Fail to get properties");
212 g_object_unref(properties_proxy);
213 return BLUETOOTH_ERROR_INTERNAL;
216 g_variant_get(result, "(a{sv})", &property_iter);
218 memset(service, 0, sizeof(bt_gatt_service_property_t));
220 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
221 if (!g_strcmp0(key, "UUID")) {
223 service->uuid = g_variant_dup_string(value, &len);
224 bluetooth_get_uuid_name(service->uuid, &name);
225 BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
227 } else if (!g_strcmp0(key, "Primary")) {
228 service->primary = g_variant_get_boolean(value);
230 } else if (!g_strcmp0(key, "Includes")) {
231 g_variant_get(value, "ao", &char_iter);
232 if (char_iter != NULL) {
233 gp_array = g_ptr_array_new();
234 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
235 g_ptr_array_add(gp_array, (gpointer)char_handle);
237 if (gp_array->len != 0) {
238 service->include_handles.count = gp_array->len;
239 service->include_handles.handle =
240 __get_string_array_from_gptr_array(gp_array);
242 g_ptr_array_free(gp_array, TRUE);
243 g_variant_iter_free(char_iter);
245 } else if (!g_strcmp0(key, "Characteristics")) {
246 g_variant_get(value, "ao", &char_iter);
247 if (char_iter != NULL) {
248 gp_array = g_ptr_array_new();
249 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
250 g_ptr_array_add(gp_array, (gpointer)char_handle);
252 if (gp_array->len != 0) {
253 service->char_handle.count = gp_array->len;
254 service->char_handle.handle =
255 __get_string_array_from_gptr_array(gp_array);
257 g_ptr_array_free(gp_array, TRUE);
258 g_variant_iter_free(char_iter);
260 BT_DBG("Characteristics count : %d", service->char_handle.count);
264 service->handle = g_strdup(service_handle);
266 g_variant_iter_free(property_iter);
267 g_variant_unref(result);
268 g_object_unref(properties_proxy);
270 return BLUETOOTH_ERROR_NONE;
273 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
274 const bluetooth_device_address_t *address,
275 bt_gatt_handle_info_t *prim_svc)
277 GVariant *result = NULL;
279 GVariantIter *svc_iter;
280 GVariantIter *interface_iter;
281 char *object_path = NULL;
282 char *interface_str = NULL;
283 const gchar *key = NULL;
284 GVariant *value = NULL;
285 GPtrArray *gp_array = NULL;
286 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
287 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
288 int ret = BLUETOOTH_ERROR_INTERNAL;
292 BT_CHECK_PARAMETER(address, return);
293 BT_CHECK_PARAMETER(prim_svc, return);
294 BT_CHECK_ENABLED(return);
296 result = _bt_get_managed_objects();
300 _bt_convert_addr_type_to_string(device_address,
301 (unsigned char *)address->addr);
303 gp_array = g_ptr_array_new();
304 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
306 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
308 if (object_path == NULL)
311 _bt_convert_device_path_to_address(object_path, temp_address);
313 if (g_strcmp0(temp_address, device_address) != 0)
316 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
317 &interface_str, &svc_iter)) {
318 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
321 BT_DBG("[%d] Object Path : %s", idx++, object_path);
322 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
323 if (g_strcmp0(key, "Primary") == 0) {
324 if (g_variant_get_boolean(value))
325 g_ptr_array_add(gp_array, (gpointer)object_path);
331 if (gp_array->len == 0) {
332 BT_ERR("gp_array is NULL");
333 ret = BLUETOOTH_ERROR_NOT_FOUND;
335 ret = BLUETOOTH_ERROR_NONE;
336 prim_svc->count = gp_array->len;
337 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
340 g_ptr_array_free(gp_array, TRUE);
341 g_variant_iter_free(iter);
342 g_variant_unref(result);
347 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
348 const char *service_uuid,
349 bt_gatt_service_property_t *service)
351 GVariant *result = NULL;
353 GVariantIter *svc_iter;
354 GVariantIter *interface_iter;
355 char *object_path = NULL;
356 char *interface_str = NULL;
357 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
358 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
359 int ret = BLUETOOTH_ERROR_INTERNAL;
361 BT_CHECK_PARAMETER(address, return);
362 BT_CHECK_PARAMETER(service_uuid, return);
363 BT_CHECK_PARAMETER(service, return);
364 BT_CHECK_ENABLED(return);
366 result = _bt_get_managed_objects();
370 _bt_convert_addr_type_to_string(device_address,
371 (unsigned char *)address->addr);
373 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
375 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
377 if (object_path == NULL)
380 _bt_convert_device_path_to_address(object_path,
383 if (g_strcmp0(temp_address, device_address) != 0)
386 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
387 &interface_str, &svc_iter)) {
388 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
391 BT_DBG("Object Path: %s", object_path);
392 ret = bluetooth_gatt_get_service_property(object_path,
395 if (ret != BLUETOOTH_ERROR_NONE) {
396 BT_ERR("Get service property failed(0x%08x)", ret);
398 if (service->primary == TRUE &&
399 g_strstr_len(service->uuid, -1,
401 ret = BLUETOOTH_ERROR_NONE;
405 bluetooth_gatt_free_service_property(service);
410 g_variant_iter_free(iter);
411 g_variant_unref(result);
416 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
417 GAsyncResult *res, gpointer user_data)
420 GVariant *char_value;
421 GVariantIter *char_iter;
422 GPtrArray *gp_array = NULL;
423 bt_gatt_discovered_char_t svc_char = { 0, };
425 GError *error = NULL;
426 bt_user_info_t *user_info;
430 user_info = _bt_get_user_data(BT_COMMON);
431 svc_char.service_handle = user_data;
433 value = g_dbus_proxy_call_finish(proxy, res, &error);
437 BT_ERR("Get service characteristics failed\n errCode[%x],"
438 "message[%s]\n", error->code, error->message);
439 g_clear_error(&error);
441 BT_ERR("Get service characteristics failed\n");
444 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
445 BLUETOOTH_ERROR_INTERNAL, NULL,
446 user_info->cb, user_info->user_data);
448 g_free(svc_char.service_handle);
449 g_object_unref(proxy);
453 g_variant_get(value, "(v)", &char_value);
454 g_variant_get(char_value, "ao", &char_iter);
456 gp_array = g_ptr_array_new();
457 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
458 g_ptr_array_add(gp_array, (gpointer)char_handle);
460 if (gp_array->len != 0) {
461 svc_char.handle_info.count = gp_array->len;
462 svc_char.handle_info.handle =
463 __get_string_array_from_gptr_array(gp_array);
465 g_ptr_array_free(gp_array, TRUE);
468 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
469 BLUETOOTH_ERROR_NONE, &svc_char,
470 user_info->cb, user_info->user_data);
473 g_strfreev(svc_char.handle_info.handle);
474 g_free(svc_char.service_handle);
475 g_variant_iter_free(char_iter);
476 g_variant_unref(value);
477 g_object_unref(proxy);
480 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
481 const char *service_handle)
483 GDBusProxy *properties_proxy = NULL;
484 GDBusConnection *g_conn;
485 GError *error = NULL;
490 BT_CHECK_PARAMETER(service_handle, return);
491 BT_CHECK_ENABLED(return);
493 g_conn = _bt_gdbus_get_system_gconn();
494 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
496 properties_proxy = g_dbus_proxy_new_sync(g_conn,
497 G_DBUS_PROXY_FLAGS_NONE, NULL,
500 BT_PROPERTIES_INTERFACE,
503 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
505 handle = g_strdup(service_handle);
506 g_dbus_proxy_call(properties_proxy,
508 g_variant_new("(ss)",
509 GATT_SERV_INTERFACE, "Characteristics"),
510 G_DBUS_CALL_FLAGS_NONE,
513 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
517 return BLUETOOTH_ERROR_NONE;
521 static int __get_permission_flag(char *permission)
525 retv_if(permission == NULL, ret);
527 if (!g_strcmp0(permission, "broadcast"))
528 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
529 else if (!g_strcmp0(permission, "read"))
530 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
531 else if (!g_strcmp0(permission, "write-without-response"))
532 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
533 else if (!g_strcmp0(permission, "write"))
534 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
535 else if (!g_strcmp0(permission, "notify"))
536 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
537 else if (!g_strcmp0(permission, "indicate"))
538 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
539 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
540 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
541 else if (!g_strcmp0(permission, "reliable-write"))
542 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
543 else if (!g_strcmp0(permission, "writable-auxiliaries"))
544 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
545 else if (!g_strcmp0(permission, "encrypt-read"))
546 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
547 else if (!g_strcmp0(permission, "encrypt-write"))
548 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
549 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
550 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
551 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
552 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
557 static void __convert_permission_flag_to_str(unsigned int permission)
559 char perm[200] = { 0, };
561 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
562 g_strlcat(perm, "broadcast ", sizeof(perm));
563 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
564 g_strlcat(perm, "read ", sizeof(perm));
565 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
566 g_strlcat(perm, "write-without-response ", sizeof(perm));
567 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
568 g_strlcat(perm, "write ", sizeof(perm));
569 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
570 g_strlcat(perm, "notify ", sizeof(perm));
571 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
572 g_strlcat(perm, "indicate ", sizeof(perm));
573 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
574 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
575 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
576 g_strlcat(perm, "reliable-write ", sizeof(perm));
577 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
578 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
579 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
580 g_strlcat(perm, "encrypt-read ", sizeof(perm));
581 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
582 g_strlcat(perm, "encrypt-write ", sizeof(perm));
583 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
584 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
585 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
586 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
588 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
592 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
593 const char *char_handle, bt_gatt_char_property_t *characteristic)
595 GDBusProxy *properties_proxy = NULL;
596 GError *error = NULL;
597 GVariant *value = NULL;
598 GVariant *result = NULL;
599 GByteArray *gb_array = NULL;
600 GPtrArray *gp_array = NULL ;
601 GDBusConnection *g_conn;
605 char *char_desc_handle = NULL;
607 GVariantIter *property_iter;
608 GVariantIter *char_value_iter;
609 GVariantIter *char_perm_iter;
610 GVariantIter *char_desc_iter;
612 BT_CHECK_PARAMETER(char_handle, return);
613 BT_CHECK_PARAMETER(characteristic, return);
615 BT_CHECK_ENABLED(return);
617 g_conn = _bt_gdbus_get_system_gconn();
618 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
620 properties_proxy = g_dbus_proxy_new_sync(g_conn,
621 G_DBUS_PROXY_FLAGS_NONE, NULL,
624 BT_PROPERTIES_INTERFACE,
627 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
629 result = g_dbus_proxy_call_sync(properties_proxy,
631 g_variant_new("(s)", GATT_CHAR_INTERFACE),
632 G_DBUS_CALL_FLAGS_NONE,
639 BT_ERR("Fail to get properties (Error: %s)", error->message);
640 g_clear_error(&error);
642 BT_ERR("Fail to get properties");
643 g_object_unref(properties_proxy);
644 return BLUETOOTH_ERROR_INTERNAL;
647 g_variant_get(result, "(a{sv})", &property_iter);
649 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
650 characteristic->handle = g_strdup(char_handle);
652 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
653 if (!g_strcmp0(key, "UUID")) {
655 characteristic->uuid = g_variant_dup_string(value, &len);
656 bluetooth_get_uuid_name(characteristic->uuid, &name);
657 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
659 } else if (!g_strcmp0(key, "Value")) {
660 gb_array = g_byte_array_new();
661 g_variant_get(value, "ay", &char_value_iter);
662 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
663 // BT_DBG("value of char = %d",char_value);
664 g_byte_array_append(gb_array, &char_value, 1);
666 g_variant_iter_free(char_value_iter);
668 if (gb_array->len != 0) {
669 characteristic->val = g_malloc0(gb_array->len *
670 sizeof(unsigned char));
671 memcpy(characteristic->val, gb_array->data, gb_array->len);
673 characteristic->val_len = gb_array->len;
674 g_byte_array_free(gb_array, TRUE);
675 } else if (!g_strcmp0(key, "Flags")) {
676 g_variant_get(value, "as", &char_perm_iter);
677 characteristic->permission = 0x00;
679 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
680 characteristic->permission |= __get_permission_flag(permission);
681 __convert_permission_flag_to_str(characteristic->permission);
683 g_variant_iter_free(char_perm_iter);
684 } else if (!g_strcmp0(key, "Descriptors")) {
685 g_variant_get(value, "ao", &char_desc_iter);
686 gp_array = g_ptr_array_new();
687 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
688 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
690 g_variant_iter_free(char_desc_iter);
691 if (gp_array->len != 0) {
692 characteristic->char_desc_handle.count = gp_array->len;
693 characteristic->char_desc_handle.handle =
694 __get_string_array_from_gptr_array(gp_array);
696 g_ptr_array_free(gp_array, TRUE);
700 g_variant_iter_free(property_iter);
701 g_variant_unref(result);
702 g_object_unref(properties_proxy);
704 return BLUETOOTH_ERROR_NONE;
707 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
708 GAsyncResult *res, gpointer user_data)
711 GVariantIter *char_iter;
713 GError *error = NULL;
714 bt_user_info_t *user_info;
715 int ret = BLUETOOTH_ERROR_INTERNAL;
716 bt_gatt_char_property_t characteristic;
718 user_info = _bt_get_user_data(BT_COMMON);
720 value = g_dbus_proxy_call_finish(proxy, res, &error);
724 BT_ERR("Get service characteristics failed\n errCode[%x],"
725 "message[%s]\n", error->code, error->message);
726 g_clear_error(&error);
728 BT_ERR("Get service characteristics failed\n");
731 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
732 BLUETOOTH_ERROR_INTERNAL, NULL,
733 user_info->cb, user_info->user_data);
735 g_object_unref(proxy);
740 g_variant_get(value, "(ao)", &char_iter);
742 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
745 ret = bluetooth_gatt_get_characteristics_property(char_handle,
748 if (ret != BLUETOOTH_ERROR_NONE) {
749 BT_ERR("Get characteristic property failed(0x%08x)", ret);
751 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
752 ret = BLUETOOTH_ERROR_NONE;
756 bluetooth_gatt_free_char_property(&characteristic);
760 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
761 &characteristic, user_info->cb, user_info->user_data);
764 bluetooth_gatt_free_char_property(&characteristic);
765 g_variant_iter_free(char_iter);
766 g_variant_unref(value);
770 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
771 const char *char_uuid)
773 GDBusProxy *properties_proxy = NULL;
774 GDBusConnection *g_conn;
775 GError *error = NULL;
778 BT_CHECK_PARAMETER(service_handle, return);
779 BT_CHECK_PARAMETER(char_uuid, return);
780 BT_CHECK_ENABLED(return);
782 g_conn = _bt_gdbus_get_system_gconn();
783 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
785 properties_proxy = g_dbus_proxy_new_sync(g_conn,
786 G_DBUS_PROXY_FLAGS_NONE, NULL,
789 BT_PROPERTIES_INTERFACE,
792 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
794 uuid = g_strdup(char_uuid);
795 g_dbus_proxy_call(properties_proxy,
797 g_variant_new("(ss)",
798 GATT_SERV_INTERFACE, "Characteristics"),
799 G_DBUS_CALL_FLAGS_NONE,
802 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
805 return BLUETOOTH_ERROR_NONE;
808 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
809 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
811 GDBusProxy *properties_proxy = NULL;
812 GError *error = NULL;
813 GDBusConnection *g_conn;
814 GVariant *result = NULL;
815 GVariantIter *property_iter;
819 GVariant *value = NULL;
820 GByteArray *gb_array = NULL;
821 GVariantIter *desc_value_iter;
823 BT_CHECK_PARAMETER(descriptor_handle, return);
824 BT_CHECK_PARAMETER(descriptor, return);
826 BT_CHECK_ENABLED(return);
828 g_conn = _bt_gdbus_get_system_gconn();
829 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
831 properties_proxy = g_dbus_proxy_new_sync(g_conn,
832 G_DBUS_PROXY_FLAGS_NONE, NULL,
835 BT_PROPERTIES_INTERFACE,
838 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
840 result = g_dbus_proxy_call_sync(properties_proxy,
842 g_variant_new("(s)", GATT_DESC_INTERFACE),
843 G_DBUS_CALL_FLAGS_NONE,
850 BT_ERR("Fail to get properties (Error: %s)", error->message);
851 g_clear_error(&error);
853 BT_ERR("Fail to get properties");
854 g_object_unref(properties_proxy);
855 return BLUETOOTH_ERROR_INTERNAL;
858 g_variant_get(result, "(a{sv})", &property_iter);
860 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
861 descriptor->handle = g_strdup(descriptor_handle);
863 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
864 if (!g_strcmp0(key, "UUID")) {
866 descriptor->uuid = g_variant_dup_string(value, &len);
867 bluetooth_get_uuid_name(descriptor->uuid, &name);
868 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
870 } else if (!g_strcmp0(key, "Value")) {
871 gb_array = g_byte_array_new();
872 g_variant_get(value, "ay", &desc_value_iter);
873 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
874 BT_DBG("value of descriptor = %d", char_value);
875 g_byte_array_append(gb_array, &char_value, 1);
877 g_variant_iter_free(desc_value_iter);
879 if (gb_array->len != 0) {
880 descriptor->val = g_malloc0(gb_array->len *
881 sizeof(unsigned char));
882 memcpy(descriptor->val, gb_array->data, gb_array->len);
884 descriptor->val_len = gb_array->len;
885 g_byte_array_free(gb_array, TRUE);
889 g_variant_iter_free(property_iter);
890 g_variant_unref(result);
891 g_object_unref(properties_proxy);
893 return BLUETOOTH_ERROR_NONE;
896 static int __bluetooth_get_att_error_code(GError *error)
902 BT_ERR("Error : %s", error->message);
903 str = g_strrstr(error->message, "ATT error: 0x");
906 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
907 att_ecode += g_ascii_xdigit_value(str[len - 1]);
909 return BLUETOOTH_ATT_ERROR_INTERNAL;
912 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
913 BT_ERR("Read not permitted");
915 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
916 BT_ERR("Write not permitted");
918 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
919 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
920 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
921 BT_ERR("Not paired");
923 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
924 BT_ERR("Invalid offset");
926 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
927 BT_ERR("Invalid Length");
929 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
930 BT_ERR("Operation not Authorized");
934 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
935 BT_ERR("Application error");
940 static void __bluetooth_internal_read_cb(GObject *source_object,
941 GAsyncResult *res, gpointer user_data)
943 GError *error = NULL;
944 GDBusConnection *system_gconn = NULL;
946 bt_user_info_t *user_info;
948 GByteArray *gp_byte_array = NULL;
951 bt_gatt_resp_data_t *resp_data = user_data;
955 system_gconn = _bt_gdbus_get_system_gconn();
956 value = g_dbus_connection_call_finish(system_gconn, res, &error);
958 user_info = _bt_get_user_data(BT_COMMON);
962 BT_ERR("Error : %s", error->message);
963 g_clear_error(&error);
966 g_variant_unref(value);
971 att_ecode = __bluetooth_get_att_error_code(error);
972 g_clear_error(&error);
974 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
975 att_ecode, resp_data,
976 user_info->cb, user_info->user_data);
981 gp_byte_array = g_byte_array_new();
982 g_variant_get(value, "(ay)", &iter);
984 while (g_variant_iter_loop(iter, "y", &g_byte))
985 g_byte_array_append(gp_byte_array, &g_byte, 1);
987 if (gp_byte_array->len != 0) {
988 resp_data->len = gp_byte_array->len;
989 resp_data->value = gp_byte_array->data;
992 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
993 BLUETOOTH_ATT_ERROR_NONE, resp_data,
994 user_info->cb, user_info->user_data);
997 g_byte_array_free(gp_byte_array, TRUE);
998 g_variant_iter_free(iter);
999 g_variant_unref(value);
1004 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1007 GDBusConnection *conn;
1008 bt_gatt_resp_data_t *resp_data;
1009 GVariantBuilder *builder = NULL;
1012 BT_CHECK_PARAMETER(chr, return);
1013 BT_CHECK_ENABLED(return);
1015 conn = _bt_gdbus_get_system_gconn();
1016 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1018 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1019 resp_data->user_data = user_data;
1021 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1024 g_variant_builder_add(builder, "{sv}", "offset",
1025 g_variant_new("q", offset));
1027 /* Device Object path*/
1028 // g_variant_builder_add(builder, "{sv}", "device",
1029 // g_variant_new_object("o", NULL));
1031 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1032 "ReadValue", g_variant_new("(a{sv})", builder),
1033 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1034 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1035 (gpointer)resp_data);
1036 g_variant_builder_unref(builder);
1038 return BLUETOOTH_ERROR_NONE;
1041 static void __bluetooth_internal_write_cb(GObject *source_object,
1042 GAsyncResult *res, gpointer user_data)
1044 GError *error = NULL;
1045 GDBusConnection *system_gconn = NULL;
1046 bt_user_info_t *user_info;
1049 bt_gatt_resp_data_t *resp_data = user_data;
1051 system_gconn = _bt_gdbus_get_system_gconn();
1052 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1054 user_info = _bt_get_user_data(BT_COMMON);
1058 BT_ERR("Error : %s", error->message);
1059 g_clear_error(&error);
1062 g_variant_unref(value);
1067 att_ecode = __bluetooth_get_att_error_code(error);
1068 g_clear_error(&error);
1070 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1071 att_ecode, resp_data,
1072 user_info->cb, user_info->user_data);
1077 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1078 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1079 user_info->cb, user_info->user_data);
1082 g_variant_unref(value);
1086 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1087 const char *char_handle, const guint8 *value, int length)
1089 GVariant *val, *options;
1090 GVariantBuilder *builder1;
1091 GVariantBuilder *builder2;
1092 GError *error = NULL;
1093 GDBusConnection *conn;
1098 BT_CHECK_PARAMETER(char_handle, return);
1099 BT_CHECK_PARAMETER(value, return);
1100 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1101 BT_CHECK_ENABLED(return);
1103 conn = _bt_gdbus_get_system_gconn();
1104 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1106 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1107 for (i = 0; i < length; i++)
1108 g_variant_builder_add(builder1, "y", value[i]);
1110 val = g_variant_new("ay", builder1);
1112 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1114 g_variant_builder_add(builder2, "{sv}", "offset",
1115 g_variant_new_uint16(offset));
1117 /* Device Object path*/
1118 // g_variant_builder_add(builder2, "{sv}", "device",
1119 // g_variant_new_object("o", NULL));
1121 options = g_variant_new("a{sv}", builder2);
1123 g_dbus_connection_call(conn,
1126 GATT_CHAR_INTERFACE,
1128 g_variant_new("(@ay@a{sv})",
1131 G_DBUS_CALL_FLAGS_NONE,
1133 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1138 BT_ERR("Set value Failed: %s", error->message);
1139 g_clear_error(&error);
1140 g_variant_builder_unref(builder1);
1141 return BLUETOOTH_ERROR_INTERNAL;
1143 g_variant_builder_unref(builder1);
1144 g_variant_builder_unref(builder2);
1147 return BLUETOOTH_ERROR_NONE;
1150 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1151 const char *chr, const guint8 *value, int length,
1152 guint8 write_type, gpointer user_data)
1154 GVariant *val, *options;
1155 GVariantBuilder *builder1;
1156 GVariantBuilder *builder2;
1157 GDBusConnection *conn;
1160 int ret = BLUETOOTH_ERROR_NONE;
1161 bt_gatt_resp_data_t *resp_data;
1163 BT_CHECK_PARAMETER(chr, return);
1164 BT_CHECK_PARAMETER(value, return);
1165 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1166 BT_CHECK_ENABLED_INTERNAL(return);
1168 conn = _bt_gdbus_get_system_gconn();
1169 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1171 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1173 for (i = 0; i < length; i++)
1174 g_variant_builder_add(builder1, "y", value[i]);
1176 val = g_variant_new("ay", builder1);
1178 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1180 g_variant_builder_add(builder2, "{sv}", "offset",
1181 g_variant_new_uint16(offset));
1183 /* Device Object path*/
1184 // g_variant_builder_add(builder2, "{sv}", "device",
1185 // g_variant_new_object("o", NULL));
1187 options = g_variant_new("a{sv}", builder2);
1189 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1190 resp_data->user_data = user_data;
1192 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1194 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1196 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1197 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1198 (gpointer)resp_data);
1200 g_variant_builder_unref(builder1);
1201 g_variant_builder_unref(builder2);
1206 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1207 const char *char_handle, const guint8 *value, int length)
1209 GVariant *val, *options;
1210 GDBusConnection *conn;
1211 GVariantBuilder *builder1;
1212 GVariantBuilder *builder2;
1217 BT_CHECK_PARAMETER(char_handle, return);
1218 BT_CHECK_PARAMETER(value, return);
1219 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1220 BT_CHECK_ENABLED(return);
1222 conn = _bt_gdbus_get_system_gconn();
1223 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1225 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1227 for (i = 0; i < length; i++) {
1228 g_variant_builder_add(builder1, "y", value[i]);
1229 BT_DBG("value [] = %d", value[i]);
1232 val = g_variant_new("ay", builder1);
1234 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1236 g_variant_builder_add(builder2, "{sv}", "offset",
1237 g_variant_new_uint16(offset));
1239 /* Device Object path*/
1240 // g_variant_builder_add(builder2, "{sv}", "device",
1241 // g_variant_new_object("o", NULL));
1243 options = g_variant_new("a{sv}", builder2);
1245 g_dbus_connection_call(conn,
1248 GATT_CHAR_INTERFACE,
1250 g_variant_new("(@ay@a{sv})",
1253 G_DBUS_CALL_FLAGS_NONE,
1255 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1258 g_variant_builder_unref(builder1);
1259 g_variant_builder_unref(builder2);
1262 return BLUETOOTH_ERROR_NONE;
1265 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1266 bt_gatt_char_property_t *characteristic)
1269 GDBusProxy *properties_proxy = NULL;
1270 GError *error = NULL;
1271 GVariant *value = NULL;
1272 GVariant *result = NULL;
1273 GDBusConnection *g_conn;
1274 int i, ret = BLUETOOTH_ERROR_NONE;
1275 const char *uuid = NULL;
1277 GVariantIter *desc_value_iter, *property_iter;
1279 char_descriptor_type_t desc_type = TYPE_NONE;
1281 g_conn = _bt_gdbus_get_system_gconn();
1282 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1284 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1285 G_DBUS_PROXY_FLAGS_NONE, NULL,
1288 BT_PROPERTIES_INTERFACE,
1291 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1293 result = g_dbus_proxy_call_sync(properties_proxy,
1295 g_variant_new("(s)", GATT_DESC_INTERFACE),
1296 G_DBUS_CALL_FLAGS_NONE,
1302 if (error != NULL) {
1303 BT_ERR("Fail to get properties (Error: %s)", error->message);
1304 g_clear_error(&error);
1306 BT_ERR("Fail to get properties");
1307 g_object_unref(properties_proxy);
1308 return BLUETOOTH_ERROR_INTERNAL;
1310 g_variant_get(result, "(a{sv})", &property_iter);
1311 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1312 if (!g_strcmp0(key, "UUID")) {
1313 uuid = g_variant_get_string(value, &len);
1314 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1315 BT_DBG("GATT_USER_DESC_UUID");
1316 desc_type = USER_DESC;
1317 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1318 BT_DBG("GATT_CHAR_FORMAT");
1319 desc_type = CHAR_FORMAT;
1320 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1321 BT_DBG("GATT_CHAR_CLIENT_CONF");
1322 desc_type = CLIENT_CONF;
1323 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1324 BT_DBG("GATT_CHAR_SERVER_CONF");
1325 desc_type = SERVER_CONF;
1327 BT_DBG("descriptor uuid = %s", uuid);
1329 } else if (!g_strcmp0(key, "Value")) {
1330 switch (desc_type) {
1332 BT_DBG("Format descriptor");
1333 g_variant_get(value, "(yyqyq)",
1334 &(characteristic->format.format),
1335 &(characteristic->format.exponent),
1336 &(characteristic->format.unit),
1337 &(characteristic->format.name_space),
1338 &(characteristic->format.description));
1341 BT_DBG("User descriptor");
1342 g_variant_get(value, "ay", &desc_value_iter);
1343 len = g_variant_get_size((GVariant *)desc_value_iter);
1346 characteristic->description = (char *)g_malloc0(len + 1);
1348 for (i = 0; i < len; i++) {
1349 g_variant_iter_loop(desc_value_iter, "y",
1350 &characteristic->description[i]);
1351 BT_DBG("description = %s", characteristic->description);
1353 g_variant_iter_free(desc_value_iter);
1356 BT_DBG(" CLIENT_CONF");
1359 BT_DBG(" SERVER_CONF");
1367 g_variant_iter_free(property_iter);
1368 g_variant_unref(result);
1369 g_object_unref(properties_proxy);
1376 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1377 GAsyncResult *res, gpointer user_data)
1381 GVariant *char_value;
1382 GVariantIter *char_iter;
1384 GError *error = NULL;
1385 bt_user_info_t *user_info;
1386 bt_gatt_char_property_t characteristic = {0, };
1387 int ret = BLUETOOTH_ERROR_INTERNAL;
1389 user_info = _bt_get_user_data(BT_COMMON);
1391 value = g_dbus_proxy_call_finish(proxy, res, &error);
1392 characteristic.handle = user_data;
1394 if (value == NULL) {
1395 if (error != NULL) {
1396 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1397 "message[%s]\n", error->code, error->message);
1398 g_clear_error(&error);
1400 BT_ERR("Get characteristic descriptor failed\n");
1403 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1404 BLUETOOTH_ERROR_INTERNAL, NULL,
1405 user_info->cb, user_info->user_data);
1407 g_free(characteristic.handle);
1408 g_object_unref(proxy);
1412 g_variant_get(value, "(v)", &char_value);
1413 g_variant_get(char_value, "ao", &char_iter);
1415 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1416 BT_DBG("object path of descriptor = %s", char_handle);
1418 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1420 BT_DBG("Descriptor read status [%d]", ret);
1425 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1426 ret, &characteristic, user_info->cb, user_info->user_data);
1428 bluetooth_gatt_free_char_property(&characteristic);
1430 g_free(characteristic.handle);
1431 g_variant_iter_free(char_iter);
1432 g_variant_unref(value);
1436 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1437 const char *characteristic_handle)
1439 GDBusProxy *properties_proxy = NULL;
1440 GDBusConnection *g_conn;
1442 GError *error = NULL;
1444 BT_CHECK_PARAMETER(characteristic_handle, return);
1445 BT_CHECK_ENABLED(return);
1447 g_conn = _bt_gdbus_get_system_gconn();
1448 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1450 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1451 G_DBUS_PROXY_FLAGS_NONE, NULL,
1453 characteristic_handle,
1454 BT_PROPERTIES_INTERFACE,
1457 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1459 handle = g_strdup(characteristic_handle);
1460 g_dbus_proxy_call(properties_proxy,
1462 g_variant_new("(ss)",
1463 GATT_CHAR_INTERFACE, "Descriptors"),
1464 G_DBUS_CALL_FLAGS_NONE,
1466 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1469 return BLUETOOTH_ERROR_NONE;
1472 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1476 GError *error = NULL;
1477 GDBusConnection *system_gconn = NULL;
1479 bt_user_info_t *user_info;
1480 GByteArray *gp_byte_array = NULL;
1484 bt_gatt_resp_data_t *resp_data = user_data;
1488 system_gconn = _bt_gdbus_get_system_gconn();
1489 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1491 user_info = _bt_get_user_data(BT_COMMON);
1495 BT_ERR("Error : %s", error->message);
1496 g_clear_error(&error);
1499 g_variant_unref(value);
1504 att_ecode = __bluetooth_get_att_error_code(error);
1505 g_clear_error(&error);
1507 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1508 att_ecode, resp_data,
1509 user_info->cb, user_info->user_data);
1514 gp_byte_array = g_byte_array_new();
1515 g_variant_get(value, "(ay)", &iter);
1517 while (g_variant_iter_loop(iter, "y", &g_byte))
1518 g_byte_array_append(gp_byte_array, &g_byte, 1);
1520 if (gp_byte_array->len != 0) {
1521 resp_data->len = gp_byte_array->len;
1522 resp_data->value = gp_byte_array->data;
1525 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1526 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1527 user_info->cb, user_info->user_data);
1531 g_byte_array_free(gp_byte_array, TRUE);
1532 g_variant_iter_free(iter);
1533 g_variant_unref(value);
1538 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1541 GDBusConnection *conn;
1542 GVariantBuilder *builder;
1544 bt_gatt_resp_data_t *resp_data;
1548 BT_CHECK_PARAMETER(desc, return);
1549 BT_CHECK_ENABLED(return);
1551 conn = _bt_gdbus_get_system_gconn();
1552 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1554 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1555 resp_data->user_data = user_data;
1557 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1560 g_variant_builder_add(builder, "{sv}", "offset",
1561 g_variant_new("q", offset));
1562 /* Device Object path*/
1563 // g_variant_builder_add(builder, "{sv}", "device",
1564 // g_variant_new("o", serv_info->serv_path));
1566 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1567 "ReadValue", g_variant_new("(a{sv})", builder),
1568 G_VARIANT_TYPE("(ay)"),
1569 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1570 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1571 (gpointer)resp_data);
1572 g_variant_builder_unref(builder);
1575 return BLUETOOTH_ERROR_NONE;
1578 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1579 GAsyncResult *res, gpointer user_data)
1581 GError *error = NULL;
1582 bt_user_info_t *user_info;
1583 GDBusConnection *system_gconn = NULL;
1585 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1586 bt_gatt_resp_data_t *resp_data = user_data;
1590 system_gconn = _bt_gdbus_get_system_gconn();
1591 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1593 user_info = _bt_get_user_data(BT_COMMON);
1597 BT_ERR("Error : %s", error->message);
1598 g_clear_error(&error);
1601 g_variant_unref(value);
1606 att_ecode = __bluetooth_get_att_error_code(error);
1607 g_clear_error(&error);
1609 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1610 att_ecode, resp_data,
1611 user_info->cb, user_info->user_data);
1616 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1617 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1618 user_info->cb, user_info->user_data);
1621 g_variant_unref(value);
1625 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1626 const guint8 *value, int length, gpointer user_data)
1628 GVariant *val, *options;
1629 GDBusConnection *conn;
1630 GVariantBuilder *builder1;
1631 GVariantBuilder *builder2;
1634 bt_gatt_resp_data_t *resp_data;
1638 BT_CHECK_PARAMETER(desc, return);
1639 BT_CHECK_PARAMETER(value, return);
1640 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1641 BT_CHECK_ENABLED(return);
1643 conn = _bt_gdbus_get_system_gconn();
1644 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1646 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1648 for (i = 0; i < length; i++)
1649 g_variant_builder_add(builder1, "y", value[i]);
1651 val = g_variant_new("ay", builder1);
1653 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1655 g_variant_builder_add(builder2, "{sv}", "offset",
1656 g_variant_new_uint16(offset));
1658 /* Device Object path*/
1659 // g_variant_builder_add(builder2, "{sv}", "device",
1660 // g_variant_new_object("o", NULL));
1662 options = g_variant_new("a{sv}", builder2);
1664 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1665 resp_data->user_data = user_data;
1667 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1668 "WriteValue", g_variant_new("(@ay@a{sv})",
1669 val, options), NULL,
1670 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1671 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1672 (gpointer)resp_data);
1674 g_variant_builder_unref(builder1);
1675 g_variant_builder_unref(builder2);
1678 return BLUETOOTH_ERROR_NONE;
1681 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1683 GDBusConnection *conn;
1684 GError *error = NULL;
1685 int ret = BLUETOOTH_ERROR_NONE;
1687 BT_CHECK_PARAMETER(char_handle, return);
1688 BT_CHECK_ENABLED(return);
1690 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
1692 conn = _bt_gdbus_get_system_gconn();
1693 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1695 g_dbus_connection_call_sync(conn,
1698 GATT_CHAR_INTERFACE,
1702 G_DBUS_CALL_FLAGS_NONE,
1703 GATT_DEFAULT_TIMEOUT, NULL, &error);
1706 g_dbus_error_strip_remote_error(error);
1707 BT_ERR_C("### Watch Failed: %s", error->message);
1708 if (g_strrstr(error->message, "Already notifying"))
1709 ret = BLUETOOTH_ERROR_NONE;
1710 else if (g_strrstr(error->message, "In Progress"))
1711 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1712 else if (g_strrstr(error->message, "Operation is not supported"))
1713 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1714 /*failed because of either Insufficient Authorization or Write Not Permitted */
1715 else if (g_strrstr(error->message, "Write not permitted") ||
1716 g_strrstr(error->message, "Operation Not Authorized"))
1717 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1718 /* failed because of either Insufficient Authentication,
1719 Insufficient Encryption Key Size, or Insufficient Encryption. */
1720 else if (g_strrstr(error->message, "Not paired"))
1721 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1723 ret = BLUETOOTH_ERROR_INTERNAL;
1725 g_clear_error(&error);
1731 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1734 GDBusConnection *conn;
1735 GError *error = NULL;
1736 int ret = BLUETOOTH_ERROR_NONE;
1737 BT_CHECK_PARAMETER(char_handle, return);
1739 BT_CHECK_ENABLED(return);
1741 BT_INFO("Disable CCCD : %s", char_handle);
1743 conn = _bt_gdbus_get_system_gconn();
1744 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1746 g_dbus_connection_call_sync(conn,
1749 GATT_CHAR_INTERFACE,
1753 G_DBUS_CALL_FLAGS_NONE,
1754 GATT_DEFAULT_TIMEOUT, NULL, &error);
1757 BT_ERR("Watch Failed: %s", error->message);
1758 g_clear_error(&error);
1759 ret = BLUETOOTH_ERROR_INTERNAL;