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 device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
128 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
130 _bt_convert_addr_type_to_string(device_address,
131 (unsigned char *)address->addr);
132 _bt_convert_addr_string_to_secure_string(secure_address,
134 BT_INFO("Set watcher for %s with %d", secure_address, enable);
136 if (enable == TRUE) {
137 if (service_monitor_list == NULL)
138 _bt_register_manager_subscribe_signal(TRUE);
140 if (_bluetooth_gatt_check_service_change_watcher_address(address)
142 BT_INFO("The watcher is already set");
143 return BLUETOOTH_ERROR_NONE;
145 addr = g_malloc0(sizeof(bluetooth_device_address_t));
146 memcpy(addr, address, sizeof(bluetooth_device_address_t));
148 service_monitor_list =
149 g_slist_append(service_monitor_list, addr);
152 for (l = service_monitor_list; l != NULL; l = l->next) {
154 if (!memcmp(address, addr,
155 sizeof(bluetooth_device_address_t))) {
156 service_monitor_list =
157 g_slist_remove(service_monitor_list, addr);
163 if (service_monitor_list == NULL)
164 _bt_register_manager_subscribe_signal(FALSE);
167 return BLUETOOTH_ERROR_NONE;
170 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
171 bt_gatt_service_property_t *service)
173 GDBusProxy *properties_proxy = NULL;
174 GError *error = NULL;
175 GVariant *result = NULL;
176 GDBusConnection *g_conn;
178 char *char_handle = NULL;
179 GPtrArray *gp_array = NULL ;
180 GVariantIter *property_iter, *char_iter = NULL;
184 BT_CHECK_PARAMETER(service_handle, return);
185 BT_CHECK_PARAMETER(service, return);
186 BT_CHECK_ENABLED(return);
188 g_conn = _bt_gdbus_get_system_gconn();
189 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
191 properties_proxy = g_dbus_proxy_new_sync(g_conn,
192 G_DBUS_PROXY_FLAGS_NONE, NULL,
195 BT_PROPERTIES_INTERFACE,
198 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
200 result = g_dbus_proxy_call_sync(properties_proxy,
202 g_variant_new("(s)", GATT_SERV_INTERFACE),
203 G_DBUS_CALL_FLAGS_NONE,
210 BT_ERR("Fail to get properties (Error: %s)", error->message);
211 g_clear_error(&error);
213 BT_ERR("Fail to get properties");
214 g_object_unref(properties_proxy);
215 return BLUETOOTH_ERROR_INTERNAL;
218 g_variant_get(result, "(a{sv})", &property_iter);
220 memset(service, 0, sizeof(bt_gatt_service_property_t));
222 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
223 if (!g_strcmp0(key, "UUID")) {
225 service->uuid = g_variant_dup_string(value, &len);
226 bluetooth_get_uuid_name(service->uuid, &name);
227 BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
229 } else if (!g_strcmp0(key, "Primary")) {
230 service->primary = g_variant_get_boolean(value);
232 } else if (!g_strcmp0(key, "Includes")) {
233 g_variant_get(value, "ao", &char_iter);
234 gp_array = g_ptr_array_new();
235 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
236 g_ptr_array_add(gp_array, (gpointer)char_handle);
238 if (gp_array->len != 0) {
239 service->include_handles.count = gp_array->len;
240 service->include_handles.handle =
241 __get_string_array_from_gptr_array(gp_array);
243 g_ptr_array_free(gp_array, TRUE);
244 g_variant_iter_free(char_iter);
245 } else if (!g_strcmp0(key, "Characteristics")) {
246 g_variant_get(value, "ao", &char_iter);
247 gp_array = g_ptr_array_new();
248 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
249 g_ptr_array_add(gp_array, (gpointer)char_handle);
251 if (gp_array->len != 0) {
252 service->char_handle.count = gp_array->len;
253 service->char_handle.handle =
254 __get_string_array_from_gptr_array(gp_array);
256 BT_DBG("Characteristics count : %d", service->char_handle.count);
257 g_ptr_array_free(gp_array, TRUE);
258 g_variant_iter_free(char_iter);
262 service->handle = g_strdup(service_handle);
264 g_variant_iter_free(property_iter);
265 g_variant_unref(result);
266 g_object_unref(properties_proxy);
268 return BLUETOOTH_ERROR_NONE;
271 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
272 const bluetooth_device_address_t *address,
273 bt_gatt_handle_info_t *prim_svc)
275 GVariant *result = NULL;
277 GVariantIter *svc_iter;
278 GVariantIter *interface_iter;
279 char *object_path = NULL;
280 char *interface_str = NULL;
281 const gchar *key = NULL;
282 GVariant *value = NULL;
283 GPtrArray *gp_array = NULL;
284 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
285 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
286 int ret = BLUETOOTH_ERROR_INTERNAL;
290 BT_CHECK_PARAMETER(address, return);
291 BT_CHECK_PARAMETER(prim_svc, return);
292 BT_CHECK_ENABLED(return);
294 result = _bt_get_managed_objects();
298 _bt_convert_addr_type_to_string(device_address,
299 (unsigned char *)address->addr);
301 gp_array = g_ptr_array_new();
302 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
304 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
306 if (object_path == NULL)
309 _bt_convert_device_path_to_address(object_path, temp_address);
311 if (g_strcmp0(temp_address, device_address) != 0)
314 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
315 &interface_str, &svc_iter)) {
316 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
319 BT_DBG("[%d] Object Path : %s", idx++, object_path);
320 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
321 if (g_strcmp0(key, "Primary") == 0) {
322 if (g_variant_get_boolean(value))
323 g_ptr_array_add(gp_array, (gpointer)object_path);
329 if (gp_array->len == 0) {
330 BT_ERR("gp_array is NULL");
331 ret = BLUETOOTH_ERROR_NOT_FOUND;
333 ret = BLUETOOTH_ERROR_NONE;
334 prim_svc->count = gp_array->len;
335 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
338 g_ptr_array_free(gp_array, TRUE);
339 g_variant_iter_free(iter);
340 g_variant_unref(result);
345 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
346 const char *service_uuid,
347 bt_gatt_service_property_t *service)
349 GVariant *result = NULL;
351 GVariantIter *svc_iter;
352 GVariantIter *interface_iter;
353 char *object_path = NULL;
354 char *interface_str = NULL;
355 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
356 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
357 int ret = BLUETOOTH_ERROR_INTERNAL;
359 BT_CHECK_PARAMETER(address, return);
360 BT_CHECK_PARAMETER(service_uuid, return);
361 BT_CHECK_PARAMETER(service, return);
362 BT_CHECK_ENABLED(return);
364 result = _bt_get_managed_objects();
368 _bt_convert_addr_type_to_string(device_address,
369 (unsigned char *)address->addr);
371 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
373 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
375 if (object_path == NULL)
378 _bt_convert_device_path_to_address(object_path,
381 if (g_strcmp0(temp_address, device_address) != 0)
384 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
385 &interface_str, &svc_iter)) {
386 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
389 BT_DBG("Object Path: %s", object_path);
390 ret = bluetooth_gatt_get_service_property(object_path,
393 if (ret != BLUETOOTH_ERROR_NONE) {
394 BT_ERR("Get service property failed(0x%08x)", ret);
396 if (service->primary == TRUE &&
397 g_strstr_len(service->uuid, -1,
399 ret = BLUETOOTH_ERROR_NONE;
403 bluetooth_gatt_free_service_property(service);
408 g_variant_iter_free(iter);
409 g_variant_unref(result);
414 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
415 GAsyncResult *res, gpointer user_data)
418 GVariant *char_value;
419 GVariantIter *char_iter;
420 GPtrArray *gp_array = NULL;
421 bt_gatt_discovered_char_t svc_char = { 0, };
423 GError *error = NULL;
424 bt_user_info_t *user_info;
428 user_info = _bt_get_user_data(BT_COMMON);
429 svc_char.service_handle = user_data;
431 value = g_dbus_proxy_call_finish(proxy, res, &error);
435 BT_ERR("Get service characteristics failed\n errCode[%x],"
436 "message[%s]\n", error->code, error->message);
437 g_clear_error(&error);
439 BT_ERR("Get service characteristics failed\n");
442 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
443 BLUETOOTH_ERROR_INTERNAL, NULL,
444 user_info->cb, user_info->user_data);
446 g_free(svc_char.service_handle);
447 g_object_unref(proxy);
451 g_variant_get(value, "(v)", &char_value);
452 g_variant_get(char_value, "ao", &char_iter);
454 gp_array = g_ptr_array_new();
455 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
456 g_ptr_array_add(gp_array, (gpointer)char_handle);
458 if (gp_array->len != 0) {
459 svc_char.handle_info.count = gp_array->len;
460 svc_char.handle_info.handle =
461 __get_string_array_from_gptr_array(gp_array);
463 g_ptr_array_free(gp_array, TRUE);
466 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
467 BLUETOOTH_ERROR_NONE, &svc_char,
468 user_info->cb, user_info->user_data);
471 g_strfreev(svc_char.handle_info.handle);
472 g_free(svc_char.service_handle);
473 g_variant_iter_free(char_iter);
474 g_variant_unref(value);
475 g_object_unref(proxy);
478 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
479 const char *service_handle)
481 GDBusProxy *properties_proxy = NULL;
482 GDBusConnection *g_conn;
483 GError *error = NULL;
488 BT_CHECK_PARAMETER(service_handle, return);
489 BT_CHECK_ENABLED(return);
491 g_conn = _bt_gdbus_get_system_gconn();
492 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
494 properties_proxy = g_dbus_proxy_new_sync(g_conn,
495 G_DBUS_PROXY_FLAGS_NONE, NULL,
498 BT_PROPERTIES_INTERFACE,
501 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
503 handle = g_strdup(service_handle);
504 g_dbus_proxy_call(properties_proxy,
506 g_variant_new("(ss)",
507 GATT_SERV_INTERFACE, "Characteristics"),
508 G_DBUS_CALL_FLAGS_NONE,
511 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
515 return BLUETOOTH_ERROR_NONE;
519 static int __get_permission_flag(char *permission)
523 retv_if(permission == NULL, ret);
525 if (!g_strcmp0(permission, "broadcast"))
526 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
527 else if (!g_strcmp0(permission, "read"))
528 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
529 else if (!g_strcmp0(permission, "write-without-response"))
530 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
531 else if (!g_strcmp0(permission, "write"))
532 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
533 else if (!g_strcmp0(permission, "notify"))
534 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
535 else if (!g_strcmp0(permission, "indicate"))
536 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
537 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
538 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
539 else if (!g_strcmp0(permission, "reliable-write"))
540 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
541 else if (!g_strcmp0(permission, "writable-auxiliaries"))
542 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
543 else if (!g_strcmp0(permission, "encrypt-read"))
544 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
545 else if (!g_strcmp0(permission, "encrypt-write"))
546 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
547 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
548 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
549 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
550 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
555 static void __convert_permission_flag_to_str(unsigned int permission)
557 char perm[200] = { 0, };
559 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
560 g_strlcat(perm, "broadcast ", sizeof(perm));
561 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
562 g_strlcat(perm, "read ", sizeof(perm));
563 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
564 g_strlcat(perm, "write-without-response ", sizeof(perm));
565 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
566 g_strlcat(perm, "write ", sizeof(perm));
567 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
568 g_strlcat(perm, "notify ", sizeof(perm));
569 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
570 g_strlcat(perm, "indicate ", sizeof(perm));
571 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
572 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
573 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
574 g_strlcat(perm, "reliable-write ", sizeof(perm));
575 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
576 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
577 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
578 g_strlcat(perm, "encrypt-read ", sizeof(perm));
579 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
580 g_strlcat(perm, "encrypt-write ", sizeof(perm));
581 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
582 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
583 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
584 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
586 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
590 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
591 const char *char_handle, bt_gatt_char_property_t *characteristic)
593 GDBusProxy *properties_proxy = NULL;
594 GError *error = NULL;
595 GVariant *value = NULL;
596 GVariant *result = NULL;
597 GByteArray *gb_array = NULL;
598 GPtrArray *gp_array = NULL ;
599 GDBusConnection *g_conn;
603 char *char_desc_handle = NULL;
605 GVariantIter *property_iter;
606 GVariantIter *char_value_iter;
607 GVariantIter *char_perm_iter;
608 GVariantIter *char_desc_iter;
610 BT_CHECK_PARAMETER(char_handle, return);
611 BT_CHECK_PARAMETER(characteristic, return);
613 BT_CHECK_ENABLED(return);
615 g_conn = _bt_gdbus_get_system_gconn();
616 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
618 properties_proxy = g_dbus_proxy_new_sync(g_conn,
619 G_DBUS_PROXY_FLAGS_NONE, NULL,
622 BT_PROPERTIES_INTERFACE,
625 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
627 result = g_dbus_proxy_call_sync(properties_proxy,
629 g_variant_new("(s)", GATT_CHAR_INTERFACE),
630 G_DBUS_CALL_FLAGS_NONE,
637 BT_ERR("Fail to get properties (Error: %s)", error->message);
638 g_clear_error(&error);
640 BT_ERR("Fail to get properties");
641 g_object_unref(properties_proxy);
642 return BLUETOOTH_ERROR_INTERNAL;
645 g_variant_get(result, "(a{sv})", &property_iter);
647 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
648 characteristic->handle = g_strdup(char_handle);
650 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
651 if (!g_strcmp0(key, "UUID")) {
653 characteristic->uuid = g_variant_dup_string(value, &len);
654 bluetooth_get_uuid_name(characteristic->uuid, &name);
655 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
657 } else if (!g_strcmp0(key, "Value")) {
658 gb_array = g_byte_array_new();
659 g_variant_get(value, "ay", &char_value_iter);
660 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
661 // BT_DBG("value of char = %d",char_value);
662 g_byte_array_append(gb_array, &char_value, 1);
664 g_variant_iter_free(char_value_iter);
666 if (gb_array->len != 0) {
667 characteristic->val = g_malloc0(gb_array->len *
668 sizeof(unsigned char));
669 memcpy(characteristic->val, gb_array->data, gb_array->len);
671 characteristic->val_len = gb_array->len;
672 g_byte_array_free(gb_array, TRUE);
673 } else if (!g_strcmp0(key, "Flags")) {
674 g_variant_get(value, "as", &char_perm_iter);
675 characteristic->permission = 0x00;
677 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
678 characteristic->permission |= __get_permission_flag(permission);
679 __convert_permission_flag_to_str(characteristic->permission);
681 g_variant_iter_free(char_perm_iter);
682 } else if (!g_strcmp0(key, "Descriptors")) {
683 g_variant_get(value, "ao", &char_desc_iter);
684 gp_array = g_ptr_array_new();
685 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
686 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
688 g_variant_iter_free(char_desc_iter);
689 if (gp_array->len != 0) {
690 characteristic->char_desc_handle.count = gp_array->len;
691 characteristic->char_desc_handle.handle =
692 __get_string_array_from_gptr_array(gp_array);
694 g_ptr_array_free(gp_array, TRUE);
698 g_variant_iter_free(property_iter);
699 g_variant_unref(result);
700 g_object_unref(properties_proxy);
702 return BLUETOOTH_ERROR_NONE;
705 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
706 GAsyncResult *res, gpointer user_data)
709 GVariantIter *char_iter;
711 GError *error = NULL;
712 bt_user_info_t *user_info;
713 int ret = BLUETOOTH_ERROR_INTERNAL;
714 bt_gatt_char_property_t characteristic;
716 user_info = _bt_get_user_data(BT_COMMON);
718 value = g_dbus_proxy_call_finish(proxy, res, &error);
722 BT_ERR("Get service characteristics failed\n errCode[%x],"
723 "message[%s]\n", error->code, error->message);
724 g_clear_error(&error);
726 BT_ERR("Get service characteristics failed\n");
729 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
730 BLUETOOTH_ERROR_INTERNAL, NULL,
731 user_info->cb, user_info->user_data);
733 g_object_unref(proxy);
738 g_variant_get(value, "(ao)", &char_iter);
740 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
743 ret = bluetooth_gatt_get_characteristics_property(char_handle,
746 if (ret != BLUETOOTH_ERROR_NONE) {
747 BT_ERR("Get characteristic property failed(0x%08x)", ret);
749 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
750 ret = BLUETOOTH_ERROR_NONE;
754 bluetooth_gatt_free_char_property(&characteristic);
758 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
759 &characteristic, user_info->cb, user_info->user_data);
762 bluetooth_gatt_free_char_property(&characteristic);
763 g_variant_iter_free(char_iter);
764 g_variant_unref(value);
768 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
769 const char *char_uuid)
771 GDBusProxy *properties_proxy = NULL;
772 GDBusConnection *g_conn;
773 GError *error = NULL;
776 BT_CHECK_PARAMETER(service_handle, return);
777 BT_CHECK_PARAMETER(char_uuid, return);
778 BT_CHECK_ENABLED(return);
780 g_conn = _bt_gdbus_get_system_gconn();
781 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
783 properties_proxy = g_dbus_proxy_new_sync(g_conn,
784 G_DBUS_PROXY_FLAGS_NONE, NULL,
787 BT_PROPERTIES_INTERFACE,
790 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
792 uuid = g_strdup(char_uuid);
793 g_dbus_proxy_call(properties_proxy,
795 g_variant_new("(ss)",
796 GATT_SERV_INTERFACE, "Characteristics"),
797 G_DBUS_CALL_FLAGS_NONE,
800 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
803 return BLUETOOTH_ERROR_NONE;
806 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
807 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
809 GDBusProxy *properties_proxy = NULL;
810 GError *error = NULL;
811 GDBusConnection *g_conn;
812 GVariant *result = NULL;
813 GVariantIter *property_iter;
817 GVariant *value = NULL;
818 GByteArray *gb_array = NULL;
819 GVariantIter *desc_value_iter;
821 BT_CHECK_PARAMETER(descriptor_handle, return);
822 BT_CHECK_PARAMETER(descriptor, return);
824 BT_CHECK_ENABLED(return);
826 g_conn = _bt_gdbus_get_system_gconn();
827 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
829 properties_proxy = g_dbus_proxy_new_sync(g_conn,
830 G_DBUS_PROXY_FLAGS_NONE, NULL,
833 BT_PROPERTIES_INTERFACE,
836 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
838 result = g_dbus_proxy_call_sync(properties_proxy,
840 g_variant_new("(s)", GATT_DESC_INTERFACE),
841 G_DBUS_CALL_FLAGS_NONE,
848 BT_ERR("Fail to get properties (Error: %s)", error->message);
849 g_clear_error(&error);
851 BT_ERR("Fail to get properties");
852 g_object_unref(properties_proxy);
853 return BLUETOOTH_ERROR_INTERNAL;
856 g_variant_get(result, "(a{sv})", &property_iter);
858 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
859 descriptor->handle = g_strdup(descriptor_handle);
861 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
862 if (!g_strcmp0(key, "UUID")) {
864 descriptor->uuid = g_variant_dup_string(value, &len);
865 bluetooth_get_uuid_name(descriptor->uuid, &name);
866 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
868 } else if (!g_strcmp0(key, "Value")) {
869 gb_array = g_byte_array_new();
870 g_variant_get(value, "ay", &desc_value_iter);
871 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
872 BT_DBG("value of descriptor = %d", char_value);
873 g_byte_array_append(gb_array, &char_value, 1);
875 g_variant_iter_free(desc_value_iter);
877 if (gb_array->len != 0) {
878 descriptor->val = g_malloc0(gb_array->len *
879 sizeof(unsigned char));
880 memcpy(descriptor->val, gb_array->data, gb_array->len);
882 descriptor->val_len = gb_array->len;
883 g_byte_array_free(gb_array, TRUE);
887 g_variant_iter_free(property_iter);
888 g_variant_unref(result);
889 g_object_unref(properties_proxy);
891 return BLUETOOTH_ERROR_NONE;
894 static int __bluetooth_get_att_error_code(GError *error)
900 BT_ERR("Error : %s", error->message);
901 str = g_strrstr(error->message, "ATT error: 0x");
904 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
905 att_ecode += g_ascii_xdigit_value(str[len - 1]);
907 return BLUETOOTH_ATT_ERROR_INTERNAL;
910 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
911 BT_ERR("Read not permitted");
913 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
914 BT_ERR("Write not permitted");
916 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
917 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
918 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
919 BT_ERR("Not paired");
921 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
922 BT_ERR("Invalid offset");
924 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
925 BT_ERR("Invalid Length");
927 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
928 BT_ERR("Operation not Authorized");
932 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
933 BT_ERR("Application error");
938 static void __bluetooth_internal_read_cb(GObject *source_object,
939 GAsyncResult *res, gpointer user_data)
941 GError *error = NULL;
942 GDBusConnection *system_gconn = NULL;
944 bt_user_info_t *user_info;
946 GByteArray *gp_byte_array = NULL;
949 bt_gatt_resp_data_t *resp_data = user_data;
953 system_gconn = _bt_gdbus_get_system_gconn();
954 value = g_dbus_connection_call_finish(system_gconn, res, &error);
956 user_info = _bt_get_user_data(BT_COMMON);
960 BT_ERR("Error : %s", error->message);
961 g_clear_error(&error);
964 g_variant_unref(value);
969 att_ecode = __bluetooth_get_att_error_code(error);
970 g_clear_error(&error);
972 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
973 att_ecode, resp_data,
974 user_info->cb, user_info->user_data);
979 gp_byte_array = g_byte_array_new();
980 g_variant_get(value, "(ay)", &iter);
982 while (g_variant_iter_loop(iter, "y", &g_byte))
983 g_byte_array_append(gp_byte_array, &g_byte, 1);
985 if (gp_byte_array->len != 0) {
986 resp_data->len = gp_byte_array->len;
987 resp_data->value = gp_byte_array->data;
990 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
991 BLUETOOTH_ATT_ERROR_NONE, resp_data,
992 user_info->cb, user_info->user_data);
995 g_byte_array_free(gp_byte_array, TRUE);
996 g_variant_iter_free(iter);
997 g_variant_unref(value);
1002 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1005 GDBusConnection *conn;
1006 bt_gatt_resp_data_t *resp_data;
1007 GVariantBuilder *builder = NULL;
1010 BT_CHECK_PARAMETER(chr, return);
1011 BT_CHECK_ENABLED(return);
1013 conn = _bt_gdbus_get_system_gconn();
1014 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1016 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1017 resp_data->user_data = user_data;
1019 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1022 g_variant_builder_add(builder, "{sv}", "offset",
1023 g_variant_new("q", offset));
1025 /* Device Object path*/
1026 // g_variant_builder_add(builder, "{sv}", "device",
1027 // g_variant_new_object("o", NULL));
1029 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1030 "ReadValue", g_variant_new("(a{sv})", builder),
1031 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1032 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1033 (gpointer)resp_data);
1034 g_variant_builder_unref(builder);
1036 return BLUETOOTH_ERROR_NONE;
1039 static void __bluetooth_internal_write_cb(GObject *source_object,
1040 GAsyncResult *res, gpointer user_data)
1042 GError *error = NULL;
1043 GDBusConnection *system_gconn = NULL;
1044 bt_user_info_t *user_info;
1047 bt_gatt_resp_data_t *resp_data = user_data;
1049 system_gconn = _bt_gdbus_get_system_gconn();
1050 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1052 user_info = _bt_get_user_data(BT_COMMON);
1056 BT_ERR("Error : %s", error->message);
1057 g_clear_error(&error);
1060 g_variant_unref(value);
1065 att_ecode = __bluetooth_get_att_error_code(error);
1066 g_clear_error(&error);
1068 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1069 att_ecode, resp_data,
1070 user_info->cb, user_info->user_data);
1075 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1076 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1077 user_info->cb, user_info->user_data);
1080 g_variant_unref(value);
1084 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1085 const char *char_handle, const guint8 *value, int length)
1087 GVariant *val, *options;
1088 GVariantBuilder *builder1;
1089 GVariantBuilder *builder2;
1090 GError *error = NULL;
1091 GDBusConnection *conn;
1096 BT_CHECK_PARAMETER(char_handle, return);
1097 BT_CHECK_PARAMETER(value, return);
1098 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1099 BT_CHECK_ENABLED(return);
1101 conn = _bt_gdbus_get_system_gconn();
1102 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1104 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1105 for (i = 0; i < length; i++)
1106 g_variant_builder_add(builder1, "y", value[i]);
1108 val = g_variant_new("ay", builder1);
1110 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1112 g_variant_builder_add(builder2, "{sv}", "offset",
1113 g_variant_new_uint16(offset));
1115 /* Device Object path*/
1116 // g_variant_builder_add(builder2, "{sv}", "device",
1117 // g_variant_new_object("o", NULL));
1119 options = g_variant_new("a{sv}", builder2);
1121 g_dbus_connection_call(conn,
1124 GATT_CHAR_INTERFACE,
1126 g_variant_new("(@ay@a{sv})",
1129 G_DBUS_CALL_FLAGS_NONE,
1131 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1136 BT_ERR("Set value Failed: %s", error->message);
1137 g_clear_error(&error);
1138 g_variant_builder_unref(builder1);
1139 return BLUETOOTH_ERROR_INTERNAL;
1141 g_variant_builder_unref(builder1);
1142 g_variant_builder_unref(builder2);
1145 return BLUETOOTH_ERROR_NONE;
1148 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1149 const char *chr, const guint8 *value, int length,
1150 guint8 write_type, gpointer user_data)
1152 GVariant *val, *options;
1153 GVariantBuilder *builder1;
1154 GVariantBuilder *builder2;
1155 GDBusConnection *conn;
1158 int ret = BLUETOOTH_ERROR_NONE;
1159 bt_gatt_resp_data_t *resp_data;
1161 BT_CHECK_PARAMETER(chr, return);
1162 BT_CHECK_PARAMETER(value, return);
1163 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1164 BT_CHECK_ENABLED_INTERNAL(return);
1166 conn = _bt_gdbus_get_system_gconn();
1167 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1169 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1171 for (i = 0; i < length; i++)
1172 g_variant_builder_add(builder1, "y", value[i]);
1174 val = g_variant_new("ay", builder1);
1176 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1178 g_variant_builder_add(builder2, "{sv}", "offset",
1179 g_variant_new_uint16(offset));
1181 /* Device Object path*/
1182 // g_variant_builder_add(builder2, "{sv}", "device",
1183 // g_variant_new_object("o", NULL));
1185 options = g_variant_new("a{sv}", builder2);
1187 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1188 resp_data->user_data = user_data;
1190 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1192 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1194 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1195 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1196 (gpointer)resp_data);
1198 g_variant_builder_unref(builder1);
1199 g_variant_builder_unref(builder2);
1204 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1205 const char *char_handle, const guint8 *value, int length)
1207 GVariant *val, *options;
1208 GDBusConnection *conn;
1209 GVariantBuilder *builder1;
1210 GVariantBuilder *builder2;
1215 BT_CHECK_PARAMETER(char_handle, return);
1216 BT_CHECK_PARAMETER(value, return);
1217 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1218 BT_CHECK_ENABLED(return);
1220 conn = _bt_gdbus_get_system_gconn();
1221 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1223 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1225 for (i = 0; i < length; i++) {
1226 g_variant_builder_add(builder1, "y", value[i]);
1227 BT_DBG("value [] = %d", value[i]);
1230 val = g_variant_new("ay", builder1);
1232 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1234 g_variant_builder_add(builder2, "{sv}", "offset",
1235 g_variant_new_uint16(offset));
1237 /* Device Object path*/
1238 // g_variant_builder_add(builder2, "{sv}", "device",
1239 // g_variant_new_object("o", NULL));
1241 options = g_variant_new("a{sv}", builder2);
1243 g_dbus_connection_call(conn,
1246 GATT_CHAR_INTERFACE,
1248 g_variant_new("(@ay@a{sv})",
1251 G_DBUS_CALL_FLAGS_NONE,
1253 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1256 g_variant_builder_unref(builder1);
1257 g_variant_builder_unref(builder2);
1260 return BLUETOOTH_ERROR_NONE;
1263 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1264 bt_gatt_char_property_t *characteristic)
1267 GDBusProxy *properties_proxy = NULL;
1268 GError *error = NULL;
1269 GVariant *value = NULL;
1270 GVariant *result = NULL;
1271 GDBusConnection *g_conn;
1272 int i, ret = BLUETOOTH_ERROR_NONE;
1273 const char *uuid = NULL;
1275 GVariantIter *desc_value_iter, *property_iter;
1277 char_descriptor_type_t desc_type = TYPE_NONE;
1279 g_conn = _bt_gdbus_get_system_gconn();
1280 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1282 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1283 G_DBUS_PROXY_FLAGS_NONE, NULL,
1286 BT_PROPERTIES_INTERFACE,
1289 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1291 result = g_dbus_proxy_call_sync(properties_proxy,
1293 g_variant_new("(s)", GATT_DESC_INTERFACE),
1294 G_DBUS_CALL_FLAGS_NONE,
1300 if (error != NULL) {
1301 BT_ERR("Fail to get properties (Error: %s)", error->message);
1302 g_clear_error(&error);
1304 BT_ERR("Fail to get properties");
1305 g_object_unref(properties_proxy);
1306 return BLUETOOTH_ERROR_INTERNAL;
1308 g_variant_get(result, "(a{sv})", &property_iter);
1309 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1310 if (!g_strcmp0(key, "UUID")) {
1311 uuid = g_variant_get_string(value, &len);
1312 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1313 BT_DBG("GATT_USER_DESC_UUID");
1314 desc_type = USER_DESC;
1315 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1316 BT_DBG("GATT_CHAR_FORMAT");
1317 desc_type = CHAR_FORMAT;
1318 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1319 BT_DBG("GATT_CHAR_CLIENT_CONF");
1320 desc_type = CLIENT_CONF;
1321 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1322 BT_DBG("GATT_CHAR_SERVER_CONF");
1323 desc_type = SERVER_CONF;
1325 BT_DBG("descriptor uuid = %s", uuid);
1327 } else if (!g_strcmp0(key, "Value")) {
1328 switch (desc_type) {
1330 BT_DBG("Format descriptor");
1331 g_variant_get(value, "(yyqyq)",
1332 &(characteristic->format.format),
1333 &(characteristic->format.exponent),
1334 &(characteristic->format.unit),
1335 &(characteristic->format.name_space),
1336 &(characteristic->format.description));
1339 BT_DBG("User descriptor");
1340 g_variant_get(value, "ay", &desc_value_iter);
1341 len = g_variant_get_size((GVariant *)desc_value_iter);
1344 characteristic->description = (char *)g_malloc0(len + 1);
1346 for (i = 0; i < len; i++) {
1347 g_variant_iter_loop(desc_value_iter, "y",
1348 &characteristic->description[i]);
1349 BT_DBG("description = %s", characteristic->description);
1351 g_variant_iter_free(desc_value_iter);
1354 BT_DBG(" CLIENT_CONF");
1357 BT_DBG(" SERVER_CONF");
1365 g_variant_iter_free(property_iter);
1366 g_variant_unref(result);
1367 g_object_unref(properties_proxy);
1374 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1375 GAsyncResult *res, gpointer user_data)
1379 GVariant *char_value;
1380 GVariantIter *char_iter;
1382 GError *error = NULL;
1383 bt_user_info_t *user_info;
1384 bt_gatt_char_property_t characteristic = {0, };
1385 int ret = BLUETOOTH_ERROR_INTERNAL;
1387 user_info = _bt_get_user_data(BT_COMMON);
1389 value = g_dbus_proxy_call_finish(proxy, res, &error);
1390 characteristic.handle = user_data;
1392 if (value == NULL) {
1393 if (error != NULL) {
1394 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1395 "message[%s]\n", error->code, error->message);
1396 g_clear_error(&error);
1398 BT_ERR("Get characteristic descriptor failed\n");
1401 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1402 BLUETOOTH_ERROR_INTERNAL, NULL,
1403 user_info->cb, user_info->user_data);
1405 g_free(characteristic.handle);
1406 g_object_unref(proxy);
1410 g_variant_get(value, "(v)", &char_value);
1411 g_variant_get(char_value, "ao", &char_iter);
1413 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1414 BT_DBG("object path of descriptor = %s", char_handle);
1416 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1418 BT_DBG("Descriptor read status [%d]", ret);
1423 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1424 ret, &characteristic, user_info->cb, user_info->user_data);
1426 bluetooth_gatt_free_char_property(&characteristic);
1428 g_free(characteristic.handle);
1429 g_variant_iter_free(char_iter);
1430 g_variant_unref(value);
1434 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1435 const char *characteristic_handle)
1437 GDBusProxy *properties_proxy = NULL;
1438 GDBusConnection *g_conn;
1440 GError *error = NULL;
1442 BT_CHECK_PARAMETER(characteristic_handle, return);
1443 BT_CHECK_ENABLED(return);
1445 g_conn = _bt_gdbus_get_system_gconn();
1446 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1448 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1449 G_DBUS_PROXY_FLAGS_NONE, NULL,
1451 characteristic_handle,
1452 BT_PROPERTIES_INTERFACE,
1455 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1457 handle = g_strdup(characteristic_handle);
1458 g_dbus_proxy_call(properties_proxy,
1460 g_variant_new("(ss)",
1461 GATT_CHAR_INTERFACE, "Descriptors"),
1462 G_DBUS_CALL_FLAGS_NONE,
1464 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1467 return BLUETOOTH_ERROR_NONE;
1470 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1474 GError *error = NULL;
1475 GDBusConnection *system_gconn = NULL;
1477 bt_user_info_t *user_info;
1478 GByteArray *gp_byte_array = NULL;
1482 bt_gatt_resp_data_t *resp_data = user_data;
1486 system_gconn = _bt_gdbus_get_system_gconn();
1487 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1489 user_info = _bt_get_user_data(BT_COMMON);
1493 BT_ERR("Error : %s", error->message);
1494 g_clear_error(&error);
1497 g_variant_unref(value);
1502 att_ecode = __bluetooth_get_att_error_code(error);
1503 g_clear_error(&error);
1505 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1506 att_ecode, resp_data,
1507 user_info->cb, user_info->user_data);
1512 gp_byte_array = g_byte_array_new();
1513 g_variant_get(value, "(ay)", &iter);
1515 while (g_variant_iter_loop(iter, "y", &g_byte))
1516 g_byte_array_append(gp_byte_array, &g_byte, 1);
1518 if (gp_byte_array->len != 0) {
1519 resp_data->len = gp_byte_array->len;
1520 resp_data->value = gp_byte_array->data;
1523 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1524 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1525 user_info->cb, user_info->user_data);
1529 g_byte_array_free(gp_byte_array, TRUE);
1530 g_variant_iter_free(iter);
1531 g_variant_unref(value);
1536 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1539 GDBusConnection *conn;
1540 GVariantBuilder *builder;
1542 bt_gatt_resp_data_t *resp_data;
1546 BT_CHECK_PARAMETER(desc, return);
1547 BT_CHECK_ENABLED(return);
1549 conn = _bt_gdbus_get_system_gconn();
1550 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1552 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1553 resp_data->user_data = user_data;
1555 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1558 g_variant_builder_add(builder, "{sv}", "offset",
1559 g_variant_new("q", offset));
1560 /* Device Object path*/
1561 // g_variant_builder_add(builder, "{sv}", "device",
1562 // g_variant_new("o", serv_info->serv_path));
1564 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1565 "ReadValue", g_variant_new("(a{sv})", builder),
1566 G_VARIANT_TYPE("(ay)"),
1567 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1568 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1569 (gpointer)resp_data);
1570 g_variant_builder_unref(builder);
1573 return BLUETOOTH_ERROR_NONE;
1576 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1577 GAsyncResult *res, gpointer user_data)
1579 GError *error = NULL;
1580 bt_user_info_t *user_info;
1581 GDBusConnection *system_gconn = NULL;
1583 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1584 bt_gatt_resp_data_t *resp_data = user_data;
1588 system_gconn = _bt_gdbus_get_system_gconn();
1589 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1591 user_info = _bt_get_user_data(BT_COMMON);
1595 BT_ERR("Error : %s", error->message);
1596 g_clear_error(&error);
1599 g_variant_unref(value);
1604 att_ecode = __bluetooth_get_att_error_code(error);
1605 g_clear_error(&error);
1607 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1608 att_ecode, resp_data,
1609 user_info->cb, user_info->user_data);
1614 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1615 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1616 user_info->cb, user_info->user_data);
1619 g_variant_unref(value);
1623 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1624 const guint8 *value, int length, gpointer user_data)
1626 GVariant *val, *options;
1627 GDBusConnection *conn;
1628 GVariantBuilder *builder1;
1629 GVariantBuilder *builder2;
1632 bt_gatt_resp_data_t *resp_data;
1636 BT_CHECK_PARAMETER(desc, return);
1637 BT_CHECK_PARAMETER(value, return);
1638 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1639 BT_CHECK_ENABLED(return);
1641 conn = _bt_gdbus_get_system_gconn();
1642 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1644 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1646 for (i = 0; i < length; i++)
1647 g_variant_builder_add(builder1, "y", value[i]);
1649 val = g_variant_new("ay", builder1);
1651 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1653 g_variant_builder_add(builder2, "{sv}", "offset",
1654 g_variant_new_uint16(offset));
1656 /* Device Object path*/
1657 // g_variant_builder_add(builder2, "{sv}", "device",
1658 // g_variant_new_object("o", NULL));
1660 options = g_variant_new("a{sv}", builder2);
1662 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1663 resp_data->user_data = user_data;
1665 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1666 "WriteValue", g_variant_new("(@ay@a{sv})",
1667 val, options), NULL,
1668 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1669 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1670 (gpointer)resp_data);
1672 g_variant_builder_unref(builder1);
1673 g_variant_builder_unref(builder2);
1676 return BLUETOOTH_ERROR_NONE;
1679 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1681 GDBusConnection *conn;
1682 GError *error = NULL;
1683 int ret = BLUETOOTH_ERROR_NONE;
1685 BT_CHECK_PARAMETER(char_handle, return);
1686 BT_CHECK_ENABLED(return);
1688 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
1690 conn = _bt_gdbus_get_system_gconn();
1691 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1693 g_dbus_connection_call_sync(conn,
1696 GATT_CHAR_INTERFACE,
1700 G_DBUS_CALL_FLAGS_NONE,
1701 GATT_DEFAULT_TIMEOUT, NULL, &error);
1704 g_dbus_error_strip_remote_error(error);
1705 BT_ERR_C("### Watch Failed: %s", error->message);
1706 if (g_strrstr(error->message, "Already notifying"))
1707 ret = BLUETOOTH_ERROR_NONE;
1708 else if (g_strrstr(error->message, "In Progress"))
1709 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1710 else if (g_strrstr(error->message, "Operation is not supported"))
1711 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1712 /*failed because of either Insufficient Authorization or Write Not Permitted */
1713 else if (g_strrstr(error->message, "Write not permitted") ||
1714 g_strrstr(error->message, "Operation Not Authorized"))
1715 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1716 /* failed because of either Insufficient Authentication,
1717 Insufficient Encryption Key Size, or Insufficient Encryption. */
1718 else if (g_strrstr(error->message, "Not paired"))
1719 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1721 ret = BLUETOOTH_ERROR_INTERNAL;
1723 g_clear_error(&error);
1729 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1732 GDBusConnection *conn;
1733 GError *error = NULL;
1734 int ret = BLUETOOTH_ERROR_NONE;
1735 BT_CHECK_PARAMETER(char_handle, return);
1737 BT_CHECK_ENABLED(return);
1739 BT_INFO("Disable CCCD : %s", char_handle);
1741 conn = _bt_gdbus_get_system_gconn();
1742 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1744 g_dbus_connection_call_sync(conn,
1747 GATT_CHAR_INTERFACE,
1751 G_DBUS_CALL_FLAGS_NONE,
1752 GATT_DEFAULT_TIMEOUT, NULL, &error);
1755 BT_ERR("Watch Failed: %s", error->message);
1756 g_clear_error(&error);
1757 ret = BLUETOOTH_ERROR_INTERNAL;