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 gp_array = g_ptr_array_new();
233 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
234 g_ptr_array_add(gp_array, (gpointer)char_handle);
236 if (gp_array->len != 0) {
237 service->include_handles.count = gp_array->len;
238 service->include_handles.handle =
239 __get_string_array_from_gptr_array(gp_array);
241 g_ptr_array_free(gp_array, TRUE);
242 g_variant_iter_free(char_iter);
243 } else if (!g_strcmp0(key, "Characteristics")) {
244 g_variant_get(value, "ao", &char_iter);
245 gp_array = g_ptr_array_new();
246 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
247 g_ptr_array_add(gp_array, (gpointer)char_handle);
249 if (gp_array->len != 0) {
250 service->char_handle.count = gp_array->len;
251 service->char_handle.handle =
252 __get_string_array_from_gptr_array(gp_array);
254 BT_DBG("Characteristics count : %d", service->char_handle.count);
255 g_ptr_array_free(gp_array, TRUE);
256 g_variant_iter_free(char_iter);
260 service->handle = g_strdup(service_handle);
262 g_variant_iter_free(property_iter);
263 g_variant_unref(result);
264 g_object_unref(properties_proxy);
266 return BLUETOOTH_ERROR_NONE;
269 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
270 const bluetooth_device_address_t *address,
271 bt_gatt_handle_info_t *prim_svc)
273 GVariant *result = NULL;
275 GVariantIter *svc_iter;
276 GVariantIter *interface_iter;
277 char *object_path = NULL;
278 char *interface_str = NULL;
279 const gchar *key = NULL;
280 GVariant *value = NULL;
281 GPtrArray *gp_array = NULL;
282 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
283 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
284 int ret = BLUETOOTH_ERROR_INTERNAL;
288 BT_CHECK_PARAMETER(address, return);
289 BT_CHECK_PARAMETER(prim_svc, return);
290 BT_CHECK_ENABLED(return);
292 result = _bt_get_managed_objects();
296 _bt_convert_addr_type_to_string(device_address,
297 (unsigned char *)address->addr);
299 gp_array = g_ptr_array_new();
300 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
302 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
304 if (object_path == NULL)
307 _bt_convert_device_path_to_address(object_path, temp_address);
309 if (g_strcmp0(temp_address, device_address) != 0)
312 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
313 &interface_str, &svc_iter)) {
314 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
317 BT_DBG("[%d] Object Path : %s", idx++, object_path);
318 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
319 if (g_strcmp0(key, "Primary") == 0) {
320 if (g_variant_get_boolean(value))
321 g_ptr_array_add(gp_array, (gpointer)object_path);
327 if (gp_array->len == 0) {
328 BT_ERR("gp_array is NULL");
329 ret = BLUETOOTH_ERROR_NOT_FOUND;
331 ret = BLUETOOTH_ERROR_NONE;
332 prim_svc->count = gp_array->len;
333 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
336 g_ptr_array_free(gp_array, TRUE);
337 g_variant_iter_free(iter);
338 g_variant_unref(result);
343 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
344 const char *service_uuid,
345 bt_gatt_service_property_t *service)
347 GVariant *result = NULL;
349 GVariantIter *svc_iter;
350 GVariantIter *interface_iter;
351 char *object_path = NULL;
352 char *interface_str = NULL;
353 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
354 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
355 int ret = BLUETOOTH_ERROR_INTERNAL;
357 BT_CHECK_PARAMETER(address, return);
358 BT_CHECK_PARAMETER(service_uuid, return);
359 BT_CHECK_PARAMETER(service, return);
360 BT_CHECK_ENABLED(return);
362 result = _bt_get_managed_objects();
366 _bt_convert_addr_type_to_string(device_address,
367 (unsigned char *)address->addr);
369 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
371 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
373 if (object_path == NULL)
376 _bt_convert_device_path_to_address(object_path,
379 if (g_strcmp0(temp_address, device_address) != 0)
382 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
383 &interface_str, &svc_iter)) {
384 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
387 BT_DBG("Object Path: %s", object_path);
388 ret = bluetooth_gatt_get_service_property(object_path,
391 if (ret != BLUETOOTH_ERROR_NONE) {
392 BT_ERR("Get service property failed(0x%08x)", ret);
394 if (service->primary == TRUE &&
395 g_strstr_len(service->uuid, -1,
397 ret = BLUETOOTH_ERROR_NONE;
401 bluetooth_gatt_free_service_property(service);
406 g_variant_iter_free(iter);
407 g_variant_unref(result);
412 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
413 GAsyncResult *res, gpointer user_data)
416 GVariant *char_value;
417 GVariantIter *char_iter;
418 GPtrArray *gp_array = NULL;
419 bt_gatt_discovered_char_t svc_char = { 0, };
421 GError *error = NULL;
422 bt_user_info_t *user_info;
426 user_info = _bt_get_user_data(BT_COMMON);
427 svc_char.service_handle = user_data;
429 value = g_dbus_proxy_call_finish(proxy, res, &error);
433 BT_ERR("Get service characteristics failed\n errCode[%x],"
434 "message[%s]\n", error->code, error->message);
435 g_clear_error(&error);
437 BT_ERR("Get service characteristics failed\n");
440 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
441 BLUETOOTH_ERROR_INTERNAL, NULL,
442 user_info->cb, user_info->user_data);
444 g_free(svc_char.service_handle);
445 g_object_unref(proxy);
449 g_variant_get(value, "(v)", &char_value);
450 g_variant_get(char_value, "ao", &char_iter);
452 gp_array = g_ptr_array_new();
453 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
454 g_ptr_array_add(gp_array, (gpointer)char_handle);
456 if (gp_array->len != 0) {
457 svc_char.handle_info.count = gp_array->len;
458 svc_char.handle_info.handle =
459 __get_string_array_from_gptr_array(gp_array);
461 g_ptr_array_free(gp_array, TRUE);
464 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
465 BLUETOOTH_ERROR_NONE, &svc_char,
466 user_info->cb, user_info->user_data);
469 g_strfreev(svc_char.handle_info.handle);
470 g_free(svc_char.service_handle);
471 g_variant_iter_free(char_iter);
472 g_variant_unref(value);
473 g_object_unref(proxy);
476 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
477 const char *service_handle)
479 GDBusProxy *properties_proxy = NULL;
480 GDBusConnection *g_conn;
481 GError *error = NULL;
486 BT_CHECK_PARAMETER(service_handle, return);
487 BT_CHECK_ENABLED(return);
489 g_conn = _bt_gdbus_get_system_gconn();
490 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
492 properties_proxy = g_dbus_proxy_new_sync(g_conn,
493 G_DBUS_PROXY_FLAGS_NONE, NULL,
496 BT_PROPERTIES_INTERFACE,
499 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
501 handle = g_strdup(service_handle);
502 g_dbus_proxy_call(properties_proxy,
504 g_variant_new("(ss)",
505 GATT_SERV_INTERFACE, "Characteristics"),
506 G_DBUS_CALL_FLAGS_NONE,
509 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
513 return BLUETOOTH_ERROR_NONE;
517 static int __get_permission_flag(char *permission)
521 retv_if(permission == NULL, ret);
523 if (!g_strcmp0(permission, "broadcast"))
524 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
525 else if (!g_strcmp0(permission, "read"))
526 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
527 else if (!g_strcmp0(permission, "write-without-response"))
528 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
529 else if (!g_strcmp0(permission, "write"))
530 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
531 else if (!g_strcmp0(permission, "notify"))
532 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
533 else if (!g_strcmp0(permission, "indicate"))
534 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
535 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
536 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
537 else if (!g_strcmp0(permission, "reliable-write"))
538 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
539 else if (!g_strcmp0(permission, "writable-auxiliaries"))
540 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
541 else if (!g_strcmp0(permission, "encrypt-read"))
542 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
543 else if (!g_strcmp0(permission, "encrypt-write"))
544 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
545 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
546 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
547 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
548 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
553 static void __convert_permission_flag_to_str(unsigned int permission)
555 char perm[200] = { 0, };
557 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
558 g_strlcat(perm, "broadcast ", sizeof(perm));
559 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
560 g_strlcat(perm, "read ", sizeof(perm));
561 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
562 g_strlcat(perm, "write-without-response ", sizeof(perm));
563 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
564 g_strlcat(perm, "write ", sizeof(perm));
565 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
566 g_strlcat(perm, "notify ", sizeof(perm));
567 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
568 g_strlcat(perm, "indicate ", sizeof(perm));
569 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
570 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
571 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
572 g_strlcat(perm, "reliable-write ", sizeof(perm));
573 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
574 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
575 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
576 g_strlcat(perm, "encrypt-read ", sizeof(perm));
577 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
578 g_strlcat(perm, "encrypt-write ", sizeof(perm));
579 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
580 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
581 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
582 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
584 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
588 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
589 const char *char_handle, bt_gatt_char_property_t *characteristic)
591 GDBusProxy *properties_proxy = NULL;
592 GError *error = NULL;
593 GVariant *value = NULL;
594 GVariant *result = NULL;
595 GByteArray *gb_array = NULL;
596 GPtrArray *gp_array = NULL ;
597 GDBusConnection *g_conn;
601 char *char_desc_handle = NULL;
603 GVariantIter *property_iter;
604 GVariantIter *char_value_iter;
605 GVariantIter *char_perm_iter;
606 GVariantIter *char_desc_iter;
608 BT_CHECK_PARAMETER(char_handle, return);
609 BT_CHECK_PARAMETER(characteristic, return);
611 BT_CHECK_ENABLED(return);
613 g_conn = _bt_gdbus_get_system_gconn();
614 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
616 properties_proxy = g_dbus_proxy_new_sync(g_conn,
617 G_DBUS_PROXY_FLAGS_NONE, NULL,
620 BT_PROPERTIES_INTERFACE,
623 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
625 result = g_dbus_proxy_call_sync(properties_proxy,
627 g_variant_new("(s)", GATT_CHAR_INTERFACE),
628 G_DBUS_CALL_FLAGS_NONE,
635 BT_ERR("Fail to get properties (Error: %s)", error->message);
636 g_clear_error(&error);
638 BT_ERR("Fail to get properties");
639 g_object_unref(properties_proxy);
640 return BLUETOOTH_ERROR_INTERNAL;
643 g_variant_get(result, "(a{sv})", &property_iter);
645 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
646 characteristic->handle = g_strdup(char_handle);
648 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
649 if (!g_strcmp0(key, "UUID")) {
651 characteristic->uuid = g_variant_dup_string(value, &len);
652 bluetooth_get_uuid_name(characteristic->uuid, &name);
653 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
655 } else if (!g_strcmp0(key, "Value")) {
656 gb_array = g_byte_array_new();
657 g_variant_get(value, "ay", &char_value_iter);
658 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
659 // BT_DBG("value of char = %d",char_value);
660 g_byte_array_append(gb_array, &char_value, 1);
662 g_variant_iter_free(char_value_iter);
664 if (gb_array->len != 0) {
665 characteristic->val = g_malloc0(gb_array->len *
666 sizeof(unsigned char));
667 memcpy(characteristic->val, gb_array->data, gb_array->len);
669 characteristic->val_len = gb_array->len;
670 g_byte_array_free(gb_array, TRUE);
671 } else if (!g_strcmp0(key, "Flags")) {
672 g_variant_get(value, "as", &char_perm_iter);
673 characteristic->permission = 0x00;
675 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
676 characteristic->permission |= __get_permission_flag(permission);
677 __convert_permission_flag_to_str(characteristic->permission);
679 g_variant_iter_free(char_perm_iter);
680 } else if (!g_strcmp0(key, "Descriptors")) {
681 g_variant_get(value, "ao", &char_desc_iter);
682 gp_array = g_ptr_array_new();
683 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
684 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
686 g_variant_iter_free(char_desc_iter);
687 if (gp_array->len != 0) {
688 characteristic->char_desc_handle.count = gp_array->len;
689 characteristic->char_desc_handle.handle =
690 __get_string_array_from_gptr_array(gp_array);
692 g_ptr_array_free(gp_array, TRUE);
696 g_variant_iter_free(property_iter);
697 g_variant_unref(result);
698 g_object_unref(properties_proxy);
700 return BLUETOOTH_ERROR_NONE;
703 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
704 GAsyncResult *res, gpointer user_data)
707 GVariantIter *char_iter;
709 GError *error = NULL;
710 bt_user_info_t *user_info;
711 int ret = BLUETOOTH_ERROR_INTERNAL;
712 bt_gatt_char_property_t characteristic;
714 user_info = _bt_get_user_data(BT_COMMON);
716 value = g_dbus_proxy_call_finish(proxy, res, &error);
720 BT_ERR("Get service characteristics failed\n errCode[%x],"
721 "message[%s]\n", error->code, error->message);
722 g_clear_error(&error);
724 BT_ERR("Get service characteristics failed\n");
727 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
728 BLUETOOTH_ERROR_INTERNAL, NULL,
729 user_info->cb, user_info->user_data);
731 g_object_unref(proxy);
736 g_variant_get(value, "(ao)", &char_iter);
738 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
741 ret = bluetooth_gatt_get_characteristics_property(char_handle,
744 if (ret != BLUETOOTH_ERROR_NONE) {
745 BT_ERR("Get characteristic property failed(0x%08x)", ret);
747 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
748 ret = BLUETOOTH_ERROR_NONE;
752 bluetooth_gatt_free_char_property(&characteristic);
756 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
757 &characteristic, user_info->cb, user_info->user_data);
760 bluetooth_gatt_free_char_property(&characteristic);
761 g_variant_iter_free(char_iter);
762 g_variant_unref(value);
766 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
767 const char *char_uuid)
769 GDBusProxy *properties_proxy = NULL;
770 GDBusConnection *g_conn;
771 GError *error = NULL;
774 BT_CHECK_PARAMETER(service_handle, return);
775 BT_CHECK_PARAMETER(char_uuid, return);
776 BT_CHECK_ENABLED(return);
778 g_conn = _bt_gdbus_get_system_gconn();
779 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
781 properties_proxy = g_dbus_proxy_new_sync(g_conn,
782 G_DBUS_PROXY_FLAGS_NONE, NULL,
785 BT_PROPERTIES_INTERFACE,
788 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
790 uuid = g_strdup(char_uuid);
791 g_dbus_proxy_call(properties_proxy,
793 g_variant_new("(ss)",
794 GATT_SERV_INTERFACE, "Characteristics"),
795 G_DBUS_CALL_FLAGS_NONE,
798 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
801 return BLUETOOTH_ERROR_NONE;
804 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
805 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
807 GDBusProxy *properties_proxy = NULL;
808 GError *error = NULL;
809 GDBusConnection *g_conn;
810 GVariant *result = NULL;
811 GVariantIter *property_iter;
815 GVariant *value = NULL;
816 GByteArray *gb_array = NULL;
817 GVariantIter *desc_value_iter;
819 BT_CHECK_PARAMETER(descriptor_handle, return);
820 BT_CHECK_PARAMETER(descriptor, return);
822 BT_CHECK_ENABLED(return);
824 g_conn = _bt_gdbus_get_system_gconn();
825 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
827 properties_proxy = g_dbus_proxy_new_sync(g_conn,
828 G_DBUS_PROXY_FLAGS_NONE, NULL,
831 BT_PROPERTIES_INTERFACE,
834 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
836 result = g_dbus_proxy_call_sync(properties_proxy,
838 g_variant_new("(s)", GATT_DESC_INTERFACE),
839 G_DBUS_CALL_FLAGS_NONE,
846 BT_ERR("Fail to get properties (Error: %s)", error->message);
847 g_clear_error(&error);
849 BT_ERR("Fail to get properties");
850 g_object_unref(properties_proxy);
851 return BLUETOOTH_ERROR_INTERNAL;
854 g_variant_get(result, "(a{sv})", &property_iter);
856 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
857 descriptor->handle = g_strdup(descriptor_handle);
859 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
860 if (!g_strcmp0(key, "UUID")) {
862 descriptor->uuid = g_variant_dup_string(value, &len);
863 bluetooth_get_uuid_name(descriptor->uuid, &name);
864 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
866 } else if (!g_strcmp0(key, "Value")) {
867 gb_array = g_byte_array_new();
868 g_variant_get(value, "ay", &desc_value_iter);
869 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
870 BT_DBG("value of descriptor = %d", char_value);
871 g_byte_array_append(gb_array, &char_value, 1);
873 g_variant_iter_free(desc_value_iter);
875 if (gb_array->len != 0) {
876 descriptor->val = g_malloc0(gb_array->len *
877 sizeof(unsigned char));
878 memcpy(descriptor->val, gb_array->data, gb_array->len);
880 descriptor->val_len = gb_array->len;
881 g_byte_array_free(gb_array, TRUE);
885 g_variant_iter_free(property_iter);
886 g_variant_unref(result);
887 g_object_unref(properties_proxy);
889 return BLUETOOTH_ERROR_NONE;
892 static int __bluetooth_get_att_error_code(GError *error)
898 BT_ERR("Error : %s", error->message);
899 str = g_strrstr(error->message, "ATT error: 0x");
902 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
903 att_ecode += g_ascii_xdigit_value(str[len - 1]);
905 return BLUETOOTH_ATT_ERROR_INTERNAL;
908 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
909 BT_ERR("Read not permitted");
911 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
912 BT_ERR("Write not permitted");
914 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
915 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
916 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
917 BT_ERR("Not paired");
919 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
920 BT_ERR("Invalid offset");
922 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
923 BT_ERR("Invalid Length");
925 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
926 BT_ERR("Operation not Authorized");
930 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
931 BT_ERR("Application error");
936 static void __bluetooth_internal_read_cb(GObject *source_object,
937 GAsyncResult *res, gpointer user_data)
939 GError *error = NULL;
940 GDBusConnection *system_gconn = NULL;
942 bt_user_info_t *user_info;
944 GByteArray *gp_byte_array = NULL;
947 bt_gatt_resp_data_t *resp_data = user_data;
951 system_gconn = _bt_gdbus_get_system_gconn();
952 value = g_dbus_connection_call_finish(system_gconn, res, &error);
954 user_info = _bt_get_user_data(BT_COMMON);
958 BT_ERR("Error : %s", error->message);
959 g_clear_error(&error);
962 g_variant_unref(value);
967 att_ecode = __bluetooth_get_att_error_code(error);
968 g_clear_error(&error);
970 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
971 att_ecode, resp_data,
972 user_info->cb, user_info->user_data);
977 gp_byte_array = g_byte_array_new();
978 g_variant_get(value, "(ay)", &iter);
980 while (g_variant_iter_loop(iter, "y", &g_byte))
981 g_byte_array_append(gp_byte_array, &g_byte, 1);
983 if (gp_byte_array->len != 0) {
984 resp_data->len = gp_byte_array->len;
985 resp_data->value = gp_byte_array->data;
988 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
989 BLUETOOTH_ATT_ERROR_NONE, resp_data,
990 user_info->cb, user_info->user_data);
993 g_byte_array_free(gp_byte_array, TRUE);
994 g_variant_iter_free(iter);
995 g_variant_unref(value);
1000 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1003 GDBusConnection *conn;
1004 bt_gatt_resp_data_t *resp_data;
1005 GVariantBuilder *builder = NULL;
1008 BT_CHECK_PARAMETER(chr, return);
1009 BT_CHECK_ENABLED(return);
1011 conn = _bt_gdbus_get_system_gconn();
1012 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1014 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1015 resp_data->user_data = user_data;
1017 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1020 g_variant_builder_add(builder, "{sv}", "offset",
1021 g_variant_new("q", offset));
1023 /* Device Object path*/
1024 // g_variant_builder_add(builder, "{sv}", "device",
1025 // g_variant_new_object("o", NULL));
1027 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1028 "ReadValue", g_variant_new("(a{sv})", builder),
1029 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1030 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1031 (gpointer)resp_data);
1032 g_variant_builder_unref(builder);
1034 return BLUETOOTH_ERROR_NONE;
1037 static void __bluetooth_internal_write_cb(GObject *source_object,
1038 GAsyncResult *res, gpointer user_data)
1040 GError *error = NULL;
1041 GDBusConnection *system_gconn = NULL;
1042 bt_user_info_t *user_info;
1045 bt_gatt_resp_data_t *resp_data = user_data;
1047 system_gconn = _bt_gdbus_get_system_gconn();
1048 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1050 user_info = _bt_get_user_data(BT_COMMON);
1054 BT_ERR("Error : %s", error->message);
1055 g_clear_error(&error);
1058 g_variant_unref(value);
1063 att_ecode = __bluetooth_get_att_error_code(error);
1064 g_clear_error(&error);
1066 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1067 att_ecode, resp_data,
1068 user_info->cb, user_info->user_data);
1073 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1074 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1075 user_info->cb, user_info->user_data);
1078 g_variant_unref(value);
1082 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1083 const char *char_handle, const guint8 *value, int length)
1085 GVariant *val, *options;
1086 GVariantBuilder *builder1;
1087 GVariantBuilder *builder2;
1088 GError *error = NULL;
1089 GDBusConnection *conn;
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(return);
1099 conn = _bt_gdbus_get_system_gconn();
1100 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1102 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1103 for (i = 0; i < length; i++)
1104 g_variant_builder_add(builder1, "y", value[i]);
1106 val = g_variant_new("ay", builder1);
1108 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1110 g_variant_builder_add(builder2, "{sv}", "offset",
1111 g_variant_new_uint16(offset));
1113 /* Device Object path*/
1114 // g_variant_builder_add(builder2, "{sv}", "device",
1115 // g_variant_new_object("o", NULL));
1117 options = g_variant_new("a{sv}", builder2);
1119 g_dbus_connection_call(conn,
1122 GATT_CHAR_INTERFACE,
1124 g_variant_new("(@ay@a{sv})",
1127 G_DBUS_CALL_FLAGS_NONE,
1129 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1134 BT_ERR("Set value Failed: %s", error->message);
1135 g_clear_error(&error);
1136 g_variant_builder_unref(builder1);
1137 return BLUETOOTH_ERROR_INTERNAL;
1139 g_variant_builder_unref(builder1);
1140 g_variant_builder_unref(builder2);
1143 return BLUETOOTH_ERROR_NONE;
1146 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1147 const char *chr, const guint8 *value, int length,
1148 guint8 write_type, gpointer user_data)
1150 GVariant *val, *options;
1151 GVariantBuilder *builder1;
1152 GVariantBuilder *builder2;
1153 GDBusConnection *conn;
1156 int ret = BLUETOOTH_ERROR_NONE;
1157 bt_gatt_resp_data_t *resp_data;
1159 BT_CHECK_PARAMETER(chr, return);
1160 BT_CHECK_PARAMETER(value, return);
1161 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1162 BT_CHECK_ENABLED_INTERNAL(return);
1164 conn = _bt_gdbus_get_system_gconn();
1165 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1167 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1169 for (i = 0; i < length; i++)
1170 g_variant_builder_add(builder1, "y", value[i]);
1172 val = g_variant_new("ay", builder1);
1174 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1176 g_variant_builder_add(builder2, "{sv}", "offset",
1177 g_variant_new_uint16(offset));
1179 /* Device Object path*/
1180 // g_variant_builder_add(builder2, "{sv}", "device",
1181 // g_variant_new_object("o", NULL));
1183 options = g_variant_new("a{sv}", builder2);
1185 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1186 resp_data->user_data = user_data;
1188 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1190 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1192 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1193 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1194 (gpointer)resp_data);
1196 g_variant_builder_unref(builder1);
1197 g_variant_builder_unref(builder2);
1202 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1203 const char *char_handle, const guint8 *value, int length)
1205 GVariant *val, *options;
1206 GDBusConnection *conn;
1207 GVariantBuilder *builder1;
1208 GVariantBuilder *builder2;
1213 BT_CHECK_PARAMETER(char_handle, return);
1214 BT_CHECK_PARAMETER(value, return);
1215 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1216 BT_CHECK_ENABLED(return);
1218 conn = _bt_gdbus_get_system_gconn();
1219 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1221 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1223 for (i = 0; i < length; i++) {
1224 g_variant_builder_add(builder1, "y", value[i]);
1225 BT_DBG("value [] = %d", value[i]);
1228 val = g_variant_new("ay", builder1);
1230 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1232 g_variant_builder_add(builder2, "{sv}", "offset",
1233 g_variant_new_uint16(offset));
1235 /* Device Object path*/
1236 // g_variant_builder_add(builder2, "{sv}", "device",
1237 // g_variant_new_object("o", NULL));
1239 options = g_variant_new("a{sv}", builder2);
1241 g_dbus_connection_call(conn,
1244 GATT_CHAR_INTERFACE,
1246 g_variant_new("(@ay@a{sv})",
1249 G_DBUS_CALL_FLAGS_NONE,
1251 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1254 g_variant_builder_unref(builder1);
1255 g_variant_builder_unref(builder2);
1258 return BLUETOOTH_ERROR_NONE;
1261 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1262 bt_gatt_char_property_t *characteristic)
1265 GDBusProxy *properties_proxy = NULL;
1266 GError *error = NULL;
1267 GVariant *value = NULL;
1268 GVariant *result = NULL;
1269 GDBusConnection *g_conn;
1270 int i, ret = BLUETOOTH_ERROR_NONE;
1271 const char *uuid = NULL;
1273 GVariantIter *desc_value_iter, *property_iter;
1275 char_descriptor_type_t desc_type = TYPE_NONE;
1277 g_conn = _bt_gdbus_get_system_gconn();
1278 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1280 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1281 G_DBUS_PROXY_FLAGS_NONE, NULL,
1284 BT_PROPERTIES_INTERFACE,
1287 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1289 result = g_dbus_proxy_call_sync(properties_proxy,
1291 g_variant_new("(s)", GATT_DESC_INTERFACE),
1292 G_DBUS_CALL_FLAGS_NONE,
1298 if (error != NULL) {
1299 BT_ERR("Fail to get properties (Error: %s)", error->message);
1300 g_clear_error(&error);
1302 BT_ERR("Fail to get properties");
1303 g_object_unref(properties_proxy);
1304 return BLUETOOTH_ERROR_INTERNAL;
1306 g_variant_get(result, "(a{sv})", &property_iter);
1307 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1308 if (!g_strcmp0(key, "UUID")) {
1309 uuid = g_variant_get_string(value, &len);
1310 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1311 BT_DBG("GATT_USER_DESC_UUID");
1312 desc_type = USER_DESC;
1313 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1314 BT_DBG("GATT_CHAR_FORMAT");
1315 desc_type = CHAR_FORMAT;
1316 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1317 BT_DBG("GATT_CHAR_CLIENT_CONF");
1318 desc_type = CLIENT_CONF;
1319 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1320 BT_DBG("GATT_CHAR_SERVER_CONF");
1321 desc_type = SERVER_CONF;
1323 BT_DBG("descriptor uuid = %s", uuid);
1325 } else if (!g_strcmp0(key, "Value")) {
1326 switch (desc_type) {
1328 BT_DBG("Format descriptor");
1329 g_variant_get(value, "(yyqyq)",
1330 &(characteristic->format.format),
1331 &(characteristic->format.exponent),
1332 &(characteristic->format.unit),
1333 &(characteristic->format.name_space),
1334 &(characteristic->format.description));
1337 BT_DBG("User descriptor");
1338 g_variant_get(value, "ay", &desc_value_iter);
1339 len = g_variant_get_size((GVariant *)desc_value_iter);
1342 characteristic->description = (char *)g_malloc0(len + 1);
1344 for (i = 0; i < len; i++) {
1345 g_variant_iter_loop(desc_value_iter, "y",
1346 &characteristic->description[i]);
1347 BT_DBG("description = %s", characteristic->description);
1349 g_variant_iter_free(desc_value_iter);
1352 BT_DBG(" CLIENT_CONF");
1355 BT_DBG(" SERVER_CONF");
1363 g_variant_iter_free(property_iter);
1364 g_variant_unref(result);
1365 g_object_unref(properties_proxy);
1372 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1373 GAsyncResult *res, gpointer user_data)
1377 GVariant *char_value;
1378 GVariantIter *char_iter;
1380 GError *error = NULL;
1381 bt_user_info_t *user_info;
1382 bt_gatt_char_property_t characteristic = {0, };
1383 int ret = BLUETOOTH_ERROR_INTERNAL;
1385 user_info = _bt_get_user_data(BT_COMMON);
1387 value = g_dbus_proxy_call_finish(proxy, res, &error);
1388 characteristic.handle = user_data;
1390 if (value == NULL) {
1391 if (error != NULL) {
1392 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1393 "message[%s]\n", error->code, error->message);
1394 g_clear_error(&error);
1396 BT_ERR("Get characteristic descriptor failed\n");
1399 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1400 BLUETOOTH_ERROR_INTERNAL, NULL,
1401 user_info->cb, user_info->user_data);
1403 g_free(characteristic.handle);
1404 g_object_unref(proxy);
1408 g_variant_get(value, "(v)", &char_value);
1409 g_variant_get(char_value, "ao", &char_iter);
1411 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1412 BT_DBG("object path of descriptor = %s", char_handle);
1414 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1416 BT_DBG("Descriptor read status [%d]", ret);
1421 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1422 ret, &characteristic, user_info->cb, user_info->user_data);
1424 bluetooth_gatt_free_char_property(&characteristic);
1426 g_free(characteristic.handle);
1427 g_variant_iter_free(char_iter);
1428 g_variant_unref(value);
1432 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1433 const char *characteristic_handle)
1435 GDBusProxy *properties_proxy = NULL;
1436 GDBusConnection *g_conn;
1438 GError *error = NULL;
1440 BT_CHECK_PARAMETER(characteristic_handle, return);
1441 BT_CHECK_ENABLED(return);
1443 g_conn = _bt_gdbus_get_system_gconn();
1444 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1446 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1447 G_DBUS_PROXY_FLAGS_NONE, NULL,
1449 characteristic_handle,
1450 BT_PROPERTIES_INTERFACE,
1453 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1455 handle = g_strdup(characteristic_handle);
1456 g_dbus_proxy_call(properties_proxy,
1458 g_variant_new("(ss)",
1459 GATT_CHAR_INTERFACE, "Descriptors"),
1460 G_DBUS_CALL_FLAGS_NONE,
1462 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1465 return BLUETOOTH_ERROR_NONE;
1468 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1472 GError *error = NULL;
1473 GDBusConnection *system_gconn = NULL;
1475 bt_user_info_t *user_info;
1476 GByteArray *gp_byte_array = NULL;
1480 bt_gatt_resp_data_t *resp_data = user_data;
1484 system_gconn = _bt_gdbus_get_system_gconn();
1485 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1487 user_info = _bt_get_user_data(BT_COMMON);
1491 BT_ERR("Error : %s", error->message);
1492 g_clear_error(&error);
1495 g_variant_unref(value);
1500 att_ecode = __bluetooth_get_att_error_code(error);
1501 g_clear_error(&error);
1503 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1504 att_ecode, resp_data,
1505 user_info->cb, user_info->user_data);
1510 gp_byte_array = g_byte_array_new();
1511 g_variant_get(value, "(ay)", &iter);
1513 while (g_variant_iter_loop(iter, "y", &g_byte))
1514 g_byte_array_append(gp_byte_array, &g_byte, 1);
1516 if (gp_byte_array->len != 0) {
1517 resp_data->len = gp_byte_array->len;
1518 resp_data->value = gp_byte_array->data;
1521 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1522 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1523 user_info->cb, user_info->user_data);
1527 g_byte_array_free(gp_byte_array, TRUE);
1528 g_variant_iter_free(iter);
1529 g_variant_unref(value);
1534 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1537 GDBusConnection *conn;
1538 GVariantBuilder *builder;
1540 bt_gatt_resp_data_t *resp_data;
1544 BT_CHECK_PARAMETER(desc, return);
1545 BT_CHECK_ENABLED(return);
1547 conn = _bt_gdbus_get_system_gconn();
1548 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1550 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1551 resp_data->user_data = user_data;
1553 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1556 g_variant_builder_add(builder, "{sv}", "offset",
1557 g_variant_new("q", offset));
1558 /* Device Object path*/
1559 // g_variant_builder_add(builder, "{sv}", "device",
1560 // g_variant_new("o", serv_info->serv_path));
1562 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1563 "ReadValue", g_variant_new("(a{sv})", builder),
1564 G_VARIANT_TYPE("(ay)"),
1565 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1566 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1567 (gpointer)resp_data);
1568 g_variant_builder_unref(builder);
1571 return BLUETOOTH_ERROR_NONE;
1574 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1575 GAsyncResult *res, gpointer user_data)
1577 GError *error = NULL;
1578 bt_user_info_t *user_info;
1579 GDBusConnection *system_gconn = NULL;
1581 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1582 bt_gatt_resp_data_t *resp_data = user_data;
1586 system_gconn = _bt_gdbus_get_system_gconn();
1587 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1589 user_info = _bt_get_user_data(BT_COMMON);
1593 BT_ERR("Error : %s", error->message);
1594 g_clear_error(&error);
1597 g_variant_unref(value);
1602 att_ecode = __bluetooth_get_att_error_code(error);
1603 g_clear_error(&error);
1605 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1606 att_ecode, resp_data,
1607 user_info->cb, user_info->user_data);
1612 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1613 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1614 user_info->cb, user_info->user_data);
1617 g_variant_unref(value);
1621 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1622 const guint8 *value, int length, gpointer user_data)
1624 GVariant *val, *options;
1625 GDBusConnection *conn;
1626 GVariantBuilder *builder1;
1627 GVariantBuilder *builder2;
1630 bt_gatt_resp_data_t *resp_data;
1634 BT_CHECK_PARAMETER(desc, return);
1635 BT_CHECK_PARAMETER(value, return);
1636 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1637 BT_CHECK_ENABLED(return);
1639 conn = _bt_gdbus_get_system_gconn();
1640 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1642 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1644 for (i = 0; i < length; i++)
1645 g_variant_builder_add(builder1, "y", value[i]);
1647 val = g_variant_new("ay", builder1);
1649 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1651 g_variant_builder_add(builder2, "{sv}", "offset",
1652 g_variant_new_uint16(offset));
1654 /* Device Object path*/
1655 // g_variant_builder_add(builder2, "{sv}", "device",
1656 // g_variant_new_object("o", NULL));
1658 options = g_variant_new("a{sv}", builder2);
1660 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1661 resp_data->user_data = user_data;
1663 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1664 "WriteValue", g_variant_new("(@ay@a{sv})",
1665 val, options), NULL,
1666 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1667 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1668 (gpointer)resp_data);
1670 g_variant_builder_unref(builder1);
1671 g_variant_builder_unref(builder2);
1674 return BLUETOOTH_ERROR_NONE;
1677 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1679 GDBusConnection *conn;
1680 GError *error = NULL;
1681 int ret = BLUETOOTH_ERROR_NONE;
1683 BT_CHECK_PARAMETER(char_handle, return);
1684 BT_CHECK_ENABLED(return);
1686 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
1688 conn = _bt_gdbus_get_system_gconn();
1689 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1691 g_dbus_connection_call_sync(conn,
1694 GATT_CHAR_INTERFACE,
1698 G_DBUS_CALL_FLAGS_NONE,
1699 GATT_DEFAULT_TIMEOUT, NULL, &error);
1702 g_dbus_error_strip_remote_error(error);
1703 BT_ERR_C("### Watch Failed: %s", error->message);
1704 if (g_strrstr(error->message, "Already notifying"))
1705 ret = BLUETOOTH_ERROR_NONE;
1706 else if (g_strrstr(error->message, "In Progress"))
1707 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1708 else if (g_strrstr(error->message, "Operation is not supported"))
1709 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1710 /*failed because of either Insufficient Authorization or Write Not Permitted */
1711 else if (g_strrstr(error->message, "Write not permitted") ||
1712 g_strrstr(error->message, "Operation Not Authorized"))
1713 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1714 /* failed because of either Insufficient Authentication,
1715 Insufficient Encryption Key Size, or Insufficient Encryption. */
1716 else if (g_strrstr(error->message, "Not paired"))
1717 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1719 ret = BLUETOOTH_ERROR_INTERNAL;
1721 g_clear_error(&error);
1727 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1730 GDBusConnection *conn;
1731 GError *error = NULL;
1732 int ret = BLUETOOTH_ERROR_NONE;
1733 BT_CHECK_PARAMETER(char_handle, return);
1735 BT_CHECK_ENABLED(return);
1737 BT_INFO("Disable CCCD : %s", char_handle);
1739 conn = _bt_gdbus_get_system_gconn();
1740 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1742 g_dbus_connection_call_sync(conn,
1745 GATT_CHAR_INTERFACE,
1749 G_DBUS_CALL_FLAGS_NONE,
1750 GATT_DEFAULT_TIMEOUT, NULL, &error);
1753 BT_ERR("Watch Failed: %s", error->message);
1754 g_clear_error(&error);
1755 ret = BLUETOOTH_ERROR_INTERNAL;