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)
110 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
111 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
113 _bt_convert_addr_type_to_string(device_address,
114 (unsigned char *)device_addr->addr);
116 for (l = service_monitor_list; l != NULL; l = l->next) {
117 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
118 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
119 bluetooth_device_address_t *addr = l->data;
121 _bt_convert_addr_type_to_string(device_address2,
122 (unsigned char *)addr->addr);
123 _bt_convert_addr_string_to_secure_string(secure_address,
125 _bt_convert_addr_string_to_secure_string(secure_address2,
127 BT_INFO("service_monitor_list [%s] - Input [%s]",
128 secure_address2, secure_address);
130 if (!memcmp(device_addr, addr,
131 sizeof(bluetooth_device_address_t)))
138 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
139 const bluetooth_device_address_t *address, gboolean enable)
142 bluetooth_device_address_t *addr = NULL;
143 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
144 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
146 _bt_convert_addr_type_to_string(device_address,
147 (unsigned char *)address->addr);
148 _bt_convert_addr_string_to_secure_string(secure_address,
150 BT_INFO("Set watcher for %s with %d", secure_address, enable);
152 if (enable == TRUE) {
153 if (service_monitor_list == NULL)
154 _bt_register_manager_subscribe_signal(TRUE);
156 if (_bluetooth_gatt_check_service_change_watcher_address(address)
158 BT_INFO("The watcher is already set");
159 return BLUETOOTH_ERROR_NONE;
161 addr = g_malloc0(sizeof(bluetooth_device_address_t));
162 memcpy(addr, address, sizeof(bluetooth_device_address_t));
164 service_monitor_list =
165 g_slist_append(service_monitor_list, addr);
168 for (l = service_monitor_list; l != NULL; l = l->next) {
170 if (!memcmp(address, addr,
171 sizeof(bluetooth_device_address_t))) {
172 service_monitor_list =
173 g_slist_remove(service_monitor_list, addr);
179 if (service_monitor_list == NULL)
180 _bt_register_manager_subscribe_signal(FALSE);
183 return BLUETOOTH_ERROR_NONE;
186 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
187 bt_gatt_service_property_t *service)
189 GDBusProxy *properties_proxy = NULL;
190 GError *error = NULL;
191 GVariant *result = NULL;
192 GDBusConnection *g_conn;
194 char *char_handle = NULL;
195 GPtrArray *gp_array = NULL ;
196 GVariantIter *property_iter, *char_iter = NULL;
200 BT_CHECK_PARAMETER(service_handle, return);
201 BT_CHECK_PARAMETER(service, return);
202 BT_CHECK_ENABLED(return);
204 g_conn = _bt_gdbus_get_system_gconn();
205 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
207 properties_proxy = g_dbus_proxy_new_sync(g_conn,
208 G_DBUS_PROXY_FLAGS_NONE, NULL,
211 BT_PROPERTIES_INTERFACE,
214 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
216 result = g_dbus_proxy_call_sync(properties_proxy,
218 g_variant_new("(s)", GATT_SERV_INTERFACE),
219 G_DBUS_CALL_FLAGS_NONE,
226 BT_ERR("Fail to get properties (Error: %s)", error->message);
227 g_clear_error(&error);
229 BT_ERR("Fail to get properties");
230 g_object_unref(properties_proxy);
231 return BLUETOOTH_ERROR_INTERNAL;
234 g_variant_get(result, "(a{sv})", &property_iter);
236 memset(service, 0, sizeof(bt_gatt_service_property_t));
238 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
239 if (!g_strcmp0(key, "UUID")) {
241 service->uuid = g_variant_dup_string(value, &len);
242 _bt_get_uuid_specification_name(service->uuid, &name);
243 BT_INFO("======> Service : %s [%s]", service->uuid, name);
245 } else if (!g_strcmp0(key, "Primary")) {
246 service->primary = g_variant_get_boolean(value);
248 } else if (!g_strcmp0(key, "Includes")) {
249 g_variant_get(value, "ao", &char_iter);
250 gp_array = g_ptr_array_new();
251 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
252 g_ptr_array_add(gp_array, (gpointer)char_handle);
254 if (gp_array->len != 0) {
255 service->include_handles.count = gp_array->len;
256 service->include_handles.handle =
257 __get_string_array_from_gptr_array(gp_array);
259 g_ptr_array_free(gp_array, TRUE);
260 g_variant_iter_free(char_iter);
261 } else if (!g_strcmp0(key, "Characteristics")) {
262 g_variant_get(value, "ao", &char_iter);
263 gp_array = g_ptr_array_new();
264 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
265 g_ptr_array_add(gp_array, (gpointer)char_handle);
267 if (gp_array->len != 0) {
268 service->char_handle.count = gp_array->len;
269 service->char_handle.handle =
270 __get_string_array_from_gptr_array(gp_array);
272 BT_DBG("Characteristics count : %d", service->char_handle.count);
273 g_ptr_array_free(gp_array, TRUE);
274 g_variant_iter_free(char_iter);
278 service->handle = g_strdup(service_handle);
280 g_variant_iter_free(property_iter);
281 g_variant_unref(result);
282 g_object_unref(properties_proxy);
284 return BLUETOOTH_ERROR_NONE;
287 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
288 const bluetooth_device_address_t *address,
289 bt_gatt_handle_info_t *prim_svc)
291 GVariant *result = NULL;
293 GVariantIter *svc_iter;
294 GVariantIter *interface_iter;
295 char *object_path = NULL;
296 char *interface_str = NULL;
297 const gchar *key = NULL;
298 GVariant *value = NULL;
299 GPtrArray *gp_array = NULL;
300 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
301 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
302 int ret = BLUETOOTH_ERROR_INTERNAL;
305 BT_CHECK_PARAMETER(address, return);
306 BT_CHECK_PARAMETER(prim_svc, return);
307 BT_CHECK_ENABLED(return);
309 result = _bt_get_managed_objects();
313 _bt_convert_addr_type_to_string(device_address,
314 (unsigned char *)address->addr);
316 gp_array = g_ptr_array_new();
317 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
319 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
321 if (object_path == NULL)
324 _bt_convert_device_path_to_address(object_path, temp_address);
326 if (g_strcmp0(temp_address, device_address) != 0)
329 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
330 &interface_str, &svc_iter)) {
331 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
334 BT_DBG("Object Path: %s", object_path);
335 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
336 if (g_strcmp0(key, "Primary") == 0) {
337 if (g_variant_get_boolean(value))
338 g_ptr_array_add(gp_array, (gpointer)object_path);
344 if (gp_array->len == 0) {
345 BT_ERR("gp_array is NULL");
346 ret = BLUETOOTH_ERROR_NOT_FOUND;
348 ret = BLUETOOTH_ERROR_NONE;
349 prim_svc->count = gp_array->len;
350 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
353 g_ptr_array_free(gp_array, TRUE);
354 g_variant_iter_free(iter);
355 g_variant_unref(result);
360 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
361 const char *service_uuid,
362 bt_gatt_service_property_t *service)
364 GVariant *result = NULL;
366 GVariantIter *svc_iter;
367 GVariantIter *interface_iter;
368 char *object_path = NULL;
369 char *interface_str = NULL;
370 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
371 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
372 int ret = BLUETOOTH_ERROR_INTERNAL;
374 BT_CHECK_PARAMETER(address, return);
375 BT_CHECK_PARAMETER(service_uuid, return);
376 BT_CHECK_PARAMETER(service, return);
377 BT_CHECK_ENABLED(return);
379 result = _bt_get_managed_objects();
383 _bt_convert_addr_type_to_string(device_address,
384 (unsigned char *)address->addr);
386 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
388 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
390 if (object_path == NULL)
393 _bt_convert_device_path_to_address(object_path,
396 if (g_strcmp0(temp_address, device_address) != 0)
399 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
400 &interface_str, &svc_iter)) {
401 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
404 BT_DBG("Object Path: %s", object_path);
405 ret = bluetooth_gatt_get_service_property(object_path,
408 if (ret != BLUETOOTH_ERROR_NONE) {
409 BT_ERR("Get service property failed(0x%08x)", ret);
411 if (service->primary == TRUE &&
412 g_strstr_len(service->uuid, -1,
414 ret = BLUETOOTH_ERROR_NONE;
418 bluetooth_gatt_free_service_property(service);
423 g_variant_iter_free(iter);
424 g_variant_unref(result);
429 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
430 GAsyncResult *res, gpointer user_data)
433 GVariant *char_value;
434 GVariantIter *char_iter;
435 GPtrArray *gp_array = NULL;
436 bt_gatt_discovered_char_t svc_char = { 0, };
438 GError *error = NULL;
439 bt_user_info_t *user_info;
443 user_info = _bt_get_user_data(BT_COMMON);
444 svc_char.service_handle = user_data;
446 value = g_dbus_proxy_call_finish(proxy, res, &error);
450 BT_ERR("Get service characteristics failed\n errCode[%x],"
451 "message[%s]\n", error->code, error->message);
452 g_clear_error(&error);
454 BT_ERR("Get service characteristics failed\n");
457 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
458 BLUETOOTH_ERROR_INTERNAL, NULL,
459 user_info->cb, user_info->user_data);
461 g_free(svc_char.service_handle);
462 g_object_unref(proxy);
466 g_variant_get(value, "(v)", &char_value);
467 g_variant_get(char_value, "ao", &char_iter);
469 gp_array = g_ptr_array_new();
470 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
471 g_ptr_array_add(gp_array, (gpointer)char_handle);
473 if (gp_array->len != 0) {
474 svc_char.handle_info.count = gp_array->len;
475 svc_char.handle_info.handle =
476 __get_string_array_from_gptr_array(gp_array);
478 g_ptr_array_free(gp_array, TRUE);
481 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
482 BLUETOOTH_ERROR_NONE, &svc_char,
483 user_info->cb, user_info->user_data);
486 g_strfreev(svc_char.handle_info.handle);
487 g_free(svc_char.service_handle);
488 g_variant_iter_free(char_iter);
489 g_variant_unref(value);
490 g_object_unref(proxy);
493 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
494 const char *service_handle)
496 GDBusProxy *properties_proxy = NULL;
497 GDBusConnection *g_conn;
498 GError *error = NULL;
503 BT_CHECK_PARAMETER(service_handle, return);
504 BT_CHECK_ENABLED(return);
506 g_conn = _bt_gdbus_get_system_gconn();
507 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
509 properties_proxy = g_dbus_proxy_new_sync(g_conn,
510 G_DBUS_PROXY_FLAGS_NONE, NULL,
513 BT_PROPERTIES_INTERFACE,
516 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
518 handle = g_strdup(service_handle);
519 g_dbus_proxy_call(properties_proxy,
521 g_variant_new("(ss)",
522 GATT_SERV_INTERFACE, "Characteristics"),
523 G_DBUS_CALL_FLAGS_NONE,
526 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
530 return BLUETOOTH_ERROR_NONE;
534 static int __get_permission_flag(char *permission)
538 retv_if(permission == NULL, ret);
540 BT_INFO("permission = %s", permission);
542 if (!g_strcmp0(permission, "broadcast"))
543 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
544 else if (!g_strcmp0(permission, "read"))
545 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
546 else if (!g_strcmp0(permission, "write-without-response"))
547 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
548 else if (!g_strcmp0(permission, "write"))
549 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
550 else if (!g_strcmp0(permission, "notify"))
551 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
552 else if (!g_strcmp0(permission, "indicate"))
553 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
554 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
555 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
556 else if (!g_strcmp0(permission, "reliable-write"))
557 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
558 else if (!g_strcmp0(permission, "writable-auxiliaries"))
559 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
560 else if (!g_strcmp0(permission, "encrypt-read"))
561 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
562 else if (!g_strcmp0(permission, "encrypt-write"))
563 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
564 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
565 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
566 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
567 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
572 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
573 const char *char_handle, bt_gatt_char_property_t *characteristic)
575 GDBusProxy *properties_proxy = NULL;
576 GError *error = NULL;
577 GVariant *value = NULL;
578 GVariant *result = NULL;
579 GByteArray *gb_array = NULL;
580 GPtrArray *gp_array = NULL ;
581 GDBusConnection *g_conn;
585 char *char_desc_handle = NULL;
587 GVariantIter *property_iter;
588 GVariantIter *char_value_iter;
589 GVariantIter *char_perm_iter;
590 GVariantIter *char_desc_iter;
592 BT_CHECK_PARAMETER(char_handle, return);
593 BT_CHECK_PARAMETER(characteristic, return);
595 BT_CHECK_ENABLED(return);
597 g_conn = _bt_gdbus_get_system_gconn();
598 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
600 properties_proxy = g_dbus_proxy_new_sync(g_conn,
601 G_DBUS_PROXY_FLAGS_NONE, NULL,
604 BT_PROPERTIES_INTERFACE,
607 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
609 result = g_dbus_proxy_call_sync(properties_proxy,
611 g_variant_new("(s)", GATT_CHAR_INTERFACE),
612 G_DBUS_CALL_FLAGS_NONE,
619 BT_ERR("Fail to get properties (Error: %s)", error->message);
620 g_clear_error(&error);
622 BT_ERR("Fail to get properties");
623 g_object_unref(properties_proxy);
624 return BLUETOOTH_ERROR_INTERNAL;
627 g_variant_get(result, "(a{sv})", &property_iter);
629 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
630 characteristic->handle = g_strdup(char_handle);
632 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
633 if (!g_strcmp0(key, "UUID")) {
635 characteristic->uuid = g_variant_dup_string(value, &len);
636 _bt_get_uuid_specification_name(characteristic->uuid, &name);
637 BT_INFO("Characteristic : %s [%s]", characteristic->uuid, name);
639 } else if (!g_strcmp0(key, "Value")) {
640 gb_array = g_byte_array_new();
641 g_variant_get(value, "ay", &char_value_iter);
642 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
643 // BT_DBG("value of char = %d",char_value);
644 g_byte_array_append(gb_array, &char_value, 1);
646 g_variant_iter_free(char_value_iter);
648 if (gb_array->len != 0) {
649 characteristic->val = g_malloc0(gb_array->len *
650 sizeof(unsigned char));
651 memcpy(characteristic->val, gb_array->data, gb_array->len);
653 characteristic->val_len = gb_array->len;
654 g_byte_array_free(gb_array, TRUE);
655 } else if (!g_strcmp0(key, "Flags")) {
656 g_variant_get(value, "as", &char_perm_iter);
657 characteristic->permission = 0x00;
659 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
660 characteristic->permission |= __get_permission_flag(permission);
662 g_variant_iter_free(char_perm_iter);
663 } else if (!g_strcmp0(key, "Descriptors")) {
664 g_variant_get(value, "ao", &char_desc_iter);
665 gp_array = g_ptr_array_new();
666 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
667 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
669 g_variant_iter_free(char_desc_iter);
670 if (gp_array->len != 0) {
671 characteristic->char_desc_handle.count = gp_array->len;
672 characteristic->char_desc_handle.handle =
673 __get_string_array_from_gptr_array(gp_array);
675 g_ptr_array_free(gp_array, TRUE);
679 g_variant_iter_free(property_iter);
680 g_variant_unref(result);
681 g_object_unref(properties_proxy);
683 return BLUETOOTH_ERROR_NONE;
686 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
687 GAsyncResult *res, gpointer user_data)
690 GVariantIter *char_iter;
692 GError *error = NULL;
693 bt_user_info_t *user_info;
694 int ret = BLUETOOTH_ERROR_INTERNAL;
695 bt_gatt_char_property_t characteristic;
697 user_info = _bt_get_user_data(BT_COMMON);
699 value = g_dbus_proxy_call_finish(proxy, res, &error);
703 BT_ERR("Get service characteristics failed\n errCode[%x],"
704 "message[%s]\n", error->code, error->message);
705 g_clear_error(&error);
707 BT_ERR("Get service characteristics failed\n");
710 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
711 BLUETOOTH_ERROR_INTERNAL, NULL,
712 user_info->cb, user_info->user_data);
714 g_object_unref(proxy);
719 g_variant_get(value, "(ao)", &char_iter);
721 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
724 ret = bluetooth_gatt_get_characteristics_property(char_handle,
727 if (ret != BLUETOOTH_ERROR_NONE) {
728 BT_ERR("Get characteristic property failed(0x%08x)", ret);
730 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
731 ret = BLUETOOTH_ERROR_NONE;
735 bluetooth_gatt_free_char_property(&characteristic);
739 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
740 &characteristic, user_info->cb, user_info->user_data);
743 bluetooth_gatt_free_char_property(&characteristic);
744 g_variant_iter_free(char_iter);
745 g_variant_unref(value);
749 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
750 const char *char_uuid)
752 GDBusProxy *properties_proxy = NULL;
753 GDBusConnection *g_conn;
754 GError *error = NULL;
757 BT_CHECK_PARAMETER(service_handle, return);
758 BT_CHECK_PARAMETER(char_uuid, return);
759 BT_CHECK_ENABLED(return);
761 g_conn = _bt_gdbus_get_system_gconn();
762 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
764 properties_proxy = g_dbus_proxy_new_sync(g_conn,
765 G_DBUS_PROXY_FLAGS_NONE, NULL,
768 BT_PROPERTIES_INTERFACE,
771 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
773 uuid = g_strdup(char_uuid);
774 g_dbus_proxy_call(properties_proxy,
776 g_variant_new("(ss)",
777 GATT_SERV_INTERFACE, "Characteristics"),
778 G_DBUS_CALL_FLAGS_NONE,
781 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
784 return BLUETOOTH_ERROR_NONE;
787 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
788 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
790 GDBusProxy *properties_proxy = NULL;
791 GError *error = NULL;
792 GDBusConnection *g_conn;
793 GVariant *result = NULL;
794 GVariantIter *property_iter;
798 GVariant *value = NULL;
799 GByteArray *gb_array = NULL;
800 GVariantIter *desc_value_iter;
802 BT_CHECK_PARAMETER(descriptor_handle, return);
803 BT_CHECK_PARAMETER(descriptor, return);
805 BT_CHECK_ENABLED(return);
807 g_conn = _bt_gdbus_get_system_gconn();
808 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
810 properties_proxy = g_dbus_proxy_new_sync(g_conn,
811 G_DBUS_PROXY_FLAGS_NONE, NULL,
814 BT_PROPERTIES_INTERFACE,
817 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
819 result = g_dbus_proxy_call_sync(properties_proxy,
821 g_variant_new("(s)", GATT_DESC_INTERFACE),
822 G_DBUS_CALL_FLAGS_NONE,
829 BT_ERR("Fail to get properties (Error: %s)", error->message);
830 g_clear_error(&error);
832 BT_ERR("Fail to get properties");
833 g_object_unref(properties_proxy);
834 return BLUETOOTH_ERROR_INTERNAL;
837 g_variant_get(result, "(a{sv})", &property_iter);
839 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
840 descriptor->handle = g_strdup(descriptor_handle);
842 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
843 if (!g_strcmp0(key, "UUID")) {
845 descriptor->uuid = g_variant_dup_string(value, &len);
846 _bt_get_uuid_specification_name(descriptor->uuid, &name);
847 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
849 } else if (!g_strcmp0(key, "Value")) {
850 gb_array = g_byte_array_new();
851 g_variant_get(value, "ay", &desc_value_iter);
852 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
853 BT_DBG("value of descriptor = %d", char_value);
854 g_byte_array_append(gb_array, &char_value, 1);
856 g_variant_iter_free(desc_value_iter);
858 if (gb_array->len != 0) {
859 descriptor->val = g_malloc0(gb_array->len *
860 sizeof(unsigned char));
861 memcpy(descriptor->val, gb_array->data, gb_array->len);
863 descriptor->val_len = gb_array->len;
864 g_byte_array_free(gb_array, TRUE);
868 g_variant_iter_free(property_iter);
869 g_variant_unref(result);
870 g_object_unref(properties_proxy);
872 return BLUETOOTH_ERROR_NONE;
875 static int __bluetooth_get_att_error_code(GError *error)
881 BT_ERR("Error : %s", error->message);
882 str = g_strrstr(error->message, "ATT error: 0x");
885 att_ecode = g_ascii_xdigit_value(str[len-2]) << 4;
886 att_ecode += g_ascii_xdigit_value(str[len-1]);
888 return BLUETOOTH_ATT_ERROR_INTERNAL;
891 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
892 BT_ERR("Read not permitted");
894 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
895 BT_ERR("Write not permitted");
897 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
899 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
900 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
901 BT_ERR("Not paired");
903 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
904 BT_ERR("Invalid offset");
906 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
907 BT_ERR("Invalid Length");
909 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
910 BT_ERR("Operation not Authorized");
914 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
915 BT_ERR("Application error");
920 static void __bluetooth_internal_read_cb(GObject *source_object,
921 GAsyncResult *res, gpointer user_data)
923 GError *error = NULL;
924 GDBusConnection *system_gconn = NULL;
926 bt_user_info_t *user_info;
928 GByteArray *gp_byte_array = NULL;
931 bt_gatt_resp_data_t *resp_data = user_data;
935 system_gconn = _bt_gdbus_get_system_gconn();
936 value = g_dbus_connection_call_finish(system_gconn, res, &error);
938 user_info = _bt_get_user_data(BT_COMMON);
942 BT_ERR("Error : %s", error->message);
943 g_clear_error(&error);
946 g_variant_unref(value);
951 att_ecode = __bluetooth_get_att_error_code(error);
952 g_clear_error(&error);
954 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
955 att_ecode, resp_data,
956 user_info->cb, user_info->user_data);
961 gp_byte_array = g_byte_array_new();
962 g_variant_get(value, "(ay)", &iter);
964 while (g_variant_iter_loop(iter, "y", &g_byte))
965 g_byte_array_append(gp_byte_array, &g_byte, 1);
967 if (gp_byte_array->len != 0) {
968 resp_data->len = gp_byte_array->len;
969 resp_data->value = gp_byte_array->data;
972 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
973 BLUETOOTH_ATT_ERROR_NONE, resp_data,
974 user_info->cb, user_info->user_data);
977 g_byte_array_free(gp_byte_array, TRUE);
978 g_variant_iter_free(iter);
979 g_variant_unref(value);
984 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
987 GDBusConnection *conn;
988 bt_gatt_resp_data_t *resp_data;
989 GVariantBuilder *builder = NULL;
992 BT_CHECK_PARAMETER(chr, return);
993 BT_CHECK_ENABLED(return);
995 conn = _bt_gdbus_get_system_gconn();
996 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
998 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
999 resp_data->user_data = user_data;
1001 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1004 g_variant_builder_add(builder, "{sv}", "offset",
1005 g_variant_new("q", offset));
1007 /* Device Object path*/
1008 // g_variant_builder_add(builder, "{sv}", "device",
1009 // g_variant_new_object("o", NULL));
1011 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1012 "ReadValue", g_variant_new("(a{sv})", builder),
1013 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1014 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1015 (gpointer)resp_data);
1016 g_variant_builder_unref(builder);
1018 return BLUETOOTH_ERROR_NONE;
1021 static void __bluetooth_internal_write_cb(GObject *source_object,
1022 GAsyncResult *res, gpointer user_data)
1024 GError *error = NULL;
1025 GDBusConnection *system_gconn = NULL;
1026 bt_user_info_t *user_info;
1029 bt_gatt_resp_data_t *resp_data = user_data;
1031 system_gconn = _bt_gdbus_get_system_gconn();
1032 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1034 user_info = _bt_get_user_data(BT_COMMON);
1038 BT_ERR("Error : %s", error->message);
1039 g_clear_error(&error);
1042 g_variant_unref(value);
1047 att_ecode = __bluetooth_get_att_error_code(error);
1048 g_clear_error(&error);
1050 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1051 att_ecode, resp_data,
1052 user_info->cb, user_info->user_data);
1057 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1058 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1059 user_info->cb, user_info->user_data);
1062 g_variant_unref(value);
1066 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1067 const char *char_handle, const guint8 *value, int length)
1069 GVariant *val, *options;
1070 GVariantBuilder *builder1;
1071 GVariantBuilder *builder2;
1072 GError *error = NULL;
1073 GDBusConnection *conn;
1078 BT_CHECK_PARAMETER(char_handle, return);
1079 BT_CHECK_PARAMETER(value, return);
1080 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1081 BT_CHECK_ENABLED(return);
1083 conn = _bt_gdbus_get_system_gconn();
1084 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1086 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1087 for (i = 0; i < length; i++)
1088 g_variant_builder_add(builder1, "y", value[i]);
1090 val = g_variant_new("ay", builder1);
1092 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1094 g_variant_builder_add(builder2, "{sv}", "offset",
1095 g_variant_new_uint16(offset));
1097 /* Device Object path*/
1098 // g_variant_builder_add(builder2, "{sv}", "device",
1099 // g_variant_new_object("o", NULL));
1101 options = g_variant_new("a{sv}", builder2);
1103 g_dbus_connection_call(conn,
1106 GATT_CHAR_INTERFACE,
1108 g_variant_new("(@ay@a{sv})",
1111 G_DBUS_CALL_FLAGS_NONE,
1113 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1118 BT_ERR("Set value Failed: %s", error->message);
1119 g_clear_error(&error);
1120 g_variant_builder_unref(builder1);
1121 return BLUETOOTH_ERROR_INTERNAL;
1123 g_variant_builder_unref(builder1);
1124 g_variant_builder_unref(builder2);
1127 return BLUETOOTH_ERROR_NONE;
1130 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1131 const char *chr, const guint8 *value, int length,
1132 guint8 write_type, gpointer user_data)
1134 GVariant *val, *options;
1135 GVariantBuilder *builder1;
1136 GVariantBuilder *builder2;
1137 GDBusConnection *conn;
1140 int ret = BLUETOOTH_ERROR_NONE;
1141 bt_gatt_resp_data_t *resp_data;
1143 BT_CHECK_PARAMETER(chr, return);
1144 BT_CHECK_PARAMETER(value, return);
1145 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1146 BT_CHECK_ENABLED_INTERNAL(return);
1148 conn = _bt_gdbus_get_system_gconn();
1149 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1151 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1153 for (i = 0; i < length; i++)
1154 g_variant_builder_add(builder1, "y", value[i]);
1156 val = g_variant_new("ay", builder1);
1158 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1160 g_variant_builder_add(builder2, "{sv}", "offset",
1161 g_variant_new_uint16(offset));
1163 /* Device Object path*/
1164 // g_variant_builder_add(builder2, "{sv}", "device",
1165 // g_variant_new_object("o", NULL));
1167 options = g_variant_new("a{sv}", builder2);
1169 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1170 resp_data->user_data = user_data;
1172 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1174 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1176 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1177 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1178 (gpointer)resp_data);
1180 g_variant_builder_unref(builder1);
1181 g_variant_builder_unref(builder2);
1186 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1187 const char *char_handle, const guint8 *value, int length)
1189 GVariant *val, *options;
1190 GDBusConnection *conn;
1191 GVariantBuilder *builder1;
1192 GVariantBuilder *builder2;
1197 BT_CHECK_PARAMETER(char_handle, return);
1198 BT_CHECK_PARAMETER(value, return);
1199 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1200 BT_CHECK_ENABLED(return);
1202 conn = _bt_gdbus_get_system_gconn();
1203 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1205 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1207 for (i = 0; i < length; i++) {
1208 g_variant_builder_add(builder1, "y", value[i]);
1209 BT_DBG("value [] = %d", value[i]);
1212 val = g_variant_new("ay", builder1);
1214 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1216 g_variant_builder_add(builder2, "{sv}", "offset",
1217 g_variant_new_uint16(offset));
1219 /* Device Object path*/
1220 // g_variant_builder_add(builder2, "{sv}", "device",
1221 // g_variant_new_object("o", NULL));
1223 options = g_variant_new("a{sv}", builder2);
1225 g_dbus_connection_call(conn,
1228 GATT_CHAR_INTERFACE,
1230 g_variant_new("(@ay@a{sv})",
1233 G_DBUS_CALL_FLAGS_NONE,
1235 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1238 g_variant_builder_unref(builder1);
1239 g_variant_builder_unref(builder2);
1242 return BLUETOOTH_ERROR_NONE;
1245 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1246 bt_gatt_char_property_t *characteristic)
1249 GDBusProxy *properties_proxy = NULL;
1250 GError *error = NULL;
1251 GVariant *value = NULL;
1252 GVariant *result = NULL;
1253 GDBusConnection *g_conn;
1254 int i, ret = BLUETOOTH_ERROR_NONE;
1255 const char *uuid = NULL;
1257 GVariantIter *desc_value_iter, *property_iter;
1259 char_descriptor_type_t desc_type = TYPE_NONE;
1261 g_conn = _bt_gdbus_get_system_gconn();
1262 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1264 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1265 G_DBUS_PROXY_FLAGS_NONE, NULL,
1268 BT_PROPERTIES_INTERFACE,
1271 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1273 result = g_dbus_proxy_call_sync(properties_proxy,
1275 g_variant_new("(s)", GATT_DESC_INTERFACE),
1276 G_DBUS_CALL_FLAGS_NONE,
1282 if (error != NULL) {
1283 BT_ERR("Fail to get properties (Error: %s)", error->message);
1284 g_clear_error(&error);
1286 BT_ERR("Fail to get properties");
1287 g_object_unref(properties_proxy);
1288 return BLUETOOTH_ERROR_INTERNAL;
1290 g_variant_get(result, "(a{sv})", &property_iter);
1291 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1292 if (!g_strcmp0(key, "UUID")) {
1293 uuid = g_variant_get_string(value, &len);
1294 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1295 BT_DBG("GATT_USER_DESC_UUID");
1296 desc_type = USER_DESC;
1297 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1298 BT_DBG("GATT_CHAR_FORMAT");
1299 desc_type = CHAR_FORMAT;
1300 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1301 BT_DBG("GATT_CHAR_CLIENT_CONF");
1302 desc_type = CLIENT_CONF;
1303 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1304 BT_DBG("GATT_CHAR_SERVER_CONF");
1305 desc_type = SERVER_CONF;
1307 BT_DBG("descriptor uuid = %s", uuid);
1309 } else if (!g_strcmp0(key, "Value")) {
1310 switch (desc_type) {
1312 BT_DBG("Format descriptor");
1313 g_variant_get(value, "(yyqyq)",
1314 &(characteristic->format.format),
1315 &(characteristic->format.exponent),
1316 &(characteristic->format.unit),
1317 &(characteristic->format.name_space),
1318 &(characteristic->format.description));
1321 BT_DBG("User descriptor");
1322 g_variant_get(value, "ay", &desc_value_iter);
1323 len = g_variant_get_size((GVariant *)desc_value_iter);
1326 characteristic->description = (char *)g_malloc0(len + 1);
1328 for (i = 0; i < len; i++) {
1329 g_variant_iter_loop(desc_value_iter, "y",
1330 &characteristic->description[i]);
1331 BT_DBG("description = %s", characteristic->description);
1333 g_variant_iter_free(desc_value_iter);
1336 BT_DBG(" CLIENT_CONF");
1339 BT_DBG(" SERVER_CONF");
1347 g_variant_iter_free(property_iter);
1348 g_variant_unref(result);
1349 g_object_unref(properties_proxy);
1356 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1357 GAsyncResult *res, gpointer user_data)
1361 GVariant *char_value;
1362 GVariantIter *char_iter;
1364 GError *error = NULL;
1365 bt_user_info_t *user_info;
1366 bt_gatt_char_property_t characteristic = {0, };
1367 int ret = BLUETOOTH_ERROR_INTERNAL;
1369 user_info = _bt_get_user_data(BT_COMMON);
1371 value = g_dbus_proxy_call_finish(proxy, res, &error);
1372 characteristic.handle = user_data;
1374 if (value == NULL) {
1375 if (error != NULL) {
1376 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1377 "message[%s]\n", error->code, error->message);
1378 g_clear_error(&error);
1380 BT_ERR("Get characteristic descriptor failed\n");
1383 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1384 BLUETOOTH_ERROR_INTERNAL, NULL,
1385 user_info->cb, user_info->user_data);
1387 g_free(characteristic.handle);
1388 g_object_unref(proxy);
1392 g_variant_get(value, "(v)", &char_value);
1393 g_variant_get(char_value, "ao", &char_iter);
1395 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1396 BT_DBG("object path of descriptor = %s", char_handle);
1398 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1400 BT_DBG("Descriptor read status [%d]", ret);
1405 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1406 ret, &characteristic, user_info->cb, user_info->user_data);
1408 bluetooth_gatt_free_char_property(&characteristic);
1410 g_free(characteristic.handle);
1411 g_variant_iter_free(char_iter);
1412 g_variant_unref(value);
1416 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1417 const char *characteristic_handle)
1419 GDBusProxy *properties_proxy = NULL;
1420 GDBusConnection *g_conn;
1422 GError *error = NULL;
1424 BT_CHECK_PARAMETER(characteristic_handle, return);
1425 BT_CHECK_ENABLED(return);
1427 g_conn = _bt_gdbus_get_system_gconn();
1428 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1430 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1431 G_DBUS_PROXY_FLAGS_NONE, NULL,
1433 characteristic_handle,
1434 BT_PROPERTIES_INTERFACE,
1437 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1439 handle = g_strdup(characteristic_handle);
1440 g_dbus_proxy_call(properties_proxy,
1442 g_variant_new("(ss)",
1443 GATT_CHAR_INTERFACE, "Descriptors"),
1444 G_DBUS_CALL_FLAGS_NONE,
1446 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1449 return BLUETOOTH_ERROR_NONE;
1452 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1456 GError *error = NULL;
1457 GDBusConnection *system_gconn = NULL;
1459 bt_user_info_t *user_info;
1460 GByteArray *gp_byte_array = NULL;
1464 bt_gatt_resp_data_t *resp_data = user_data;
1468 system_gconn = _bt_gdbus_get_system_gconn();
1469 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1471 user_info = _bt_get_user_data(BT_COMMON);
1475 BT_ERR("Error : %s", error->message);
1476 g_clear_error(&error);
1479 g_variant_unref(value);
1484 att_ecode = __bluetooth_get_att_error_code(error);
1485 g_clear_error(&error);
1487 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1488 att_ecode, resp_data,
1489 user_info->cb, user_info->user_data);
1494 gp_byte_array = g_byte_array_new();
1495 g_variant_get(value, "(ay)", &iter);
1497 while (g_variant_iter_loop(iter, "y", &g_byte))
1498 g_byte_array_append(gp_byte_array, &g_byte, 1);
1500 if (gp_byte_array->len != 0) {
1501 resp_data->len = gp_byte_array->len;
1502 resp_data->value = gp_byte_array->data;
1505 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1506 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1507 user_info->cb, user_info->user_data);
1511 g_byte_array_free(gp_byte_array, TRUE);
1512 g_variant_iter_free(iter);
1513 g_variant_unref(value);
1518 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1521 GDBusConnection *conn;
1522 GVariantBuilder *builder;
1524 bt_gatt_resp_data_t *resp_data;
1528 BT_CHECK_PARAMETER(desc, return);
1529 BT_CHECK_ENABLED(return);
1531 conn = _bt_gdbus_get_system_gconn();
1532 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1534 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1535 resp_data->user_data = user_data;
1537 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1540 g_variant_builder_add(builder, "{sv}", "offset",
1541 g_variant_new("q", offset));
1542 /* Device Object path*/
1543 // g_variant_builder_add(builder, "{sv}", "device",
1544 // g_variant_new("o", serv_info->serv_path));
1546 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1547 "ReadValue", g_variant_new("(a{sv})", builder),
1548 G_VARIANT_TYPE("(ay)"),
1549 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1550 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1551 (gpointer)resp_data);
1552 g_variant_builder_unref(builder);
1555 return BLUETOOTH_ERROR_NONE;
1558 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1559 GAsyncResult *res, gpointer user_data)
1561 GError *error = NULL;
1562 bt_user_info_t *user_info;
1563 GDBusConnection *system_gconn = NULL;
1565 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1566 bt_gatt_resp_data_t *resp_data = user_data;
1570 system_gconn = _bt_gdbus_get_system_gconn();
1571 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1573 user_info = _bt_get_user_data(BT_COMMON);
1577 BT_ERR("Error : %s", error->message);
1578 g_clear_error(&error);
1581 g_variant_unref(value);
1586 att_ecode = __bluetooth_get_att_error_code(error);
1587 g_clear_error(&error);
1589 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1590 att_ecode, resp_data,
1591 user_info->cb, user_info->user_data);
1596 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1597 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1598 user_info->cb, user_info->user_data);
1601 g_variant_unref(value);
1605 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1606 const guint8 *value, int length, gpointer user_data)
1608 GVariant *val, *options;
1609 GDBusConnection *conn;
1610 GVariantBuilder *builder1;
1611 GVariantBuilder *builder2;
1614 bt_gatt_resp_data_t *resp_data;
1618 BT_CHECK_PARAMETER(desc, return);
1619 BT_CHECK_PARAMETER(value, return);
1620 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1621 BT_CHECK_ENABLED(return);
1623 conn = _bt_gdbus_get_system_gconn();
1624 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1626 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1628 for (i = 0; i < length; i++)
1629 g_variant_builder_add(builder1, "y", value[i]);
1631 val = g_variant_new("ay", builder1);
1633 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1635 g_variant_builder_add(builder2, "{sv}", "offset",
1636 g_variant_new_uint16(offset));
1638 /* Device Object path*/
1639 // g_variant_builder_add(builder2, "{sv}", "device",
1640 // g_variant_new_object("o", NULL));
1642 options = g_variant_new("a{sv}", builder2);
1644 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1645 resp_data->user_data = user_data;
1647 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1648 "WriteValue", g_variant_new("(@ay@a{sv})",
1649 val, options), NULL,
1650 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1651 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1652 (gpointer)resp_data);
1654 g_variant_builder_unref(builder1);
1655 g_variant_builder_unref(builder2);
1658 return BLUETOOTH_ERROR_NONE;
1661 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle)
1663 GDBusConnection *conn;
1664 GError *error = NULL;
1665 int ret = BLUETOOTH_ERROR_NONE;
1667 BT_CHECK_PARAMETER(char_handle, return);
1668 BT_CHECK_ENABLED(return);
1670 BT_INFO_C("### Enable CCCD : %s", char_handle);
1672 conn = _bt_gdbus_get_system_gconn();
1673 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1675 g_dbus_connection_call_sync(conn,
1678 GATT_CHAR_INTERFACE,
1682 G_DBUS_CALL_FLAGS_NONE,
1683 GATT_DEFAULT_TIMEOUT, NULL, &error);
1686 g_dbus_error_strip_remote_error(error);
1687 BT_ERR_C("### Watch Failed: %s", error->message);
1688 if (g_strrstr(error->message, "Already notifying"))
1689 ret = BLUETOOTH_ERROR_NONE;
1690 else if (g_strrstr(error->message, "In Progress"))
1691 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1692 else if (g_strrstr(error->message, "Operation is not supported"))
1693 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1694 /*failed because of either Insufficient Authorization or Write Not Permitted */
1695 else if (g_strrstr(error->message, "Write not permitted") ||
1696 g_strrstr(error->message, "Operation Not Authorized"))
1697 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1698 /* failed because of either Insufficient Authentication,
1699 Insufficient Encryption Key Size, or Insufficient Encryption. */
1700 else if (g_strrstr(error->message, "Not paired"))
1701 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1703 ret = BLUETOOTH_ERROR_INTERNAL;
1705 g_clear_error(&error);
1711 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1714 GDBusConnection *conn;
1715 GError *error = NULL;
1716 int ret = BLUETOOTH_ERROR_NONE;
1717 BT_CHECK_PARAMETER(char_handle, return);
1719 BT_CHECK_ENABLED(return);
1721 BT_INFO("Disable CCCD : %s", char_handle);
1723 conn = _bt_gdbus_get_system_gconn();
1724 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1726 g_dbus_connection_call_sync(conn,
1729 GATT_CHAR_INTERFACE,
1733 G_DBUS_CALL_FLAGS_NONE,
1734 GATT_DEFAULT_TIMEOUT, NULL, &error);
1737 BT_ERR("Watch Failed: %s", error->message);
1738 g_clear_error(&error);
1739 ret = BLUETOOTH_ERROR_INTERNAL;