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 #ifdef TIZEN_GATT_CLIENT
32 #include "bluetooth-gatt-client-api.h"
33 #include <arpa/inet.h>
36 #define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
44 } char_descriptor_type_t;
46 static GSList *service_monitor_list = NULL;
48 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
52 BT_CHECK_PARAMETER(svc_pty, return);
54 #ifdef TIZEN_GATT_CLIENT
55 g_free(svc_pty->uuid);
57 g_free(svc_pty->uuid);
58 g_free(svc_pty->handle);
59 g_strfreev(svc_pty->include_handles.handle);
60 g_strfreev(svc_pty->char_handle.handle);
63 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
66 return BLUETOOTH_ERROR_NONE;
69 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
73 BT_CHECK_PARAMETER(char_pty, return);
75 g_free(char_pty->uuid);
76 g_free(char_pty->name);
77 g_free(char_pty->description);
78 g_free(char_pty->val);
79 #ifndef TIZEN_GATT_CLIENT
80 g_free(char_pty->handle);
81 g_strfreev(char_pty->char_desc_handle.handle);
84 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
87 return BLUETOOTH_ERROR_NONE;
90 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
94 BT_CHECK_PARAMETER(desc_pty, return);
96 g_free(desc_pty->uuid);
97 g_free(desc_pty->val);
98 #ifndef TIZEN_GATT_CLIENT
99 g_free(desc_pty->handle);
102 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
105 return BLUETOOTH_ERROR_NONE;
108 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
110 gchar *gp_path = NULL;
117 path = g_malloc0((gp->len + 1) * sizeof(char *));
119 for (i = 0; i < gp->len; i++) {
120 gp_path = g_ptr_array_index(gp, i);
121 path[i] = g_strdup(gp_path);
122 // BT_DBG("path[%d] : [%s]", i, path[i]);
128 gboolean _bluetooth_gatt_check_service_change_watcher_address(
129 const bluetooth_device_address_t *device_addr)
132 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
133 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
135 _bt_convert_addr_type_to_string(device_address,
136 (unsigned char *)device_addr->addr);
138 for (l = service_monitor_list; l != NULL; l = l->next) {
139 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
140 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
141 bluetooth_device_address_t *addr = l->data;
143 _bt_convert_addr_type_to_string(device_address2,
144 (unsigned char *)addr->addr);
145 _bt_convert_addr_string_to_secure_string(secure_address,
147 _bt_convert_addr_string_to_secure_string(secure_address2,
149 BT_INFO("service_monitor_list [%s] - Input [%s]",
150 secure_address2, secure_address);
152 if (!memcmp(device_addr, addr,
153 sizeof(bluetooth_device_address_t)))
160 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
161 const bluetooth_device_address_t *address, gboolean enable)
164 bluetooth_device_address_t *addr = NULL;
165 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
167 _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
168 BT_INFO("Set watcher for %s with %d", secure_address, enable);
170 if (enable == TRUE) {
171 if (_bluetooth_gatt_check_service_change_watcher_address(address)
173 BT_INFO("The watcher is already set");
174 return BLUETOOTH_ERROR_NONE;
177 if (service_monitor_list == NULL)
178 _bt_register_manager_subscribe_signal(TRUE);
180 addr = g_malloc0(sizeof(bluetooth_device_address_t));
181 memcpy(addr, address, sizeof(bluetooth_device_address_t));
183 service_monitor_list =
184 g_slist_append(service_monitor_list, addr);
186 for (l = service_monitor_list; l != NULL; l = l->next) {
189 if (!memcmp(address, addr,
190 sizeof(bluetooth_device_address_t))) {
191 service_monitor_list =
192 g_slist_remove(service_monitor_list, addr);
198 if (service_monitor_list == NULL)
199 _bt_register_manager_subscribe_signal(FALSE);
202 return BLUETOOTH_ERROR_NONE;
205 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
206 bt_gatt_service_property_t *service)
208 GDBusProxy *properties_proxy = NULL;
209 GError *error = NULL;
210 GVariant *result = NULL;
211 GDBusConnection *g_conn;
213 char *char_handle = NULL;
214 GPtrArray *gp_array = NULL ;
215 GVariantIter *property_iter, *char_iter = NULL;
219 BT_CHECK_PARAMETER(service_handle, return);
220 BT_CHECK_PARAMETER(service, return);
221 BT_CHECK_ENABLED(return);
223 g_conn = _bt_gdbus_get_system_gconn();
224 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
226 properties_proxy = g_dbus_proxy_new_sync(g_conn,
227 G_DBUS_PROXY_FLAGS_NONE, NULL,
230 BT_PROPERTIES_INTERFACE,
233 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
235 result = g_dbus_proxy_call_sync(properties_proxy,
237 g_variant_new("(s)", GATT_SERV_INTERFACE),
238 G_DBUS_CALL_FLAGS_NONE,
245 BT_ERR("Fail to get properties (Error: %s)", error->message);
246 g_clear_error(&error);
248 BT_ERR("Fail to get properties");
249 g_object_unref(properties_proxy);
250 return BLUETOOTH_ERROR_INTERNAL;
253 g_variant_get(result, "(a{sv})", &property_iter);
255 memset(service, 0, sizeof(bt_gatt_service_property_t));
257 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
258 if (!g_strcmp0(key, "UUID")) {
260 service->uuid = g_variant_dup_string(value, &len);
261 bluetooth_get_uuid_name(service->uuid, &name);
262 BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
264 } else if (!g_strcmp0(key, "Primary")) {
265 service->primary = g_variant_get_boolean(value);
267 } else if (!g_strcmp0(key, "Includes")) {
268 g_variant_get(value, "ao", &char_iter);
269 if (char_iter != NULL) {
270 gp_array = g_ptr_array_new();
271 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
272 g_ptr_array_add(gp_array, (gpointer)char_handle);
274 if (gp_array->len != 0) {
275 service->include_handles.count = gp_array->len;
276 service->include_handles.handle =
277 __get_string_array_from_gptr_array(gp_array);
279 g_ptr_array_free(gp_array, TRUE);
280 g_variant_iter_free(char_iter);
282 } else if (!g_strcmp0(key, "Characteristics")) {
283 g_variant_get(value, "ao", &char_iter);
284 if (char_iter != NULL) {
285 gp_array = g_ptr_array_new();
286 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
287 g_ptr_array_add(gp_array, (gpointer)char_handle);
289 if (gp_array->len != 0) {
290 service->char_handle.count = gp_array->len;
291 service->char_handle.handle =
292 __get_string_array_from_gptr_array(gp_array);
294 g_ptr_array_free(gp_array, TRUE);
295 g_variant_iter_free(char_iter);
297 BT_DBG("Characteristics count : %d", service->char_handle.count);
301 service->handle = g_strdup(service_handle);
303 g_variant_iter_free(property_iter);
304 g_variant_unref(result);
305 g_object_unref(properties_proxy);
307 return BLUETOOTH_ERROR_NONE;
310 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
311 const bluetooth_device_address_t *address,
312 bt_gatt_handle_info_t *prim_svc)
314 GVariant *result = NULL;
316 GVariantIter *svc_iter;
317 GVariantIter *interface_iter;
318 char *object_path = NULL;
319 char *interface_str = NULL;
320 const gchar *key = NULL;
321 GVariant *value = NULL;
322 GPtrArray *gp_array = NULL;
323 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
324 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
325 int ret = BLUETOOTH_ERROR_INTERNAL;
329 BT_CHECK_PARAMETER(address, return);
330 BT_CHECK_PARAMETER(prim_svc, return);
331 BT_CHECK_ENABLED(return);
333 result = _bt_get_managed_objects();
337 _bt_convert_addr_type_to_string(device_address,
338 (unsigned char *)address->addr);
340 gp_array = g_ptr_array_new();
341 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
343 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
345 if (object_path == NULL)
348 _bt_convert_device_path_to_address(object_path, temp_address);
350 if (g_strcmp0(temp_address, device_address) != 0)
353 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
354 &interface_str, &svc_iter)) {
355 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
358 BT_DBG("[%d] Object Path : %s", idx++, object_path);
359 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
360 if (g_strcmp0(key, "Primary") == 0) {
361 if (g_variant_get_boolean(value))
362 g_ptr_array_add(gp_array, (gpointer)object_path);
368 if (gp_array->len == 0) {
369 BT_ERR("gp_array is NULL");
370 ret = BLUETOOTH_ERROR_NOT_FOUND;
372 ret = BLUETOOTH_ERROR_NONE;
373 prim_svc->count = gp_array->len;
374 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
377 g_ptr_array_free(gp_array, TRUE);
378 g_variant_iter_free(iter);
379 g_variant_unref(result);
384 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
385 const char *service_uuid,
386 bt_gatt_service_property_t *service)
388 GVariant *result = NULL;
390 GVariantIter *svc_iter;
391 GVariantIter *interface_iter;
392 char *object_path = NULL;
393 char *interface_str = NULL;
394 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
395 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
396 int ret = BLUETOOTH_ERROR_INTERNAL;
398 BT_CHECK_PARAMETER(address, return);
399 BT_CHECK_PARAMETER(service_uuid, return);
400 BT_CHECK_PARAMETER(service, return);
401 BT_CHECK_ENABLED(return);
403 result = _bt_get_managed_objects();
407 _bt_convert_addr_type_to_string(device_address,
408 (unsigned char *)address->addr);
410 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
412 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
414 if (object_path == NULL)
417 _bt_convert_device_path_to_address(object_path,
420 if (g_strcmp0(temp_address, device_address) != 0)
423 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
424 &interface_str, &svc_iter)) {
425 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
428 BT_DBG("Object Path: %s", object_path);
429 ret = bluetooth_gatt_get_service_property(object_path,
432 if (ret != BLUETOOTH_ERROR_NONE) {
433 BT_ERR("Get service property failed(0x%08x)", ret);
435 if (service->primary == TRUE &&
436 g_strstr_len(service->uuid, -1,
438 ret = BLUETOOTH_ERROR_NONE;
442 bluetooth_gatt_free_service_property(service);
447 g_variant_iter_free(iter);
448 g_variant_unref(result);
453 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
454 GAsyncResult *res, gpointer user_data)
457 GVariant *char_value;
458 GVariantIter *char_iter;
459 GPtrArray *gp_array = NULL;
460 bt_gatt_discovered_char_t svc_char = { 0, };
462 GError *error = NULL;
463 bt_user_info_t *user_info;
467 user_info = _bt_get_user_data(BT_COMMON);
468 svc_char.service_handle = user_data;
470 value = g_dbus_proxy_call_finish(proxy, res, &error);
474 BT_ERR("Get service characteristics failed\n errCode[%x],"
475 "message[%s]\n", error->code, error->message);
476 g_clear_error(&error);
478 BT_ERR("Get service characteristics failed\n");
481 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
482 BLUETOOTH_ERROR_INTERNAL, NULL,
483 user_info->cb, user_info->user_data);
485 g_free(svc_char.service_handle);
486 g_object_unref(proxy);
490 g_variant_get(value, "(v)", &char_value);
491 g_variant_get(char_value, "ao", &char_iter);
493 gp_array = g_ptr_array_new();
494 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
495 g_ptr_array_add(gp_array, (gpointer)char_handle);
497 if (gp_array->len != 0) {
498 svc_char.handle_info.count = gp_array->len;
499 svc_char.handle_info.handle =
500 __get_string_array_from_gptr_array(gp_array);
502 g_ptr_array_free(gp_array, TRUE);
505 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
506 BLUETOOTH_ERROR_NONE, &svc_char,
507 user_info->cb, user_info->user_data);
510 g_strfreev(svc_char.handle_info.handle);
511 g_free(svc_char.service_handle);
512 g_variant_iter_free(char_iter);
513 g_variant_unref(value);
514 g_object_unref(proxy);
517 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
518 const char *service_handle)
520 GDBusProxy *properties_proxy = NULL;
521 GDBusConnection *g_conn;
522 GError *error = NULL;
527 BT_CHECK_PARAMETER(service_handle, return);
528 BT_CHECK_ENABLED(return);
530 g_conn = _bt_gdbus_get_system_gconn();
531 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
533 properties_proxy = g_dbus_proxy_new_sync(g_conn,
534 G_DBUS_PROXY_FLAGS_NONE, NULL,
537 BT_PROPERTIES_INTERFACE,
540 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
542 handle = g_strdup(service_handle);
543 g_dbus_proxy_call(properties_proxy,
545 g_variant_new("(ss)",
546 GATT_SERV_INTERFACE, "Characteristics"),
547 G_DBUS_CALL_FLAGS_NONE,
550 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
554 return BLUETOOTH_ERROR_NONE;
558 static int __get_permission_flag(char *permission)
562 retv_if(permission == NULL, ret);
564 if (!g_strcmp0(permission, "broadcast"))
565 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
566 else if (!g_strcmp0(permission, "read"))
567 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
568 else if (!g_strcmp0(permission, "write-without-response"))
569 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
570 else if (!g_strcmp0(permission, "write"))
571 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
572 else if (!g_strcmp0(permission, "notify"))
573 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
574 else if (!g_strcmp0(permission, "indicate"))
575 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
576 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
577 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
578 else if (!g_strcmp0(permission, "reliable-write"))
579 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
580 else if (!g_strcmp0(permission, "writable-auxiliaries"))
581 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
582 else if (!g_strcmp0(permission, "encrypt-read"))
583 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
584 else if (!g_strcmp0(permission, "encrypt-write"))
585 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
586 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
587 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
588 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
589 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
594 static void __convert_permission_flag_to_str(unsigned int permission)
596 char perm[200] = { 0, };
598 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
599 g_strlcat(perm, "broadcast ", sizeof(perm));
600 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
601 g_strlcat(perm, "read ", sizeof(perm));
602 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
603 g_strlcat(perm, "write-without-response ", sizeof(perm));
604 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
605 g_strlcat(perm, "write ", sizeof(perm));
606 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
607 g_strlcat(perm, "notify ", sizeof(perm));
608 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
609 g_strlcat(perm, "indicate ", sizeof(perm));
610 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
611 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
612 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
613 g_strlcat(perm, "reliable-write ", sizeof(perm));
614 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
615 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
616 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
617 g_strlcat(perm, "encrypt-read ", sizeof(perm));
618 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
619 g_strlcat(perm, "encrypt-write ", sizeof(perm));
620 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
621 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
622 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
623 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
625 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
629 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
630 const char *char_handle, bt_gatt_char_property_t *characteristic)
632 GDBusProxy *properties_proxy = NULL;
633 GError *error = NULL;
634 GVariant *value = NULL;
635 GVariant *result = NULL;
636 GByteArray *gb_array = NULL;
637 GPtrArray *gp_array = NULL ;
638 GDBusConnection *g_conn;
642 char *char_desc_handle = NULL;
644 GVariantIter *property_iter;
645 GVariantIter *char_value_iter;
646 GVariantIter *char_perm_iter;
647 GVariantIter *char_desc_iter;
649 BT_CHECK_PARAMETER(char_handle, return);
650 BT_CHECK_PARAMETER(characteristic, return);
652 BT_CHECK_ENABLED(return);
654 g_conn = _bt_gdbus_get_system_gconn();
655 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
657 properties_proxy = g_dbus_proxy_new_sync(g_conn,
658 G_DBUS_PROXY_FLAGS_NONE, NULL,
661 BT_PROPERTIES_INTERFACE,
664 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
666 result = g_dbus_proxy_call_sync(properties_proxy,
668 g_variant_new("(s)", GATT_CHAR_INTERFACE),
669 G_DBUS_CALL_FLAGS_NONE,
676 BT_ERR("Fail to get properties (Error: %s)", error->message);
677 g_clear_error(&error);
679 BT_ERR("Fail to get properties");
680 g_object_unref(properties_proxy);
681 return BLUETOOTH_ERROR_INTERNAL;
684 g_variant_get(result, "(a{sv})", &property_iter);
686 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
687 characteristic->handle = g_strdup(char_handle);
689 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
690 if (!g_strcmp0(key, "UUID")) {
692 characteristic->uuid = g_variant_dup_string(value, &len);
693 bluetooth_get_uuid_name(characteristic->uuid, &name);
694 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
696 } else if (!g_strcmp0(key, "Value")) {
697 gb_array = g_byte_array_new();
698 g_variant_get(value, "ay", &char_value_iter);
699 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
700 // BT_DBG("value of char = %d",char_value);
701 g_byte_array_append(gb_array, &char_value, 1);
703 g_variant_iter_free(char_value_iter);
705 if (gb_array->len != 0) {
706 characteristic->val = g_malloc0(gb_array->len *
707 sizeof(unsigned char));
708 memcpy(characteristic->val, gb_array->data, gb_array->len);
710 characteristic->val_len = gb_array->len;
711 g_byte_array_free(gb_array, TRUE);
712 } else if (!g_strcmp0(key, "Flags")) {
713 g_variant_get(value, "as", &char_perm_iter);
714 characteristic->permission = 0x00;
716 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
717 characteristic->permission |= __get_permission_flag(permission);
718 __convert_permission_flag_to_str(characteristic->permission);
720 g_variant_iter_free(char_perm_iter);
721 } else if (!g_strcmp0(key, "Descriptors")) {
722 g_variant_get(value, "ao", &char_desc_iter);
723 gp_array = g_ptr_array_new();
724 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
725 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
727 g_variant_iter_free(char_desc_iter);
728 if (gp_array->len != 0) {
729 characteristic->char_desc_handle.count = gp_array->len;
730 characteristic->char_desc_handle.handle =
731 __get_string_array_from_gptr_array(gp_array);
733 g_ptr_array_free(gp_array, TRUE);
737 g_variant_iter_free(property_iter);
738 g_variant_unref(result);
739 g_object_unref(properties_proxy);
741 return BLUETOOTH_ERROR_NONE;
744 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
745 GAsyncResult *res, gpointer user_data)
748 GVariantIter *char_iter;
750 GError *error = NULL;
751 bt_user_info_t *user_info;
752 int ret = BLUETOOTH_ERROR_INTERNAL;
753 bt_gatt_char_property_t characteristic;
755 user_info = _bt_get_user_data(BT_COMMON);
757 value = g_dbus_proxy_call_finish(proxy, res, &error);
761 BT_ERR("Get service characteristics failed\n errCode[%x],"
762 "message[%s]\n", error->code, error->message);
763 g_clear_error(&error);
765 BT_ERR("Get service characteristics failed\n");
768 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
769 BLUETOOTH_ERROR_INTERNAL, NULL,
770 user_info->cb, user_info->user_data);
772 g_object_unref(proxy);
777 g_variant_get(value, "(ao)", &char_iter);
779 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
782 ret = bluetooth_gatt_get_characteristics_property(char_handle,
785 if (ret != BLUETOOTH_ERROR_NONE) {
786 BT_ERR("Get characteristic property failed(0x%08x)", ret);
788 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
789 ret = BLUETOOTH_ERROR_NONE;
793 bluetooth_gatt_free_char_property(&characteristic);
797 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
798 &characteristic, user_info->cb, user_info->user_data);
801 bluetooth_gatt_free_char_property(&characteristic);
802 g_variant_iter_free(char_iter);
803 g_variant_unref(value);
807 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
808 const char *char_uuid)
810 GDBusProxy *properties_proxy = NULL;
811 GDBusConnection *g_conn;
812 GError *error = NULL;
815 BT_CHECK_PARAMETER(service_handle, return);
816 BT_CHECK_PARAMETER(char_uuid, return);
817 BT_CHECK_ENABLED(return);
819 g_conn = _bt_gdbus_get_system_gconn();
820 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
822 properties_proxy = g_dbus_proxy_new_sync(g_conn,
823 G_DBUS_PROXY_FLAGS_NONE, NULL,
826 BT_PROPERTIES_INTERFACE,
829 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
831 uuid = g_strdup(char_uuid);
832 g_dbus_proxy_call(properties_proxy,
834 g_variant_new("(ss)",
835 GATT_SERV_INTERFACE, "Characteristics"),
836 G_DBUS_CALL_FLAGS_NONE,
839 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
842 return BLUETOOTH_ERROR_NONE;
845 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
846 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
848 GDBusProxy *properties_proxy = NULL;
849 GError *error = NULL;
850 GDBusConnection *g_conn;
851 GVariant *result = NULL;
852 GVariantIter *property_iter;
856 GVariant *value = NULL;
857 GByteArray *gb_array = NULL;
858 GVariantIter *desc_value_iter;
860 BT_CHECK_PARAMETER(descriptor_handle, return);
861 BT_CHECK_PARAMETER(descriptor, return);
863 BT_CHECK_ENABLED(return);
865 g_conn = _bt_gdbus_get_system_gconn();
866 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
868 properties_proxy = g_dbus_proxy_new_sync(g_conn,
869 G_DBUS_PROXY_FLAGS_NONE, NULL,
872 BT_PROPERTIES_INTERFACE,
875 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
877 result = g_dbus_proxy_call_sync(properties_proxy,
879 g_variant_new("(s)", GATT_DESC_INTERFACE),
880 G_DBUS_CALL_FLAGS_NONE,
887 BT_ERR("Fail to get properties (Error: %s)", error->message);
888 g_clear_error(&error);
890 BT_ERR("Fail to get properties");
891 g_object_unref(properties_proxy);
892 return BLUETOOTH_ERROR_INTERNAL;
895 g_variant_get(result, "(a{sv})", &property_iter);
897 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
898 descriptor->handle = g_strdup(descriptor_handle);
900 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
901 if (!g_strcmp0(key, "UUID")) {
903 descriptor->uuid = g_variant_dup_string(value, &len);
904 bluetooth_get_uuid_name(descriptor->uuid, &name);
905 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
907 } else if (!g_strcmp0(key, "Value")) {
908 gb_array = g_byte_array_new();
909 g_variant_get(value, "ay", &desc_value_iter);
910 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
911 BT_DBG("value of descriptor = %d", char_value);
912 g_byte_array_append(gb_array, &char_value, 1);
914 g_variant_iter_free(desc_value_iter);
916 if (gb_array->len != 0) {
917 descriptor->val = g_malloc0(gb_array->len *
918 sizeof(unsigned char));
919 memcpy(descriptor->val, gb_array->data, gb_array->len);
921 descriptor->val_len = gb_array->len;
922 g_byte_array_free(gb_array, TRUE);
926 g_variant_iter_free(property_iter);
927 g_variant_unref(result);
928 g_object_unref(properties_proxy);
930 return BLUETOOTH_ERROR_NONE;
933 static int __bluetooth_get_att_error_code(GError *error, char *handle)
939 BT_ERR("Error : %s [%s]", error->message, handle + 15);
940 str = g_strrstr(error->message, "ATT error: 0x");
943 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
944 att_ecode += g_ascii_xdigit_value(str[len - 1]);
946 return BLUETOOTH_ATT_ERROR_INTERNAL;
949 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
950 BT_ERR("Read not permitted");
952 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
953 BT_ERR("Write not permitted");
955 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
956 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
957 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
958 BT_ERR("Not paired");
960 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
961 BT_ERR("Invalid offset");
963 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
964 BT_ERR("Invalid Length");
966 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
967 BT_ERR("Operation not Authorized");
970 BT_ERR("default ecode");
974 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
975 BT_ERR("Application error");
980 static void __bluetooth_internal_read_cb(GObject *source_object,
981 GAsyncResult *res, gpointer user_data)
983 GError *error = NULL;
984 GDBusConnection *system_gconn = NULL;
986 bt_user_info_t *user_info;
988 GByteArray *gp_byte_array = NULL;
991 bt_gatt_resp_data_t *resp_data = user_data;
995 system_gconn = _bt_gdbus_get_system_gconn();
996 value = g_dbus_connection_call_finish(system_gconn, res, &error);
998 user_info = _bt_get_user_data(BT_COMMON);
1001 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1002 g_clear_error(&error);
1007 g_variant_unref(value);
1012 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1013 g_clear_error(&error);
1015 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1016 att_ecode, resp_data,
1017 user_info->cb, user_info->user_data);
1022 gp_byte_array = g_byte_array_new();
1023 g_variant_get(value, "(ay)", &iter);
1025 while (g_variant_iter_loop(iter, "y", &g_byte))
1026 g_byte_array_append(gp_byte_array, &g_byte, 1);
1028 if (gp_byte_array->len != 0) {
1029 resp_data->len = gp_byte_array->len;
1030 resp_data->value = gp_byte_array->data;
1033 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1034 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1035 user_info->cb, user_info->user_data);
1038 g_byte_array_free(gp_byte_array, TRUE);
1039 g_variant_iter_free(iter);
1040 g_variant_unref(value);
1045 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1048 GDBusConnection *conn;
1049 bt_gatt_resp_data_t *resp_data;
1050 GVariantBuilder *builder = NULL;
1053 BT_CHECK_PARAMETER(chr, return);
1054 BT_CHECK_ENABLED(return);
1056 conn = _bt_gdbus_get_system_gconn();
1057 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1059 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1060 resp_data->user_data = user_data;
1061 resp_data->handle = (char *)chr;
1063 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1066 g_variant_builder_add(builder, "{sv}", "offset",
1067 g_variant_new("q", offset));
1069 /* Device Object path*/
1070 // g_variant_builder_add(builder, "{sv}", "device",
1071 // g_variant_new_object("o", NULL));
1073 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1074 "ReadValue", g_variant_new("(a{sv})", builder),
1075 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1076 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1077 (gpointer)resp_data);
1078 g_variant_builder_unref(builder);
1080 return BLUETOOTH_ERROR_NONE;
1083 static void __bluetooth_internal_write_cb(GObject *source_object,
1084 GAsyncResult *res, gpointer user_data)
1086 GError *error = NULL;
1087 GDBusConnection *system_gconn = NULL;
1088 bt_user_info_t *user_info;
1091 bt_gatt_resp_data_t *resp_data = user_data;
1093 system_gconn = _bt_gdbus_get_system_gconn();
1094 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1096 user_info = _bt_get_user_data(BT_COMMON);
1099 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1100 g_clear_error(&error);
1105 g_variant_unref(value);
1110 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1111 g_clear_error(&error);
1113 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1114 att_ecode, resp_data,
1115 user_info->cb, user_info->user_data);
1120 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1121 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1122 user_info->cb, user_info->user_data);
1125 g_variant_unref(value);
1129 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1130 const char *char_handle, const guint8 *value, int length)
1132 GVariant *val, *options;
1133 GVariantBuilder *builder1;
1134 GVariantBuilder *builder2;
1135 GError *error = NULL;
1136 GDBusConnection *conn;
1141 BT_CHECK_PARAMETER(char_handle, return);
1142 BT_CHECK_PARAMETER(value, return);
1143 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1144 BT_CHECK_ENABLED(return);
1146 conn = _bt_gdbus_get_system_gconn();
1147 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1149 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1150 for (i = 0; i < length; i++)
1151 g_variant_builder_add(builder1, "y", value[i]);
1153 val = g_variant_new("ay", builder1);
1155 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1157 g_variant_builder_add(builder2, "{sv}", "offset",
1158 g_variant_new_uint16(offset));
1160 /* Device Object path*/
1161 // g_variant_builder_add(builder2, "{sv}", "device",
1162 // g_variant_new_object("o", NULL));
1164 options = g_variant_new("a{sv}", builder2);
1166 g_dbus_connection_call(conn,
1169 GATT_CHAR_INTERFACE,
1171 g_variant_new("(@ay@a{sv})",
1174 G_DBUS_CALL_FLAGS_NONE,
1176 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1181 BT_ERR("Set value Failed: %s", error->message);
1182 g_clear_error(&error);
1183 g_variant_builder_unref(builder1);
1184 return BLUETOOTH_ERROR_INTERNAL;
1186 g_variant_builder_unref(builder1);
1187 g_variant_builder_unref(builder2);
1190 return BLUETOOTH_ERROR_NONE;
1193 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1194 const char *chr, const guint8 *value, int length,
1195 guint8 write_type, gpointer user_data)
1197 GVariant *val, *options;
1198 GVariantBuilder *builder1;
1199 GVariantBuilder *builder2;
1200 GDBusConnection *conn;
1203 int ret = BLUETOOTH_ERROR_NONE;
1204 bt_gatt_resp_data_t *resp_data;
1206 BT_CHECK_PARAMETER(chr, return);
1207 BT_CHECK_PARAMETER(value, return);
1208 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1209 BT_CHECK_ENABLED_INTERNAL(return);
1211 conn = _bt_gdbus_get_system_gconn();
1212 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1214 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1216 for (i = 0; i < length; i++)
1217 g_variant_builder_add(builder1, "y", value[i]);
1219 val = g_variant_new("ay", builder1);
1221 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1223 g_variant_builder_add(builder2, "{sv}", "offset",
1224 g_variant_new_uint16(offset));
1226 /* Device Object path*/
1227 // g_variant_builder_add(builder2, "{sv}", "device",
1228 // g_variant_new_object("o", NULL));
1230 options = g_variant_new("a{sv}", builder2);
1232 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1233 resp_data->user_data = user_data;
1234 resp_data->handle = (char *)chr;
1236 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1238 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1240 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1241 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1242 (gpointer)resp_data);
1244 g_variant_builder_unref(builder1);
1245 g_variant_builder_unref(builder2);
1250 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1251 const char *char_handle, const guint8 *value, int length)
1253 GVariant *val, *options;
1254 GDBusConnection *conn;
1255 GVariantBuilder *builder1;
1256 GVariantBuilder *builder2;
1261 BT_CHECK_PARAMETER(char_handle, return);
1262 BT_CHECK_PARAMETER(value, return);
1263 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1264 BT_CHECK_ENABLED(return);
1266 conn = _bt_gdbus_get_system_gconn();
1267 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1269 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1271 for (i = 0; i < length; i++) {
1272 g_variant_builder_add(builder1, "y", value[i]);
1273 BT_DBG("value [] = %d", value[i]);
1276 val = g_variant_new("ay", builder1);
1278 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1280 g_variant_builder_add(builder2, "{sv}", "offset",
1281 g_variant_new_uint16(offset));
1283 /* Device Object path*/
1284 // g_variant_builder_add(builder2, "{sv}", "device",
1285 // g_variant_new_object("o", NULL));
1287 options = g_variant_new("a{sv}", builder2);
1289 g_dbus_connection_call(conn,
1292 GATT_CHAR_INTERFACE,
1294 g_variant_new("(@ay@a{sv})",
1297 G_DBUS_CALL_FLAGS_NONE,
1299 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1302 g_variant_builder_unref(builder1);
1303 g_variant_builder_unref(builder2);
1306 return BLUETOOTH_ERROR_NONE;
1309 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1310 bt_gatt_char_property_t *characteristic)
1313 GDBusProxy *properties_proxy = NULL;
1314 GError *error = NULL;
1315 GVariant *value = NULL;
1316 GVariant *result = NULL;
1317 GDBusConnection *g_conn;
1318 int i, ret = BLUETOOTH_ERROR_NONE;
1319 const char *uuid = NULL;
1321 GVariantIter *desc_value_iter, *property_iter;
1323 char_descriptor_type_t desc_type = TYPE_NONE;
1325 g_conn = _bt_gdbus_get_system_gconn();
1326 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1328 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1329 G_DBUS_PROXY_FLAGS_NONE, NULL,
1332 BT_PROPERTIES_INTERFACE,
1335 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1337 result = g_dbus_proxy_call_sync(properties_proxy,
1339 g_variant_new("(s)", GATT_DESC_INTERFACE),
1340 G_DBUS_CALL_FLAGS_NONE,
1346 if (error != NULL) {
1347 BT_ERR("Fail to get properties (Error: %s)", error->message);
1348 g_clear_error(&error);
1350 BT_ERR("Fail to get properties");
1351 g_object_unref(properties_proxy);
1352 return BLUETOOTH_ERROR_INTERNAL;
1354 g_variant_get(result, "(a{sv})", &property_iter);
1355 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1356 if (!g_strcmp0(key, "UUID")) {
1357 uuid = g_variant_get_string(value, &len);
1358 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1359 BT_DBG("GATT_USER_DESC_UUID");
1360 desc_type = USER_DESC;
1361 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1362 BT_DBG("GATT_CHAR_FORMAT");
1363 desc_type = CHAR_FORMAT;
1364 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1365 BT_DBG("GATT_CHAR_CLIENT_CONF");
1366 desc_type = CLIENT_CONF;
1367 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1368 BT_DBG("GATT_CHAR_SERVER_CONF");
1369 desc_type = SERVER_CONF;
1371 BT_DBG("descriptor uuid = %s", uuid);
1373 } else if (!g_strcmp0(key, "Value")) {
1374 switch (desc_type) {
1376 BT_DBG("Format descriptor");
1377 g_variant_get(value, "(yyqyq)",
1378 &(characteristic->format.format),
1379 &(characteristic->format.exponent),
1380 &(characteristic->format.unit),
1381 &(characteristic->format.name_space),
1382 &(characteristic->format.description));
1385 BT_DBG("User descriptor");
1386 g_variant_get(value, "ay", &desc_value_iter);
1387 len = g_variant_get_size((GVariant *)desc_value_iter);
1390 characteristic->description = (char *)g_malloc0(len + 1);
1392 for (i = 0; i < len; i++) {
1393 g_variant_iter_loop(desc_value_iter, "y",
1394 &characteristic->description[i]);
1395 BT_DBG("description = %s", characteristic->description);
1397 g_variant_iter_free(desc_value_iter);
1400 BT_DBG(" CLIENT_CONF");
1403 BT_DBG(" SERVER_CONF");
1411 g_variant_iter_free(property_iter);
1412 g_variant_unref(result);
1413 g_object_unref(properties_proxy);
1420 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1421 GAsyncResult *res, gpointer user_data)
1425 GVariant *char_value;
1426 GVariantIter *char_iter;
1428 GError *error = NULL;
1429 bt_user_info_t *user_info;
1430 bt_gatt_char_property_t characteristic = {0, };
1431 int ret = BLUETOOTH_ERROR_INTERNAL;
1433 user_info = _bt_get_user_data(BT_COMMON);
1435 value = g_dbus_proxy_call_finish(proxy, res, &error);
1436 characteristic.handle = user_data;
1438 if (value == NULL) {
1439 if (error != NULL) {
1440 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1441 "message[%s]\n", error->code, error->message);
1442 g_clear_error(&error);
1444 BT_ERR("Get characteristic descriptor failed\n");
1447 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1448 BLUETOOTH_ERROR_INTERNAL, NULL,
1449 user_info->cb, user_info->user_data);
1451 g_free(characteristic.handle);
1452 g_object_unref(proxy);
1456 g_variant_get(value, "(v)", &char_value);
1457 g_variant_get(char_value, "ao", &char_iter);
1459 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1460 BT_DBG("object path of descriptor = %s", char_handle);
1462 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1464 BT_DBG("Descriptor read status [%d]", ret);
1469 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1470 ret, &characteristic, user_info->cb, user_info->user_data);
1472 bluetooth_gatt_free_char_property(&characteristic);
1474 g_variant_iter_free(char_iter);
1475 g_variant_unref(value);
1479 BT_EXPORT_API int bluetooth_gatt_discover_characteristic_descriptor(
1480 const char *characteristic_handle)
1482 GDBusProxy *properties_proxy = NULL;
1483 GDBusConnection *g_conn;
1485 GError *error = NULL;
1487 BT_CHECK_PARAMETER(characteristic_handle, return);
1488 BT_CHECK_ENABLED(return);
1490 g_conn = _bt_gdbus_get_system_gconn();
1491 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1493 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1494 G_DBUS_PROXY_FLAGS_NONE, NULL,
1496 characteristic_handle,
1497 BT_PROPERTIES_INTERFACE,
1500 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1502 handle = g_strdup(characteristic_handle);
1503 g_dbus_proxy_call(properties_proxy,
1505 g_variant_new("(ss)",
1506 GATT_CHAR_INTERFACE, "Descriptors"),
1507 G_DBUS_CALL_FLAGS_NONE,
1509 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1512 return BLUETOOTH_ERROR_NONE;
1515 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1519 GError *error = NULL;
1520 GDBusConnection *system_gconn = NULL;
1522 bt_user_info_t *user_info;
1523 GByteArray *gp_byte_array = NULL;
1527 bt_gatt_resp_data_t *resp_data = user_data;
1531 system_gconn = _bt_gdbus_get_system_gconn();
1532 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1534 user_info = _bt_get_user_data(BT_COMMON);
1537 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1538 g_clear_error(&error);
1543 g_variant_unref(value);
1548 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1549 g_clear_error(&error);
1551 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1552 att_ecode, resp_data,
1553 user_info->cb, user_info->user_data);
1558 gp_byte_array = g_byte_array_new();
1559 g_variant_get(value, "(ay)", &iter);
1561 while (g_variant_iter_loop(iter, "y", &g_byte))
1562 g_byte_array_append(gp_byte_array, &g_byte, 1);
1564 if (gp_byte_array->len != 0) {
1565 resp_data->len = gp_byte_array->len;
1566 resp_data->value = gp_byte_array->data;
1569 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1570 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1571 user_info->cb, user_info->user_data);
1575 g_byte_array_free(gp_byte_array, TRUE);
1576 g_variant_iter_free(iter);
1577 g_variant_unref(value);
1582 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1585 GDBusConnection *conn;
1586 GVariantBuilder *builder;
1588 bt_gatt_resp_data_t *resp_data;
1592 BT_CHECK_PARAMETER(desc, return);
1593 BT_CHECK_ENABLED(return);
1595 conn = _bt_gdbus_get_system_gconn();
1596 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1598 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1599 resp_data->user_data = user_data;
1600 resp_data->handle = (char *)desc;
1602 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1605 g_variant_builder_add(builder, "{sv}", "offset",
1606 g_variant_new("q", offset));
1607 /* Device Object path*/
1608 // g_variant_builder_add(builder, "{sv}", "device",
1609 // g_variant_new("o", serv_info->serv_path));
1611 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1612 "ReadValue", g_variant_new("(a{sv})", builder),
1613 G_VARIANT_TYPE("(ay)"),
1614 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1615 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1616 (gpointer)resp_data);
1617 g_variant_builder_unref(builder);
1620 return BLUETOOTH_ERROR_NONE;
1623 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1624 GAsyncResult *res, gpointer user_data)
1626 GError *error = NULL;
1627 bt_user_info_t *user_info;
1628 GDBusConnection *system_gconn = NULL;
1630 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1631 bt_gatt_resp_data_t *resp_data = user_data;
1635 system_gconn = _bt_gdbus_get_system_gconn();
1636 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1638 user_info = _bt_get_user_data(BT_COMMON);
1641 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1642 g_clear_error(&error);
1647 g_variant_unref(value);
1652 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1653 g_clear_error(&error);
1655 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1656 att_ecode, resp_data,
1657 user_info->cb, user_info->user_data);
1662 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1663 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1664 user_info->cb, user_info->user_data);
1667 g_variant_unref(value);
1671 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1672 const guint8 *value, int length, gpointer user_data)
1674 GVariant *val, *options;
1675 GDBusConnection *conn;
1676 GVariantBuilder *builder1;
1677 GVariantBuilder *builder2;
1680 bt_gatt_resp_data_t *resp_data;
1684 BT_CHECK_PARAMETER(desc, return);
1685 BT_CHECK_PARAMETER(value, return);
1686 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1687 BT_CHECK_ENABLED(return);
1689 conn = _bt_gdbus_get_system_gconn();
1690 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1692 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1694 for (i = 0; i < length; i++)
1695 g_variant_builder_add(builder1, "y", value[i]);
1697 val = g_variant_new("ay", builder1);
1699 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1701 g_variant_builder_add(builder2, "{sv}", "offset",
1702 g_variant_new_uint16(offset));
1704 /* Device Object path*/
1705 // g_variant_builder_add(builder2, "{sv}", "device",
1706 // g_variant_new_object("o", NULL));
1708 options = g_variant_new("a{sv}", builder2);
1710 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1711 resp_data->user_data = user_data;
1712 resp_data->handle = (char *)desc;
1714 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1715 "WriteValue", g_variant_new("(@ay@a{sv})",
1716 val, options), NULL,
1717 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1718 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1719 (gpointer)resp_data);
1721 g_variant_builder_unref(builder1);
1722 g_variant_builder_unref(builder2);
1725 return BLUETOOTH_ERROR_NONE;
1728 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1730 GDBusConnection *conn;
1731 GError *error = NULL;
1732 int ret = BLUETOOTH_ERROR_NONE;
1734 BT_CHECK_PARAMETER(char_handle, return);
1735 BT_CHECK_ENABLED(return);
1737 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
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 g_dbus_error_strip_remote_error(error);
1754 BT_ERR_C("### Watch Failed: %s", error->message);
1755 if (g_strrstr(error->message, "Already notifying"))
1756 ret = BLUETOOTH_ERROR_NONE;
1757 else if (g_strrstr(error->message, "In Progress"))
1758 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1759 else if (g_strrstr(error->message, "Operation is not supported"))
1760 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1761 /*failed because of either Insufficient Authorization or Write Not Permitted */
1762 else if (g_strrstr(error->message, "Write not permitted") ||
1763 g_strrstr(error->message, "Operation Not Authorized"))
1764 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1765 /* failed because of either Insufficient Authentication,
1766 Insufficient Encryption Key Size, or Insufficient Encryption. */
1767 else if (g_strrstr(error->message, "Not paired"))
1768 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1770 ret = BLUETOOTH_ERROR_INTERNAL;
1772 g_clear_error(&error);
1778 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1780 GDBusConnection *conn;
1781 GError *error = NULL;
1782 int ret = BLUETOOTH_ERROR_NONE;
1783 BT_CHECK_PARAMETER(char_handle, return);
1785 BT_CHECK_ENABLED(return);
1787 BT_INFO("Disable CCCD : %s", char_handle);
1789 conn = _bt_gdbus_get_system_gconn();
1790 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1792 g_dbus_connection_call_sync(conn,
1795 GATT_CHAR_INTERFACE,
1799 G_DBUS_CALL_FLAGS_NONE,
1800 GATT_DEFAULT_TIMEOUT, NULL, &error);
1803 BT_ERR("Watch Failed: %s", error->message);
1804 g_clear_error(&error);
1805 ret = BLUETOOTH_ERROR_INTERNAL;
1811 #ifdef TIZEN_GATT_CLIENT
1812 void __bt_uuid_hex_to_string(unsigned char *uuid, char *str)
1814 uint32_t uuid0, uuid4;
1815 uint16_t uuid1, uuid2, uuid3, uuid5;
1817 memcpy(&uuid0, &(uuid[0]), 4);
1818 memcpy(&uuid1, &(uuid[4]), 2);
1819 memcpy(&uuid2, &(uuid[6]), 2);
1820 memcpy(&uuid3, &(uuid[8]), 2);
1821 memcpy(&uuid4, &(uuid[10]), 4);
1822 memcpy(&uuid5, &(uuid[14]), 2);
1824 snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1825 ntohl(uuid0), ntohs(uuid1),
1826 ntohs(uuid2), ntohs(uuid3),
1827 ntohl(uuid4), ntohs(uuid5));
1832 static void __bt_fill_service_handle_informations(bt_services_browse_info_t *props,
1833 bt_gatt_handle_info_t *svcs)
1836 BT_INFO("Total services found [%d]", props->count);
1838 if (props->count == 0)
1841 svcs->count = props->count;
1843 for (count = 0; count < props->count; count++) {
1844 BT_INFO("UUID[%d] = [%s] instance_id [%d] Is Primary [%d]",
1845 count, props->uuids[count], props->inst_id[count], props->primary[count]);
1846 g_strlcpy(svcs->uuids[count], props->uuids[count],
1847 BLUETOOTH_UUID_STRING_MAX);
1848 svcs->inst_id[count] = props->inst_id[count];
1852 static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props,
1853 bt_gatt_service_property_t *service)
1856 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1857 BT_INFO("Total number of characteristics found [%d]",
1860 service->char_handle.count = props->count;
1862 /* Before filling all char handles, fill the service's UUID and instance ID */
1863 __bt_uuid_hex_to_string(props->svc_uuid, uuid_string);
1864 service->uuid = g_strdup(uuid_string);
1865 service->primary = TRUE;
1867 /* Now fill all the char handles [UUID and Instance ID's]*/
1868 for (count = 0; count < props->count; count++) {
1869 BT_INFO("UUID[%d] = [%s] instance_id [%d] properties [%d]",
1870 count, props->uuids[count], props->inst_id[count], props->props[count]);
1872 g_strlcpy(service->char_handle.uuids[count],
1873 props->uuids[count],
1874 BLUETOOTH_UUID_STRING_MAX);
1876 service->char_handle.inst_id[count] = props->inst_id[count];
1880 static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *props,
1881 bt_gatt_char_property_t *charc)
1884 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1885 BT_INFO("Total descriptor count found [%d]", props->count);
1887 charc->char_desc_handle.count = props->count;
1889 /* Before filling all desc handles, fill the charac's UUID and instance ID */
1890 __bt_uuid_hex_to_string(props->char_uuid, uuid_string);
1891 charc->uuid = g_strdup(uuid_string);
1893 /* Now fill all the descriptor handles [UUID and Instance ID's]*/
1894 for (count = 0; count < props->count; count++) {
1895 BT_INFO("UUID[%d] = [%s] instance_id [%d]",
1896 count, props->uuids[count], props->inst_id[count]);
1898 g_strlcpy(charc->char_desc_handle.uuids[count],
1899 props->uuids[count],
1900 BLUETOOTH_UUID_STRING_MAX);
1902 charc->char_desc_handle.inst_id[count] = props->inst_id[count];
1904 charc->permission = props->char_props_map;
1905 BT_INFO("Characteritic property map val [%d]", charc->permission);
1909 BT_EXPORT_API int bluetooth_gatt_client_init(
1911 const bluetooth_device_address_t *address,
1912 gatt_client_cb_func_ptr callback_ptr)
1914 int ret = BLUETOOTH_ERROR_NONE;
1915 bt_event_info_t *event_info;
1918 BT_CHECK_PARAMETER(client_id, return);
1919 BT_CHECK_PARAMETER(callback_ptr, return);
1920 BT_CHECK_ENABLED(return);
1925 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1927 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1929 ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_REGISTER,
1930 in_param1, in_param2, in_param3, in_param4, &out_param);
1932 /* App ID -1 is invalid */
1933 if (ret == BLUETOOTH_ERROR_NONE) {
1935 *client_id = g_array_index(out_param, int, 0);
1937 BT_INFO("GATT Client Registered successfully: Client instance ID [%d]", *client_id);
1939 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
1942 count = (int*)event_info->user_data;
1944 BT_INFO("Total num of GATT client instances [%d]", *count);
1946 /* Increement the count */
1949 BT_INFO("No GATT Client instances found in this application: Set User data");
1950 count = g_malloc0(sizeof(int));
1953 /* Register event handler for GATT */
1954 _bt_register_event(BT_GATT_CLIENT_EVENT,
1955 (void *)callback_ptr,
1957 _bt_set_user_data(BT_GATT_CLIENT, (void *)callback_ptr, NULL);
1960 BT_ERR("GATT Client Registration failed!! ret [%d]", ret);
1962 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1969 BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
1970 const bluetooth_device_address_t *address, /* Remote GATT Server */
1971 bt_gatt_handle_info_t *prim_svc) /* UUID & instance_id */
1974 int result = BLUETOOTH_ERROR_NONE;
1975 bt_services_browse_info_t service_props;
1979 BT_CHECK_PARAMETER(address, return);
1980 BT_CHECK_PARAMETER(prim_svc, return);
1981 BT_CHECK_ENABLED(return);
1984 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1985 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1987 result = _bt_send_request(BT_BLUEZ_SERVICE,
1988 BT_GATT_GET_PRIMARY_SERVICES,
1989 in_param1, in_param2, in_param3, in_param4, &out_param);
1991 if (BLUETOOTH_ERROR_NONE != result)
1994 memset(&service_props, 0x00, sizeof(bt_services_browse_info_t));
1996 service_props = g_array_index(
1997 out_param, bt_services_browse_info_t, 0);
1999 __bt_fill_service_handle_informations(
2000 &service_props, prim_svc);
2003 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2004 BT_DBG("result = %d", result);
2008 BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
2009 const char *address,
2010 bt_gatt_handle_property_t *service_handle,
2011 bt_gatt_service_property_t *service)
2013 int result = BLUETOOTH_ERROR_NONE;
2014 bluetooth_gatt_client_svc_prop_info_t svc_prop;
2015 bt_char_browse_info_t char_handles_info;
2016 BT_INFO("Remote Address [%s]", address);
2018 BT_CHECK_PARAMETER(address, return);
2019 BT_CHECK_PARAMETER(service_handle, return);
2020 BT_CHECK_PARAMETER(service, return);
2021 BT_CHECK_ENABLED(return);
2023 /* Call to bt-service (sync) and send address and service_handle info */
2025 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2027 memset(&svc_prop, 0x00, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2028 /* All characteristics handles are discovered */
2029 memset(&char_handles_info, 0x00, sizeof(bt_char_browse_info_t));
2031 svc_prop.svc.instance_id = service_handle->instance_id;
2032 memcpy(&svc_prop.svc.uuid, &service_handle->uuid, 16);
2034 _bt_convert_addr_string_to_type(svc_prop.device_address.addr, address);
2036 g_array_append_vals(in_param1, &svc_prop, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2038 result = _bt_send_request(BT_BLUEZ_SERVICE,
2039 BT_GATT_GET_SERVICE_PROPERTIES,
2040 in_param1, in_param2, in_param3, in_param4, &out_param);
2042 if (BLUETOOTH_ERROR_NONE != result)
2045 char_handles_info = g_array_index(
2046 out_param, bt_char_browse_info_t, 0);
2047 __bt_fill_char_handle_informations(&char_handles_info,
2049 /* TODO Get all Included Services */
2052 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2053 BT_INFO("result = %d", result);
2057 BT_EXPORT_API int bluetooth_gatt_client_get_characteristics_property(
2058 const char *address,
2059 bt_gatt_handle_property_t *service_handle,
2060 bt_gatt_handle_property_t *char_handle,
2061 bt_gatt_char_property_t *char_property)
2063 int result = BLUETOOTH_ERROR_NONE;
2064 bt_descriptor_browse_info_t desc_handles_info;
2065 bluetooth_gatt_client_char_prop_info_t char_prop;
2066 BT_INFO("Get Properties of characteristics from remote device [%s]", address);
2068 BT_CHECK_PARAMETER(address, return);
2069 BT_CHECK_PARAMETER(service_handle, return);
2070 BT_CHECK_PARAMETER(char_handle, return);
2071 BT_CHECK_PARAMETER(char_property, return);
2072 BT_CHECK_ENABLED(return);
2075 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2077 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2079 memset(&char_prop, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2080 char_prop.svc.instance_id = service_handle->instance_id;
2081 memcpy(&char_prop.svc.uuid, &service_handle->uuid, 16);
2083 char_prop.characteristic.instance_id = char_handle->instance_id;
2084 memcpy(&char_prop.characteristic.uuid, &char_handle->uuid, 16);
2086 _bt_convert_addr_string_to_type(char_prop.device_address.addr, address);
2088 g_array_append_vals(in_param1, &char_prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
2090 result = _bt_send_request(BT_BLUEZ_SERVICE,
2091 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
2092 in_param1, in_param2, in_param3, in_param4, &out_param);
2094 BT_INFO("result = [%d]", result);
2095 if (BLUETOOTH_ERROR_NONE != result)
2098 /* All descriptors handles are discovered */
2099 memset(&desc_handles_info, 0x00, sizeof(bt_descriptor_browse_info_t));
2101 desc_handles_info = g_array_index(
2102 out_param, bt_descriptor_browse_info_t, 0);
2104 __bt_fill_desc_handle_informations(&desc_handles_info,
2108 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2109 BT_INFO("result = %d", result);
2111 /* Call to bt-service (sync) and send address, service_handle & char_handle infos */
2113 /* After result is fetched, extract descriptor handles (UUID's & instance_id's) */
2115 /* Fill the info in *char_prop */
2117 /*No: Before returning, call bluetooth_gatt_client_read_characteristic_value as
2118 an asyn function and leave every thing else in the callback */
2121 BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
2122 const char *address,
2123 bt_gatt_handle_property_t *service_handle,
2124 bt_gatt_handle_property_t *char_handle,
2125 bt_gatt_handle_property_t *descriptor_handle,
2126 bt_gatt_char_descriptor_property_t *desc_prop)
2128 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
2129 BT_DBG("Remote Address [%s]", address);
2131 BT_CHECK_PARAMETER(address, return);
2132 BT_CHECK_PARAMETER(service_handle, return);
2133 BT_CHECK_PARAMETER(char_handle, return);
2134 BT_CHECK_PARAMETER(descriptor_handle, return);
2135 BT_CHECK_PARAMETER(desc_prop, return);
2136 /* No Need to Call to bt-service (sync) and send address, service_handle,
2137 char_handle & descriptor handle infos */
2138 /* After result is fetched, extract descriptior handles (UUID's & instance_id's) */
2139 /* Fill the info in *desc_prop */
2140 __bt_uuid_hex_to_string(descriptor_handle->uuid, uuid_string);
2142 /* Before filling all desc handles, fill the charac's UUID and instance ID */
2143 desc_prop->uuid = g_strdup(uuid_string);
2145 return BLUETOOTH_ERROR_NONE;
2146 /* No: Before returning, call bluetooth_gatt_client_read_descriptor_value
2147 as an asyn function and leave every thing else in the callback */
2150 BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
2151 const char *address,
2152 bt_gatt_handle_property_t *service_handle,
2153 bt_gatt_handle_property_t *char_handle,
2157 int result = BLUETOOTH_ERROR_NONE;
2158 bluetooth_gatt_client_char_prop_info_t param;
2161 BT_CHECK_PARAMETER(address, return);
2162 BT_CHECK_PARAMETER(service_handle, return);
2163 BT_CHECK_PARAMETER(char_handle, return);
2165 /* ASync Function, result expected in callback from bt-service */
2168 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2170 BT_INFO("Address [%s]", address);
2171 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2173 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2174 param.svc.instance_id = service_handle->instance_id;
2176 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2177 param.characteristic.instance_id = char_handle->instance_id;
2179 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2181 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2182 g_array_append_vals(in_param2, &client_id, sizeof(int));
2183 g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
2185 result = _bt_send_request(BT_BLUEZ_SERVICE,
2186 BT_GATT_WATCH_CHARACTERISTIC,
2187 in_param1, in_param2, in_param3, in_param4, &out_param);
2189 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2191 BT_INFO("Result [%d]", result);
2195 BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
2196 const char *address,
2197 bt_gatt_handle_property_t *service_handle,
2198 bt_gatt_handle_property_t *char_handle)
2200 int result = BLUETOOTH_ERROR_NONE;
2201 bt_user_info_t *user_info;
2202 bluetooth_gatt_client_char_prop_info_t param;
2205 BT_CHECK_PARAMETER(address, return);
2206 BT_CHECK_PARAMETER(service_handle, return);
2207 BT_CHECK_PARAMETER(char_handle, return);
2209 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2210 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2213 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2215 /* Async Function, result expected in callback from bt-service */
2216 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2217 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2219 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2220 param.svc.instance_id = service_handle->instance_id;
2222 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2223 param.characteristic.instance_id = char_handle->instance_id;
2225 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2227 g_array_append_vals(in_param1, ¶m,
2228 sizeof(bluetooth_gatt_client_char_prop_info_t));
2231 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_CHARACTERISTIC,
2232 in_param1, in_param2, in_param3, in_param4,
2233 user_info->cb, user_info->user_data);
2236 BT_INFO("result = [%d]", result);
2237 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2241 BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
2242 const char *address,
2243 bt_gatt_handle_property_t *service_handle,
2244 bt_gatt_handle_property_t *char_handle,
2245 bt_gatt_handle_property_t *descriptor_handle)
2247 int result = BLUETOOTH_ERROR_NONE;
2248 bt_user_info_t *user_info;
2249 bluetooth_gatt_client_desc_prop_info_t param;
2252 BT_CHECK_PARAMETER(address, return);
2253 BT_CHECK_PARAMETER(service_handle, return);
2254 BT_CHECK_PARAMETER(char_handle, return);
2255 BT_CHECK_PARAMETER(descriptor_handle, return);
2257 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2258 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2261 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2263 /* Async Function, result expected in callback from bt-service */
2264 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2266 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2267 param.svc.instance_id = service_handle->instance_id;
2269 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2270 param.characteristic.instance_id = char_handle->instance_id;
2272 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2273 param.descriptor.instance_id = descriptor_handle->instance_id;
2275 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2277 g_array_append_vals(in_param1, ¶m,
2278 sizeof(bluetooth_gatt_client_desc_prop_info_t));
2281 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_DESCRIPTOR_VALUE,
2282 in_param1, in_param2, in_param3, in_param4,
2283 user_info->cb, user_info->user_data);
2285 BT_INFO("result = [%d]", result);
2286 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2290 BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
2291 const char *address,
2292 bt_gatt_handle_property_t *service_handle,
2293 bt_gatt_handle_property_t *char_handle,
2294 bluetooth_gatt_att_data_t *data,
2295 bluetooth_gatt_write_type_e write_type)
2297 int result = BLUETOOTH_ERROR_NONE;
2298 bt_user_info_t *user_info;
2299 bluetooth_gatt_client_char_prop_info_t param;
2302 BT_CHECK_PARAMETER(address, return);
2303 BT_CHECK_PARAMETER(service_handle, return);
2304 BT_CHECK_PARAMETER(char_handle, return);
2305 BT_CHECK_PARAMETER(data, return);
2307 /* ASync Function, result expected in callback from bt-service */
2308 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2309 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2312 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2314 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2316 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2317 param.svc.instance_id = service_handle->instance_id;
2319 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2320 param.characteristic.instance_id = char_handle->instance_id;
2322 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2324 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2325 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2326 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2328 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2329 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
2330 in_param1, in_param2, in_param3, in_param4,
2331 user_info->cb, user_info->user_data);
2333 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2338 BT_EXPORT_API int bluetooth_gatt_client_write_descriptor_value(
2339 const char *address,
2340 bt_gatt_handle_property_t *service_handle,
2341 bt_gatt_handle_property_t *char_handle,
2342 bt_gatt_handle_property_t *descriptor_handle,
2343 bluetooth_gatt_att_data_t *data,
2344 bluetooth_gatt_write_type_e write_type)
2346 int result = BLUETOOTH_ERROR_NONE;
2347 bt_user_info_t *user_info;
2348 bluetooth_gatt_client_desc_prop_info_t param;
2351 BT_CHECK_PARAMETER(address, return);
2352 BT_CHECK_PARAMETER(service_handle, return);
2353 BT_CHECK_PARAMETER(char_handle, return);
2354 BT_CHECK_PARAMETER(descriptor_handle, return);
2355 BT_CHECK_PARAMETER(data, return);
2357 /* Async Function, result expected in callback from bt-service */
2358 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2359 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2362 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2364 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2366 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2367 param.svc.instance_id = service_handle->instance_id;
2369 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2370 param.characteristic.instance_id = char_handle->instance_id;
2372 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2373 param.descriptor.instance_id = descriptor_handle->instance_id;
2375 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2377 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2378 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2379 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2381 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2382 BT_GATT_WRITE_DESCRIPTOR_VALUE,
2383 in_param1, in_param2, in_param3, in_param4,
2384 user_info->cb, user_info->user_data);
2386 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2391 BT_EXPORT_API int bluetooth_gatt_client_set_service_change_watcher(
2392 const bluetooth_device_address_t *address, gboolean enable)
2395 bluetooth_device_address_t *addr = NULL;
2396 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2397 int result = BLUETOOTH_ERROR_NONE;
2402 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2404 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
2405 g_array_append_vals(in_param2, &enable, sizeof(gboolean));
2408 _bt_convert_addr_string_to_secure_string(secure_address, (const char *)address->addr);
2409 BT_INFO("Set watcher for %s with %d", secure_address, enable);
2411 if (enable == TRUE) {
2412 if (_bluetooth_gatt_check_service_change_watcher_address(address)
2414 BT_INFO("The watcher is already set");
2415 return BLUETOOTH_ERROR_NONE;
2418 if (service_monitor_list == NULL) {
2419 //_bt_register_manager_subscribe_signal(TRUE);
2421 result = _bt_send_request(BT_BLUEZ_SERVICE,
2422 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2423 in_param1, in_param2, in_param3, in_param4, &out_param);
2426 if (result == BLUETOOTH_ERROR_NONE) {
2427 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2428 memcpy(addr, address, sizeof(bluetooth_device_address_t));
2430 service_monitor_list =
2431 g_slist_append(service_monitor_list, addr);
2434 for (l = service_monitor_list; l != NULL; l = l->next) {
2437 if (!memcmp(address, addr,
2438 sizeof(bluetooth_device_address_t))) {
2439 service_monitor_list =
2440 g_slist_remove(service_monitor_list, addr);
2446 if (service_monitor_list == NULL) {
2447 //_bt_register_manager_subscribe_signal(FALSE);
2448 result = _bt_send_request(BT_BLUEZ_SERVICE,
2449 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2450 in_param1, in_param2, in_param3, in_param4, &out_param);
2455 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2459 BT_EXPORT_API int bluetooth_gatt_client_deinit(
2464 bt_event_info_t *event_info;
2466 BT_CHECK_ENABLED(return);
2468 BT_INFO("GATT Client Deinit Client instance ID [%d]", client_id);
2471 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2473 g_array_append_vals(in_param1, &client_id, sizeof(int));
2475 /* Unregistration MUST NOT FAIL */
2476 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_UNREGISTER,
2477 in_param1, in_param2, in_param3, in_param4, &out_param);
2479 if (result != BLUETOOTH_ERROR_NONE)
2480 BT_INFO("GATT Client Unregistration failed result [%d]", result);
2482 BT_INFO("GATT Client Unregistration successful");
2484 /* Unregister event handler if this is the only instance */
2485 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
2488 count = (int*)event_info->user_data;
2490 BT_INFO("Total num of GATT client instances [%d]", *count);
2493 BT_INFO("Currently only one GATT client instance, so remove it and unregister GATT client events");
2494 _bt_unregister_event(BT_GATT_CLIENT_EVENT);
2495 _bt_set_user_data(BT_GATT_CLIENT, NULL, NULL);
2499 BT_ERR("Impossible that client is created, but no event handler is registered!!!");
2501 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);