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>
24 #include <gio/gunixfdlist.h>
26 #include "bt-common.h"
27 #include "bt-event-handler.h"
28 #include "bt-gatt-client.h"
29 #include "bt-internal-types.h"
30 #include "bt-request-sender.h"
32 #ifdef TIZEN_GATT_CLIENT
33 #include "bluetooth-gatt-client-api.h"
34 #include <arpa/inet.h>
35 static GSList *gatt_characteristic_notify_list;
36 static GSList *gatt_characteristic_write_list = NULL;;
39 #define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
47 } char_descriptor_type_t;
49 static GSList *service_monitor_list = NULL;
51 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
55 BT_CHECK_PARAMETER(svc_pty, return);
57 #ifdef TIZEN_GATT_CLIENT
58 g_free(svc_pty->uuid);
60 g_free(svc_pty->uuid);
61 g_free(svc_pty->handle);
62 g_strfreev(svc_pty->include_handles.handle);
63 g_strfreev(svc_pty->char_handle.handle);
66 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
69 return BLUETOOTH_ERROR_NONE;
72 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
76 BT_CHECK_PARAMETER(char_pty, return);
78 g_free(char_pty->uuid);
79 g_free(char_pty->name);
80 g_free(char_pty->description);
81 g_free(char_pty->val);
82 #ifndef TIZEN_GATT_CLIENT
83 g_free(char_pty->handle);
84 g_strfreev(char_pty->char_desc_handle.handle);
87 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
90 return BLUETOOTH_ERROR_NONE;
93 BT_EXPORT_API int bluetooth_gatt_free_desc_property(bt_gatt_char_descriptor_property_t *desc_pty)
97 BT_CHECK_PARAMETER(desc_pty, return);
99 g_free(desc_pty->uuid);
100 g_free(desc_pty->val);
101 #ifndef TIZEN_GATT_CLIENT
102 g_free(desc_pty->handle);
105 memset(desc_pty, 0, sizeof(bt_gatt_char_descriptor_property_t));
108 return BLUETOOTH_ERROR_NONE;
111 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
113 gchar *gp_path = NULL;
120 path = g_malloc0((gp->len + 1) * sizeof(char *));
122 for (i = 0; i < gp->len; i++) {
123 gp_path = g_ptr_array_index(gp, i);
124 path[i] = g_strdup(gp_path);
125 // BT_DBG("path[%d] : [%s]", i, path[i]);
131 gboolean _bluetooth_gatt_check_service_change_watcher_address(
132 const bluetooth_device_address_t *device_addr)
135 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
136 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
138 _bt_convert_addr_type_to_string(device_address,
139 (unsigned char *)device_addr->addr);
141 for (l = service_monitor_list; l != NULL; l = l->next) {
142 char device_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
143 char secure_address2[BT_ADDRESS_STRING_SIZE] = { 0 };
144 bluetooth_device_address_t *addr = l->data;
146 _bt_convert_addr_type_to_string(device_address2,
147 (unsigned char *)addr->addr);
148 _bt_convert_addr_string_to_secure_string(secure_address,
150 _bt_convert_addr_string_to_secure_string(secure_address2,
152 BT_INFO("service_monitor_list [%s] - Input [%s]",
153 secure_address2, secure_address);
155 if (!memcmp(device_addr, addr,
156 sizeof(bluetooth_device_address_t)))
163 BT_EXPORT_API int bluetooth_gatt_set_service_change_watcher(
164 const bluetooth_device_address_t *address, gboolean enable)
167 bluetooth_device_address_t *addr = NULL;
168 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
170 _bt_convert_addr_type_to_secure_string(secure_address, (unsigned char *)address->addr);
171 BT_INFO("Set watcher for %s with %d", secure_address, enable);
173 if (enable == TRUE) {
174 if (_bluetooth_gatt_check_service_change_watcher_address(address)
176 BT_INFO("The watcher is already set");
177 return BLUETOOTH_ERROR_NONE;
180 if (service_monitor_list == NULL)
181 _bt_register_manager_subscribe_signal(TRUE);
183 addr = g_malloc0(sizeof(bluetooth_device_address_t));
184 memcpy(addr, address, sizeof(bluetooth_device_address_t));
186 service_monitor_list =
187 g_slist_append(service_monitor_list, addr);
189 for (l = service_monitor_list; l != NULL; l = l->next) {
192 if (!memcmp(address, addr,
193 sizeof(bluetooth_device_address_t))) {
194 service_monitor_list =
195 g_slist_remove(service_monitor_list, addr);
201 if (service_monitor_list == NULL)
202 _bt_register_manager_subscribe_signal(FALSE);
205 return BLUETOOTH_ERROR_NONE;
208 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
209 bt_gatt_service_property_t *service)
211 GDBusProxy *properties_proxy = NULL;
212 GError *error = NULL;
213 GVariant *result = NULL;
214 GDBusConnection *g_conn;
216 char *char_handle = NULL;
217 GPtrArray *gp_array = NULL ;
218 GVariantIter *property_iter, *char_iter = NULL;
222 BT_CHECK_PARAMETER(service_handle, return);
223 BT_CHECK_PARAMETER(service, return);
224 BT_CHECK_ENABLED(return);
226 g_conn = _bt_get_system_private_conn();
227 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
229 properties_proxy = g_dbus_proxy_new_sync(g_conn,
230 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
233 BT_PROPERTIES_INTERFACE,
236 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
238 result = g_dbus_proxy_call_sync(properties_proxy,
240 g_variant_new("(s)", GATT_SERV_INTERFACE),
241 G_DBUS_CALL_FLAGS_NONE,
248 BT_ERR("Fail to get properties (Error: %s)", error->message);
249 g_clear_error(&error);
251 BT_ERR("Fail to get properties");
252 g_object_unref(properties_proxy);
253 return BLUETOOTH_ERROR_INTERNAL;
256 g_variant_get(result, "(a{sv})", &property_iter);
258 memset(service, 0, sizeof(bt_gatt_service_property_t));
260 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
261 if (!g_strcmp0(key, "UUID")) {
263 service->uuid = g_variant_dup_string(value, &len);
264 bluetooth_get_uuid_name(service->uuid, &name);
265 BT_INFO("%s %s [%s]", service_handle + 37, service->uuid, name);
267 } else if (!g_strcmp0(key, "Primary")) {
268 service->primary = g_variant_get_boolean(value);
270 } else if (!g_strcmp0(key, "Includes")) {
271 g_variant_get(value, "ao", &char_iter);
272 if (char_iter != NULL) {
273 gp_array = g_ptr_array_new();
274 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
275 g_ptr_array_add(gp_array, (gpointer)char_handle);
277 if (gp_array->len != 0) {
278 service->include_handles.count = gp_array->len;
279 service->include_handles.handle =
280 __get_string_array_from_gptr_array(gp_array);
282 g_ptr_array_free(gp_array, TRUE);
283 g_variant_iter_free(char_iter);
285 } else if (!g_strcmp0(key, "Characteristics")) {
286 g_variant_get(value, "ao", &char_iter);
287 if (char_iter != NULL) {
288 gp_array = g_ptr_array_new();
289 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
290 g_ptr_array_add(gp_array, (gpointer)char_handle);
292 if (gp_array->len != 0) {
293 service->char_handle.count = gp_array->len;
294 service->char_handle.handle =
295 __get_string_array_from_gptr_array(gp_array);
297 g_ptr_array_free(gp_array, TRUE);
298 g_variant_iter_free(char_iter);
300 BT_DBG("Characteristics count : %d", service->char_handle.count);
304 service->handle = g_strdup(service_handle);
306 g_variant_iter_free(property_iter);
307 g_variant_unref(result);
308 g_object_unref(properties_proxy);
310 return BLUETOOTH_ERROR_NONE;
313 BT_EXPORT_API int bluetooth_gatt_get_primary_services(
314 const bluetooth_device_address_t *address,
315 bt_gatt_handle_info_t *prim_svc)
317 GVariant *result = NULL;
319 GVariantIter *svc_iter;
320 GVariantIter *interface_iter;
321 char *object_path = NULL;
322 char *interface_str = NULL;
323 const gchar *key = NULL;
324 GVariant *value = NULL;
325 GPtrArray *gp_array = NULL;
326 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
327 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
328 int ret = BLUETOOTH_ERROR_INTERNAL;
332 BT_CHECK_PARAMETER(address, return);
333 BT_CHECK_PARAMETER(prim_svc, return);
334 BT_CHECK_ENABLED(return);
336 result = _bt_get_managed_objects();
340 _bt_convert_addr_type_to_string(device_address,
341 (unsigned char *)address->addr);
343 gp_array = g_ptr_array_new();
344 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
346 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
348 if (object_path == NULL)
351 _bt_convert_device_path_to_address(object_path, temp_address);
353 if (g_strcmp0(temp_address, device_address) != 0)
356 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
357 &interface_str, &svc_iter)) {
358 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
361 BT_DBG("[%d] Object Path : %s", idx++, object_path);
362 while (g_variant_iter_loop(svc_iter, "{sv}", &key, &value)) {
363 if (g_strcmp0(key, "Primary") == 0) {
364 if (g_variant_get_boolean(value))
365 g_ptr_array_add(gp_array, (gpointer)object_path);
371 if (gp_array->len == 0) {
372 BT_ERR("gp_array is NULL");
373 ret = BLUETOOTH_ERROR_NOT_FOUND;
375 ret = BLUETOOTH_ERROR_NONE;
376 prim_svc->count = gp_array->len;
377 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
380 g_ptr_array_free(gp_array, TRUE);
381 g_variant_iter_free(iter);
382 g_variant_unref(result);
387 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
388 const char *service_uuid,
389 bt_gatt_service_property_t *service)
391 GVariant *result = NULL;
393 GVariantIter *svc_iter;
394 GVariantIter *interface_iter;
395 char *object_path = NULL;
396 char *interface_str = NULL;
397 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
398 char temp_address[BT_ADDRESS_STRING_SIZE] = { 0 };
399 int ret = BLUETOOTH_ERROR_INTERNAL;
401 BT_CHECK_PARAMETER(address, return);
402 BT_CHECK_PARAMETER(service_uuid, return);
403 BT_CHECK_PARAMETER(service, return);
404 BT_CHECK_ENABLED(return);
406 result = _bt_get_managed_objects();
410 _bt_convert_addr_type_to_string(device_address,
411 (unsigned char *)address->addr);
413 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
415 while (g_variant_iter_loop(iter, "{oa{sa{sv}}}", &object_path,
417 if (object_path == NULL)
420 _bt_convert_device_path_to_address(object_path,
423 if (g_strcmp0(temp_address, device_address) != 0)
426 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
427 &interface_str, &svc_iter)) {
428 if (g_strcmp0(interface_str, GATT_SERV_INTERFACE) != 0)
431 BT_DBG("Object Path: %s", object_path);
432 ret = bluetooth_gatt_get_service_property(object_path,
435 if (ret != BLUETOOTH_ERROR_NONE) {
436 BT_ERR("Get service property failed(0x%08x)", ret);
438 if (service->primary == TRUE &&
439 g_strstr_len(service->uuid, -1,
441 ret = BLUETOOTH_ERROR_NONE;
443 /* release resources */
445 g_variant_iter_free(interface_iter);
446 g_free(interface_str);
447 g_variant_iter_free(svc_iter);
452 bluetooth_gatt_free_service_property(service);
457 g_variant_iter_free(iter);
458 g_variant_unref(result);
463 static void __bluetooth_internal_get_char_cb(GDBusProxy *proxy,
464 GAsyncResult *res, gpointer user_data)
467 GVariant *char_value;
468 GVariantIter *char_iter;
469 GPtrArray *gp_array = NULL;
470 bt_gatt_discovered_char_t svc_char = { 0, };
472 GError *error = NULL;
473 bt_user_info_t *user_info;
477 user_info = _bt_get_user_data(BT_COMMON);
478 svc_char.service_handle = user_data;
480 value = g_dbus_proxy_call_finish(proxy, res, &error);
484 BT_ERR("Get service characteristics failed\n errCode[%x],"
485 "message[%s]\n", error->code, error->message);
486 g_clear_error(&error);
488 BT_ERR("Get service characteristics failed\n");
491 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
492 BLUETOOTH_ERROR_INTERNAL, NULL,
493 user_info->cb, user_info->user_data);
495 g_free(svc_char.service_handle);
496 g_object_unref(proxy);
500 g_variant_get(value, "(v)", &char_value);
501 g_variant_get(char_value, "ao", &char_iter);
503 gp_array = g_ptr_array_new();
504 while (g_variant_iter_loop(char_iter, "&o", &char_handle))
505 g_ptr_array_add(gp_array, (gpointer)char_handle);
507 if (gp_array->len != 0) {
508 svc_char.handle_info.count = gp_array->len;
509 svc_char.handle_info.handle =
510 __get_string_array_from_gptr_array(gp_array);
512 g_ptr_array_free(gp_array, TRUE);
515 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
516 BLUETOOTH_ERROR_NONE, &svc_char,
517 user_info->cb, user_info->user_data);
520 g_strfreev(svc_char.handle_info.handle);
521 g_free(svc_char.service_handle);
522 g_variant_iter_free(char_iter);
523 g_variant_unref(value);
524 g_object_unref(proxy);
525 g_variant_unref(char_value);
528 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(
529 const char *service_handle)
531 GDBusProxy *properties_proxy = NULL;
532 GDBusConnection *g_conn;
533 GError *error = NULL;
538 BT_CHECK_PARAMETER(service_handle, return);
539 BT_CHECK_ENABLED(return);
541 g_conn = _bt_get_system_private_conn();
542 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
544 properties_proxy = g_dbus_proxy_new_sync(g_conn,
545 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
548 BT_PROPERTIES_INTERFACE,
551 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
553 handle = g_strdup(service_handle);
554 g_dbus_proxy_call(properties_proxy,
556 g_variant_new("(ss)",
557 GATT_SERV_INTERFACE, "Characteristics"),
558 G_DBUS_CALL_FLAGS_NONE,
561 (GAsyncReadyCallback)__bluetooth_internal_get_char_cb,
565 return BLUETOOTH_ERROR_NONE;
569 static int __get_permission_flag(char *permission)
573 retv_if(permission == NULL, ret);
575 if (!g_strcmp0(permission, "broadcast"))
576 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST;
577 else if (!g_strcmp0(permission, "read"))
578 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
579 else if (!g_strcmp0(permission, "write-without-response"))
580 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
581 else if (!g_strcmp0(permission, "write"))
582 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
583 else if (!g_strcmp0(permission, "notify"))
584 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
585 else if (!g_strcmp0(permission, "indicate"))
586 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE;
587 else if (!g_strcmp0(permission, "authenticated-signed-writes"))
588 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE;
589 else if (!g_strcmp0(permission, "reliable-write"))
590 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE;
591 else if (!g_strcmp0(permission, "writable-auxiliaries"))
592 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES;
593 else if (!g_strcmp0(permission, "encrypt-read"))
594 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ;
595 else if (!g_strcmp0(permission, "encrypt-write"))
596 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE;
597 else if (!g_strcmp0(permission, "encrypt-authenticated-read"))
598 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ;
599 else if (!g_strcmp0(permission, "encrypt-authenticated-write"))
600 ret = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE;
605 static void __convert_permission_flag_to_str(unsigned int permission)
607 char perm[200] = { 0, };
609 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_BROADCAST)
610 g_strlcat(perm, "broadcast ", sizeof(perm));
611 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ)
612 g_strlcat(perm, "read ", sizeof(perm));
613 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE)
614 g_strlcat(perm, "write-without-response ", sizeof(perm));
615 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE)
616 g_strlcat(perm, "write ", sizeof(perm));
617 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_NOTIFY)
618 g_strlcat(perm, "notify ", sizeof(perm));
619 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_INDICATE)
620 g_strlcat(perm, "indicate ", sizeof(perm));
621 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_SIGNED_WRITE)
622 g_strlcat(perm, "authenticated-signed-writes ", sizeof(perm));
623 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_RELIABLE_WRITE)
624 g_strlcat(perm, "reliable-write ", sizeof(perm));
625 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITABLE_AUXILIARIES)
626 g_strlcat(perm, "writable-auxiliaries ", sizeof(perm));
627 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_READ)
628 g_strlcat(perm, "encrypt-read ", sizeof(perm));
629 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_WRITE)
630 g_strlcat(perm, "encrypt-write ", sizeof(perm));
631 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_READ)
632 g_strlcat(perm, "encrypt-authenticated-read ", sizeof(perm));
633 if (permission & BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_ENCRYPT_AUTHENTICATED_WRITE)
634 g_strlcat(perm, "encrypt-authenticated-write ", sizeof(perm));
636 BT_INFO("permission [0x%04x] : %s\n", permission, perm);
640 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(
641 const char *char_handle, bt_gatt_char_property_t *characteristic)
643 GDBusProxy *properties_proxy = NULL;
644 GError *error = NULL;
645 GVariant *value = NULL;
646 GVariant *result = NULL;
647 GByteArray *gb_array = NULL;
648 GPtrArray *gp_array = NULL ;
649 GDBusConnection *g_conn;
653 char *char_desc_handle = NULL;
655 GVariantIter *property_iter;
656 GVariantIter *char_value_iter;
657 GVariantIter *char_perm_iter;
658 GVariantIter *char_desc_iter;
660 BT_CHECK_PARAMETER(char_handle, return);
661 BT_CHECK_PARAMETER(characteristic, return);
663 BT_CHECK_ENABLED(return);
665 g_conn = _bt_get_system_private_conn();
666 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
668 properties_proxy = g_dbus_proxy_new_sync(g_conn,
669 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
672 BT_PROPERTIES_INTERFACE,
675 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
677 result = g_dbus_proxy_call_sync(properties_proxy,
679 g_variant_new("(s)", GATT_CHAR_INTERFACE),
680 G_DBUS_CALL_FLAGS_NONE,
687 BT_ERR("Fail to get properties (Error: %s)", error->message);
688 g_clear_error(&error);
690 BT_ERR("Fail to get properties");
691 g_object_unref(properties_proxy);
692 return BLUETOOTH_ERROR_INTERNAL;
695 g_variant_get(result, "(a{sv})", &property_iter);
697 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
698 characteristic->handle = g_strdup(char_handle);
700 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
701 if (!g_strcmp0(key, "UUID")) {
703 characteristic->uuid = g_variant_dup_string(value, &len);
704 bluetooth_get_uuid_name(characteristic->uuid, &name);
705 BT_INFO("%s %s [%s]", char_handle + 37, characteristic->uuid, name);
707 } else if (!g_strcmp0(key, "Value")) {
708 gb_array = g_byte_array_new();
709 g_variant_get(value, "ay", &char_value_iter);
710 while (g_variant_iter_loop(char_value_iter, "y", &char_value)) {
711 // BT_DBG("value of char = %d",char_value);
712 g_byte_array_append(gb_array, &char_value, 1);
714 g_variant_iter_free(char_value_iter);
716 if (gb_array->len != 0) {
717 characteristic->val = g_malloc0(gb_array->len *
718 sizeof(unsigned char));
719 memcpy(characteristic->val, gb_array->data, gb_array->len);
721 characteristic->val_len = gb_array->len;
722 g_byte_array_free(gb_array, TRUE);
723 } else if (!g_strcmp0(key, "Flags")) {
724 g_variant_get(value, "as", &char_perm_iter);
725 characteristic->permission = 0x00;
727 while (g_variant_iter_loop(char_perm_iter, "s", &permission))
728 characteristic->permission |= __get_permission_flag(permission);
729 __convert_permission_flag_to_str(characteristic->permission);
731 g_variant_iter_free(char_perm_iter);
732 } else if (!g_strcmp0(key, "Descriptors")) {
733 g_variant_get(value, "ao", &char_desc_iter);
734 gp_array = g_ptr_array_new();
735 while (g_variant_iter_loop(char_desc_iter, "&o", &char_desc_handle))
736 g_ptr_array_add(gp_array, (gpointer)char_desc_handle);
738 g_variant_iter_free(char_desc_iter);
739 if (gp_array->len != 0) {
740 characteristic->char_desc_handle.count = gp_array->len;
741 characteristic->char_desc_handle.handle =
742 __get_string_array_from_gptr_array(gp_array);
744 g_ptr_array_free(gp_array, TRUE);
748 g_variant_iter_free(property_iter);
749 g_variant_unref(result);
750 g_object_unref(properties_proxy);
752 return BLUETOOTH_ERROR_NONE;
755 void bluetooth_gatt_get_char_from_uuid_cb(GDBusProxy *proxy,
756 GAsyncResult *res, gpointer user_data)
759 GVariantIter *char_iter;
761 GError *error = NULL;
762 bt_user_info_t *user_info;
763 int ret = BLUETOOTH_ERROR_INTERNAL;
764 bt_gatt_char_property_t characteristic;
766 user_info = _bt_get_user_data(BT_COMMON);
768 value = g_dbus_proxy_call_finish(proxy, res, &error);
772 BT_ERR("Get service characteristics failed\n errCode[%x],"
773 "message[%s]\n", error->code, error->message);
774 g_clear_error(&error);
776 BT_ERR("Get service characteristics failed\n");
779 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
780 BLUETOOTH_ERROR_INTERNAL, NULL,
781 user_info->cb, user_info->user_data);
783 g_object_unref(proxy);
788 g_variant_get(value, "(ao)", &char_iter);
790 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
793 ret = bluetooth_gatt_get_characteristics_property(char_handle,
796 if (ret != BLUETOOTH_ERROR_NONE) {
797 BT_ERR("Get characteristic property failed(0x%08x)", ret);
799 if (g_strstr_len(characteristic.uuid, -1, user_data)) {
800 ret = BLUETOOTH_ERROR_NONE;
804 bluetooth_gatt_free_char_property(&characteristic);
808 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
809 &characteristic, user_info->cb, user_info->user_data);
812 bluetooth_gatt_free_char_property(&characteristic);
813 g_variant_iter_free(char_iter);
814 g_variant_unref(value);
818 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
819 const char *char_uuid)
821 GDBusProxy *properties_proxy = NULL;
822 GDBusConnection *g_conn;
823 GError *error = NULL;
826 BT_CHECK_PARAMETER(service_handle, return);
827 BT_CHECK_PARAMETER(char_uuid, return);
828 BT_CHECK_ENABLED(return);
830 g_conn = _bt_get_system_private_conn();
831 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
833 properties_proxy = g_dbus_proxy_new_sync(g_conn,
834 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
837 BT_PROPERTIES_INTERFACE,
840 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
842 uuid = g_strdup(char_uuid);
843 g_dbus_proxy_call(properties_proxy,
845 g_variant_new("(ss)",
846 GATT_SERV_INTERFACE, "Characteristics"),
847 G_DBUS_CALL_FLAGS_NONE,
850 (GAsyncReadyCallback)bluetooth_gatt_get_char_from_uuid_cb,
853 return BLUETOOTH_ERROR_NONE;
856 BT_EXPORT_API int bluetooth_gatt_get_char_descriptor_property(
857 const char *descriptor_handle, bt_gatt_char_descriptor_property_t *descriptor)
859 GDBusProxy *properties_proxy = NULL;
860 GError *error = NULL;
861 GDBusConnection *g_conn;
862 GVariant *result = NULL;
863 GVariantIter *property_iter;
867 GVariant *value = NULL;
868 GByteArray *gb_array = NULL;
869 GVariantIter *desc_value_iter;
871 BT_CHECK_PARAMETER(descriptor_handle, return);
872 BT_CHECK_PARAMETER(descriptor, return);
874 BT_CHECK_ENABLED(return);
876 g_conn = _bt_get_system_private_conn();
877 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
879 properties_proxy = g_dbus_proxy_new_sync(g_conn,
880 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
883 BT_PROPERTIES_INTERFACE,
886 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
888 result = g_dbus_proxy_call_sync(properties_proxy,
890 g_variant_new("(s)", GATT_DESC_INTERFACE),
891 G_DBUS_CALL_FLAGS_NONE,
898 BT_ERR("Fail to get properties (Error: %s)", error->message);
899 g_clear_error(&error);
901 BT_ERR("Fail to get properties");
902 g_object_unref(properties_proxy);
903 return BLUETOOTH_ERROR_INTERNAL;
906 g_variant_get(result, "(a{sv})", &property_iter);
908 memset(descriptor, 0, sizeof(bt_gatt_char_descriptor_property_t));
909 descriptor->handle = g_strdup(descriptor_handle);
911 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
912 if (!g_strcmp0(key, "UUID")) {
914 descriptor->uuid = g_variant_dup_string(value, &len);
915 bluetooth_get_uuid_name(descriptor->uuid, &name);
916 BT_INFO("Descriptor : %s [%s]", descriptor->uuid, name);
918 } else if (!g_strcmp0(key, "Value")) {
919 gb_array = g_byte_array_new();
920 g_variant_get(value, "ay", &desc_value_iter);
921 while (g_variant_iter_loop(desc_value_iter, "y", &char_value)) {
922 BT_DBG("value of descriptor = %d", char_value);
923 g_byte_array_append(gb_array, &char_value, 1);
925 g_variant_iter_free(desc_value_iter);
927 if (gb_array->len != 0) {
928 descriptor->val = g_malloc0(gb_array->len *
929 sizeof(unsigned char));
930 memcpy(descriptor->val, gb_array->data, gb_array->len);
932 descriptor->val_len = gb_array->len;
933 g_byte_array_free(gb_array, TRUE);
937 g_variant_iter_free(property_iter);
938 g_variant_unref(result);
939 g_object_unref(properties_proxy);
941 return BLUETOOTH_ERROR_NONE;
944 static int __bluetooth_get_att_error_code(GError *error, char *handle)
950 BT_ERR("Error : %s [%s]", error->message, handle + 15);
951 str = g_strrstr(error->message, "ATT error: 0x");
954 att_ecode = g_ascii_xdigit_value(str[len - 2]) << 4;
955 att_ecode += g_ascii_xdigit_value(str[len - 1]);
957 return BLUETOOTH_ATT_ERROR_INTERNAL;
960 case BLUETOOTH_ATT_ERROR_READ_NOT_PERMITTED:
961 BT_ERR("Read not permitted");
963 case BLUETOOTH_ATT_ERROR_WRITE_NOT_PERMITTED:
964 BT_ERR("Write not permitted");
966 case BLUETOOTH_ATT_ERROR_AUTHENTICATION:
967 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION:
968 case BLUETOOTH_ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE:
969 BT_ERR("Not paired");
971 case BLUETOOTH_ATT_ERROR_INVALID_OFFSET:
972 BT_ERR("Invalid offset");
974 case BLUETOOTH_ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LEN:
975 BT_ERR("Invalid Length");
977 case BLUETOOTH_ATT_ERROR_AUTHORIZATION:
978 BT_ERR("Operation not Authorized");
981 BT_ERR("default ecode");
985 if (att_ecode >= 0x80 && att_ecode <= 0x9F)
986 BT_ERR("Application error");
991 static void __bluetooth_internal_read_cb(GObject *source_object,
992 GAsyncResult *res, gpointer user_data)
994 GError *error = NULL;
995 GDBusConnection *system_gconn = NULL;
997 bt_user_info_t *user_info;
999 GByteArray *gp_byte_array = NULL;
1002 bt_gatt_resp_data_t *resp_data = user_data;
1006 system_gconn = _bt_get_system_private_conn();
1007 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1009 user_info = _bt_get_user_data(BT_COMMON);
1012 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1013 g_clear_error(&error);
1018 g_variant_unref(value);
1023 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1024 g_clear_error(&error);
1026 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1027 att_ecode, resp_data,
1028 user_info->cb, user_info->user_data);
1033 gp_byte_array = g_byte_array_new();
1034 g_variant_get(value, "(ay)", &iter);
1036 while (g_variant_iter_loop(iter, "y", &g_byte))
1037 g_byte_array_append(gp_byte_array, &g_byte, 1);
1039 if (gp_byte_array->len != 0) {
1040 resp_data->len = gp_byte_array->len;
1041 resp_data->value = gp_byte_array->data;
1044 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_CHAR,
1045 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1046 user_info->cb, user_info->user_data);
1049 g_byte_array_free(gp_byte_array, TRUE);
1050 g_variant_iter_free(iter);
1051 g_variant_unref(value);
1056 BT_EXPORT_API int bluetooth_gatt_read_characteristic_value(const char *chr,
1059 GDBusConnection *conn;
1060 bt_gatt_resp_data_t *resp_data;
1061 GVariantBuilder *builder = NULL;
1064 BT_CHECK_PARAMETER(chr, return);
1065 BT_CHECK_ENABLED(return);
1067 conn = _bt_get_system_private_conn();
1068 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1070 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1071 resp_data->user_data = user_data;
1072 resp_data->handle = (char *)chr;
1074 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1077 g_variant_builder_add(builder, "{sv}", "offset",
1078 g_variant_new("q", offset));
1080 /* Device Object path*/
1081 // g_variant_builder_add(builder, "{sv}", "device",
1082 // g_variant_new_object("o", NULL));
1084 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1085 "ReadValue", g_variant_new("(a{sv})", builder),
1086 G_VARIANT_TYPE("(ay)"), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1087 (GAsyncReadyCallback)__bluetooth_internal_read_cb,
1088 (gpointer)resp_data);
1089 g_variant_builder_unref(builder);
1091 return BLUETOOTH_ERROR_NONE;
1094 static void __bluetooth_internal_write_cb(GObject *source_object,
1095 GAsyncResult *res, gpointer user_data)
1097 GError *error = NULL;
1098 GDBusConnection *system_gconn = NULL;
1099 bt_user_info_t *user_info;
1102 bt_gatt_resp_data_t *resp_data = user_data;
1104 system_gconn = _bt_get_system_private_conn();
1105 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1107 user_info = _bt_get_user_data(BT_COMMON);
1110 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1111 g_clear_error(&error);
1116 g_variant_unref(value);
1121 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1122 g_clear_error(&error);
1124 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1125 att_ecode, resp_data,
1126 user_info->cb, user_info->user_data);
1131 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_CHAR,
1132 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1133 user_info->cb, user_info->user_data);
1136 g_variant_unref(value);
1140 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(
1141 const char *char_handle, const guint8 *value, int length)
1143 GVariant *val, *options;
1144 GVariantBuilder *builder1;
1145 GVariantBuilder *builder2;
1146 GError *error = NULL;
1147 GDBusConnection *conn;
1152 BT_CHECK_PARAMETER(char_handle, return);
1153 BT_CHECK_PARAMETER(value, return);
1154 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1155 BT_CHECK_ENABLED(return);
1157 conn = _bt_get_system_private_conn();
1158 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1160 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1161 for (i = 0; i < length; i++)
1162 g_variant_builder_add(builder1, "y", value[i]);
1164 val = g_variant_new("ay", builder1);
1166 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1168 g_variant_builder_add(builder2, "{sv}", "offset",
1169 g_variant_new_uint16(offset));
1171 /* Device Object path*/
1172 // g_variant_builder_add(builder2, "{sv}", "device",
1173 // g_variant_new_object("o", NULL));
1175 options = g_variant_new("a{sv}", builder2);
1177 g_dbus_connection_call(conn,
1180 GATT_CHAR_INTERFACE,
1182 g_variant_new("(@ay@a{sv})",
1185 G_DBUS_CALL_FLAGS_NONE,
1187 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1192 BT_ERR("Set value Failed: %s", error->message);
1193 g_clear_error(&error);
1194 g_variant_builder_unref(builder1);
1195 return BLUETOOTH_ERROR_INTERNAL;
1197 g_variant_builder_unref(builder1);
1198 g_variant_builder_unref(builder2);
1201 return BLUETOOTH_ERROR_NONE;
1204 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_by_type(
1205 const char *chr, const guint8 *value, int length,
1206 guint8 write_type, gpointer user_data)
1208 GVariant *val, *options;
1209 GVariantBuilder *builder1;
1210 GVariantBuilder *builder2;
1211 GDBusConnection *conn;
1214 int ret = BLUETOOTH_ERROR_NONE;
1215 bt_gatt_resp_data_t *resp_data;
1217 BT_CHECK_PARAMETER(chr, return);
1218 BT_CHECK_PARAMETER(value, return);
1219 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1220 BT_CHECK_ENABLED_INTERNAL(return);
1222 conn = _bt_get_system_private_conn();
1223 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1225 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1227 for (i = 0; i < length; i++)
1228 g_variant_builder_add(builder1, "y", value[i]);
1230 val = g_variant_new("ay", builder1);
1232 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1234 g_variant_builder_add(builder2, "{sv}", "offset",
1235 g_variant_new_uint16(offset));
1237 /* Device Object path*/
1238 // g_variant_builder_add(builder2, "{sv}", "device",
1239 // g_variant_new_object("o", NULL));
1241 options = g_variant_new("a{sv}", builder2);
1243 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1244 resp_data->user_data = user_data;
1245 resp_data->handle = (char *)chr;
1247 g_dbus_connection_call(conn, BT_BLUEZ_NAME, chr, GATT_CHAR_INTERFACE,
1249 g_variant_new("(y@ay@a{sv})", write_type, val, options),
1251 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1252 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1253 (gpointer)resp_data);
1255 g_variant_builder_unref(builder1);
1256 g_variant_builder_unref(builder2);
1261 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value_request(
1262 const char *char_handle, const guint8 *value, int length)
1264 GVariant *val, *options;
1265 GDBusConnection *conn;
1266 GVariantBuilder *builder1;
1267 GVariantBuilder *builder2;
1272 BT_CHECK_PARAMETER(char_handle, return);
1273 BT_CHECK_PARAMETER(value, return);
1274 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1275 BT_CHECK_ENABLED(return);
1277 conn = _bt_get_system_private_conn();
1278 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1280 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1282 for (i = 0; i < length; i++) {
1283 g_variant_builder_add(builder1, "y", value[i]);
1284 BT_DBG("value [] = %d", value[i]);
1287 val = g_variant_new("ay", builder1);
1289 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1291 g_variant_builder_add(builder2, "{sv}", "offset",
1292 g_variant_new_uint16(offset));
1294 /* Device Object path*/
1295 // g_variant_builder_add(builder2, "{sv}", "device",
1296 // g_variant_new_object("o", NULL));
1298 options = g_variant_new("a{sv}", builder2);
1300 g_dbus_connection_call(conn,
1303 GATT_CHAR_INTERFACE,
1305 g_variant_new("(@ay@a{sv})",
1308 G_DBUS_CALL_FLAGS_NONE,
1310 (GAsyncReadyCallback)__bluetooth_internal_write_cb,
1313 g_variant_builder_unref(builder1);
1314 g_variant_builder_unref(builder2);
1317 return BLUETOOTH_ERROR_NONE;
1320 static int __bluetooth_gatt_descriptor_iter(const char *char_handle,
1321 bt_gatt_char_property_t *characteristic)
1324 GDBusProxy *properties_proxy = NULL;
1325 GError *error = NULL;
1326 GVariant *value = NULL;
1327 GVariant *result = NULL;
1328 GDBusConnection *g_conn;
1329 int i, ret = BLUETOOTH_ERROR_NONE;
1330 const char *uuid = NULL;
1332 GVariantIter *desc_value_iter, *property_iter;
1334 char_descriptor_type_t desc_type = TYPE_NONE;
1336 g_conn = _bt_get_system_private_conn();
1337 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1339 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1340 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
1343 BT_PROPERTIES_INTERFACE,
1346 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1348 result = g_dbus_proxy_call_sync(properties_proxy,
1350 g_variant_new("(s)", GATT_DESC_INTERFACE),
1351 G_DBUS_CALL_FLAGS_NONE,
1357 if (error != NULL) {
1358 BT_ERR("Fail to get properties (Error: %s)", error->message);
1359 g_clear_error(&error);
1361 BT_ERR("Fail to get properties");
1362 g_object_unref(properties_proxy);
1363 return BLUETOOTH_ERROR_INTERNAL;
1365 g_variant_get(result, "(a{sv})", &property_iter);
1366 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
1367 if (!g_strcmp0(key, "UUID")) {
1368 uuid = g_variant_get_string(value, &len);
1369 if (g_strcmp0(uuid, GATT_USER_DESC_UUID) == 0) {
1370 BT_DBG("GATT_USER_DESC_UUID");
1371 desc_type = USER_DESC;
1372 } else if (g_strcmp0(uuid, GATT_CHAR_FORMAT) == 0) {
1373 BT_DBG("GATT_CHAR_FORMAT");
1374 desc_type = CHAR_FORMAT;
1375 } else if (g_strcmp0(uuid, GATT_CHAR_CLIENT_CONF) == 0) {
1376 BT_DBG("GATT_CHAR_CLIENT_CONF");
1377 desc_type = CLIENT_CONF;
1378 } else if (g_strcmp0(uuid, GATT_CHAR_SERVER_CONF) == 0) {
1379 BT_DBG("GATT_CHAR_SERVER_CONF");
1380 desc_type = SERVER_CONF;
1382 BT_DBG("descriptor uuid = %s", uuid);
1384 } else if (!g_strcmp0(key, "Value")) {
1385 switch (desc_type) {
1387 BT_DBG("Format descriptor");
1388 g_variant_get(value, "(yyqyq)",
1389 &(characteristic->format.format),
1390 &(characteristic->format.exponent),
1391 &(characteristic->format.unit),
1392 &(characteristic->format.name_space),
1393 &(characteristic->format.description));
1396 BT_DBG("User descriptor");
1397 g_variant_get(value, "ay", &desc_value_iter);
1398 len = g_variant_get_size((GVariant *)desc_value_iter);
1401 characteristic->description = (char *)g_malloc0(len + 1);
1403 for (i = 0; i < len; i++) {
1404 g_variant_iter_loop(desc_value_iter, "y",
1405 &characteristic->description[i]);
1406 BT_DBG("description = %s", characteristic->description);
1408 g_variant_iter_free(desc_value_iter);
1411 BT_DBG(" CLIENT_CONF");
1414 BT_DBG(" SERVER_CONF");
1422 g_variant_iter_free(property_iter);
1423 g_variant_unref(result);
1424 g_object_unref(properties_proxy);
1431 static void bluetooth_gatt_get_char_desc_cb(GDBusProxy *proxy,
1432 GAsyncResult *res, gpointer user_data)
1436 GVariant *char_value;
1437 GVariantIter *char_iter;
1439 GError *error = NULL;
1440 bt_user_info_t *user_info;
1441 bt_gatt_char_property_t characteristic = {0, };
1442 int ret = BLUETOOTH_ERROR_INTERNAL;
1444 user_info = _bt_get_user_data(BT_COMMON);
1446 value = g_dbus_proxy_call_finish(proxy, res, &error);
1447 characteristic.handle = user_data;
1449 if (value == NULL) {
1450 if (error != NULL) {
1451 BT_ERR("Get characteristic descriptor failed\n errCode[%x],"
1452 "message[%s]\n", error->code, error->message);
1453 g_clear_error(&error);
1455 BT_ERR("Get characteristic descriptor failed\n");
1458 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1459 BLUETOOTH_ERROR_INTERNAL, NULL,
1460 user_info->cb, user_info->user_data);
1462 g_free(characteristic.handle);
1463 g_object_unref(proxy);
1467 g_variant_get(value, "(v)", &char_value);
1468 g_variant_get(char_value, "ao", &char_iter);
1470 while (g_variant_iter_loop(char_iter, "&o", &char_handle)) {
1471 BT_DBG("object path of descriptor = %s", char_handle);
1473 ret = __bluetooth_gatt_descriptor_iter(char_handle,
1475 BT_DBG("Descriptor read status [%d]", ret);
1480 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DESC_DISCOVERED,
1481 ret, &characteristic, user_info->cb, user_info->user_data);
1483 bluetooth_gatt_free_char_property(&characteristic);
1485 g_variant_iter_free(char_iter);
1486 g_variant_unref(value);
1487 g_variant_unref(char_value);
1491 BT_EXPORT_API int bltooth_gatt_discover_characteristic_descriptor(
1492 const char *characteristic_handle)
1494 GDBusProxy *properties_proxy = NULL;
1495 GDBusConnection *g_conn;
1497 GError *error = NULL;
1499 BT_CHECK_PARAMETER(characteristic_handle, return);
1500 BT_CHECK_ENABLED(return);
1502 g_conn = _bt_get_system_private_conn();
1503 retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1505 properties_proxy = g_dbus_proxy_new_sync(g_conn,
1506 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL,
1508 characteristic_handle,
1509 BT_PROPERTIES_INTERFACE,
1512 retv_if(properties_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1514 handle = g_strdup(characteristic_handle);
1515 g_dbus_proxy_call(properties_proxy,
1517 g_variant_new("(ss)",
1518 GATT_CHAR_INTERFACE, "Descriptors"),
1519 G_DBUS_CALL_FLAGS_NONE,
1521 (GAsyncReadyCallback)bluetooth_gatt_get_char_desc_cb,
1524 return BLUETOOTH_ERROR_NONE;
1527 static void __bluetooth_internal_read_desc_cb(GObject *source_object,
1531 GError *error = NULL;
1532 GDBusConnection *system_gconn = NULL;
1534 bt_user_info_t *user_info;
1535 GByteArray *gp_byte_array = NULL;
1539 bt_gatt_resp_data_t *resp_data = user_data;
1543 system_gconn = _bt_get_system_private_conn();
1544 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1546 user_info = _bt_get_user_data(BT_COMMON);
1549 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1550 g_clear_error(&error);
1555 g_variant_unref(value);
1560 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1561 g_clear_error(&error);
1563 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1564 att_ecode, resp_data,
1565 user_info->cb, user_info->user_data);
1570 gp_byte_array = g_byte_array_new();
1571 g_variant_get(value, "(ay)", &iter);
1573 while (g_variant_iter_loop(iter, "y", &g_byte))
1574 g_byte_array_append(gp_byte_array, &g_byte, 1);
1576 if (gp_byte_array->len != 0) {
1577 resp_data->len = gp_byte_array->len;
1578 resp_data->value = gp_byte_array->data;
1581 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_READ_DESC,
1582 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1583 user_info->cb, user_info->user_data);
1587 g_byte_array_free(gp_byte_array, TRUE);
1588 g_variant_iter_free(iter);
1589 g_variant_unref(value);
1594 BT_EXPORT_API int bluetooth_gatt_read_descriptor_value(const char *desc,
1597 GDBusConnection *conn;
1598 GVariantBuilder *builder;
1600 bt_gatt_resp_data_t *resp_data;
1604 BT_CHECK_PARAMETER(desc, return);
1605 BT_CHECK_ENABLED(return);
1607 conn = _bt_get_system_private_conn();
1608 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1610 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1611 resp_data->user_data = user_data;
1612 resp_data->handle = (char *)desc;
1614 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1617 g_variant_builder_add(builder, "{sv}", "offset",
1618 g_variant_new("q", offset));
1619 /* Device Object path*/
1620 // g_variant_builder_add(builder, "{sv}", "device",
1621 // g_variant_new("o", serv_info->serv_path));
1623 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1624 "ReadValue", g_variant_new("(a{sv})", builder),
1625 G_VARIANT_TYPE("(ay)"),
1626 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1627 (GAsyncReadyCallback)__bluetooth_internal_read_desc_cb,
1628 (gpointer)resp_data);
1629 g_variant_builder_unref(builder);
1632 return BLUETOOTH_ERROR_NONE;
1635 static void __bluetooth_internal_write_desc_cb(GObject *source_object,
1636 GAsyncResult *res, gpointer user_data)
1638 GError *error = NULL;
1639 bt_user_info_t *user_info;
1640 GDBusConnection *system_gconn = NULL;
1642 int att_ecode = BLUETOOTH_ATT_ERROR_NONE;
1643 bt_gatt_resp_data_t *resp_data = user_data;
1647 system_gconn = _bt_get_system_private_conn();
1648 value = g_dbus_connection_call_finish(system_gconn, res, &error);
1650 user_info = _bt_get_user_data(BT_COMMON);
1653 BT_ERR("Error : %s [%s]", error->message, resp_data->handle + 15);
1654 g_clear_error(&error);
1659 g_variant_unref(value);
1664 att_ecode = __bluetooth_get_att_error_code(error, resp_data->handle);
1665 g_clear_error(&error);
1667 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1668 att_ecode, resp_data,
1669 user_info->cb, user_info->user_data);
1674 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_WRITE_DESC,
1675 BLUETOOTH_ATT_ERROR_NONE, resp_data,
1676 user_info->cb, user_info->user_data);
1679 g_variant_unref(value);
1683 BT_EXPORT_API int bluetooth_gatt_write_descriptor_value(const char *desc,
1684 const guint8 *value, int length, gpointer user_data)
1686 GVariant *val, *options;
1687 GDBusConnection *conn;
1688 GVariantBuilder *builder1;
1689 GVariantBuilder *builder2;
1692 bt_gatt_resp_data_t *resp_data;
1696 BT_CHECK_PARAMETER(desc, return);
1697 BT_CHECK_PARAMETER(value, return);
1698 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
1699 BT_CHECK_ENABLED(return);
1701 conn = _bt_get_system_private_conn();
1702 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1704 builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
1706 for (i = 0; i < length; i++)
1707 g_variant_builder_add(builder1, "y", value[i]);
1709 val = g_variant_new("ay", builder1);
1711 builder2 = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1713 g_variant_builder_add(builder2, "{sv}", "offset",
1714 g_variant_new_uint16(offset));
1716 /* Device Object path*/
1717 // g_variant_builder_add(builder2, "{sv}", "device",
1718 // g_variant_new_object("o", NULL));
1720 options = g_variant_new("a{sv}", builder2);
1722 resp_data = g_malloc0(sizeof(bt_gatt_resp_data_t));
1723 resp_data->user_data = user_data;
1724 resp_data->handle = (char *)desc;
1726 g_dbus_connection_call(conn, BT_BLUEZ_NAME, desc, GATT_DESC_INTERFACE,
1727 "WriteValue", g_variant_new("(@ay@a{sv})",
1728 val, options), NULL,
1729 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1730 (GAsyncReadyCallback)__bluetooth_internal_write_desc_cb,
1731 (gpointer)resp_data);
1733 g_variant_builder_unref(builder1);
1734 g_variant_builder_unref(builder2);
1737 return BLUETOOTH_ERROR_NONE;
1740 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *char_handle, const char *svc_name)
1742 GDBusConnection *conn;
1743 GError *error = NULL;
1744 int ret = BLUETOOTH_ERROR_NONE;
1746 BT_CHECK_PARAMETER(char_handle, return);
1747 BT_CHECK_ENABLED(return);
1749 BT_INFO_C("### Enable CCCD : %s [%s]", char_handle + 15, svc_name);
1751 conn = _bt_get_system_private_conn();
1752 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1754 g_dbus_connection_call_sync(conn,
1757 GATT_CHAR_INTERFACE,
1761 G_DBUS_CALL_FLAGS_NONE,
1762 GATT_DEFAULT_TIMEOUT, NULL, &error);
1765 g_dbus_error_strip_remote_error(error);
1766 BT_ERR_C("### Watch Failed: %s", error->message);
1767 if (g_strrstr(error->message, "Already notifying"))
1768 ret = BLUETOOTH_ERROR_NONE;
1769 else if (g_strrstr(error->message, "In Progress"))
1770 ret = BLUETOOTH_ERROR_IN_PROGRESS;
1771 else if (g_strrstr(error->message, "Operation is not supported"))
1772 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
1773 /*failed because of either Insufficient Authorization or Write Not Permitted */
1774 else if (g_strrstr(error->message, "Write not permitted") ||
1775 g_strrstr(error->message, "Operation Not Authorized"))
1776 ret = BLUETOOTH_ERROR_PERMISSION_DEINED;
1777 /* failed because of either Insufficient Authentication,
1778 Insufficient Encryption Key Size, or Insufficient Encryption. */
1779 else if (g_strrstr(error->message, "Not paired"))
1780 ret = BLUETOOTH_ERROR_NOT_PAIRED;
1782 ret = BLUETOOTH_ERROR_INTERNAL;
1784 g_clear_error(&error);
1790 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *char_handle)
1792 GDBusConnection *conn;
1793 GError *error = NULL;
1794 int ret = BLUETOOTH_ERROR_NONE;
1795 BT_CHECK_PARAMETER(char_handle, return);
1797 BT_CHECK_ENABLED(return);
1799 BT_INFO("Disable CCCD : %s", char_handle);
1801 conn = _bt_get_system_private_conn();
1802 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1804 g_dbus_connection_call_sync(conn,
1807 GATT_CHAR_INTERFACE,
1811 G_DBUS_CALL_FLAGS_NONE,
1812 GATT_DEFAULT_TIMEOUT, NULL, &error);
1815 BT_ERR("Watch Failed: %s", error->message);
1816 g_clear_error(&error);
1817 ret = BLUETOOTH_ERROR_INTERNAL;
1823 #ifdef TIZEN_GATT_CLIENT
1824 void __bt_uuid_hex_to_string(unsigned char *uuid, char *str)
1826 uint32_t uuid0, uuid4;
1827 uint16_t uuid1, uuid2, uuid3, uuid5;
1829 memcpy(&uuid0, &(uuid[0]), 4);
1830 memcpy(&uuid1, &(uuid[4]), 2);
1831 memcpy(&uuid2, &(uuid[6]), 2);
1832 memcpy(&uuid3, &(uuid[8]), 2);
1833 memcpy(&uuid4, &(uuid[10]), 4);
1834 memcpy(&uuid5, &(uuid[14]), 2);
1836 snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
1837 ntohl(uuid0), ntohs(uuid1),
1838 ntohs(uuid2), ntohs(uuid3),
1839 ntohl(uuid4), ntohs(uuid5));
1844 static void __bt_fill_service_handle_informations(bt_services_browse_info_t *props,
1845 bt_gatt_handle_info_t *svcs)
1849 if (props->count == 0)
1852 svcs->count = props->count;
1854 for (count = 0; count < props->count; count++) {
1855 BT_DBG("[%d] %s instance_id [%d] Is Primary [%d]",
1856 count, props->uuids[count], props->inst_id[count], props->primary[count]);
1857 g_strlcpy(svcs->uuids[count], props->uuids[count],
1858 BLUETOOTH_UUID_STRING_MAX);
1859 svcs->inst_id[count] = props->inst_id[count];
1863 static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props, bt_gatt_service_property_t *service)
1866 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1868 service->char_handle.count = props->count;
1870 /* Before filling all char handles, fill the service's UUID and instance ID */
1871 __bt_uuid_hex_to_string(props->svc_uuid, uuid_string);
1872 service->uuid = g_strdup(uuid_string);
1873 service->primary = TRUE;
1875 /* Now fill all the char handles [UUID and Instance ID's]*/
1876 for (count = 0; count < props->count; count++) {
1877 BT_INFO("[%d] %s instance_id [%d] properties [%d]",
1878 count, props->uuids[count], props->inst_id[count], props->props[count]);
1880 g_strlcpy(service->char_handle.uuids[count],
1881 props->uuids[count],
1882 BLUETOOTH_UUID_STRING_MAX);
1884 service->char_handle.inst_id[count] = props->inst_id[count];
1888 static void __bt_fill_desc_handle_informations(bt_descriptor_browse_info_t *props,
1889 bt_gatt_char_property_t *charc)
1892 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
1894 charc->char_desc_handle.count = props->count;
1896 /* Before filling all desc handles, fill the charac's UUID and instance ID */
1897 __bt_uuid_hex_to_string(props->char_uuid, uuid_string);
1898 charc->uuid = g_strdup(uuid_string);
1900 /* Now fill all the descriptor handles [UUID and Instance ID's]*/
1901 for (count = 0; count < props->count; count++) {
1902 BT_INFO("[%d] %s instance_id [%d]",
1903 count, props->uuids[count], props->inst_id[count]);
1905 g_strlcpy(charc->char_desc_handle.uuids[count],
1906 props->uuids[count],
1907 BLUETOOTH_UUID_STRING_MAX);
1909 charc->char_desc_handle.inst_id[count] = props->inst_id[count];
1911 charc->permission = props->char_props_map;
1912 __convert_permission_flag_to_str(charc->permission);
1916 BT_EXPORT_API int bluetooth_gatt_client_init(
1918 const bluetooth_device_address_t *address,
1919 gatt_client_cb_func_ptr callback_ptr)
1921 int ret = BLUETOOTH_ERROR_NONE;
1922 bt_event_info_t *event_info;
1925 BT_CHECK_PARAMETER(client_id, return);
1926 BT_CHECK_PARAMETER(callback_ptr, return);
1927 BT_CHECK_ENABLED(return);
1930 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1932 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1934 ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_REGISTER,
1935 in_param1, in_param2, in_param3, in_param4, &out_param);
1937 /* App ID -1 is invalid */
1938 if (ret == BLUETOOTH_ERROR_NONE) {
1940 *client_id = g_array_index(out_param, int, 0);
1942 BT_INFO("GATT Client Registered successfully: Client instance ID [%d]", *client_id);
1944 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
1947 count = (int*)event_info->user_data;
1949 BT_INFO("Total num of GATT client instances [%d]", *count);
1951 /* Increement the count */
1954 BT_INFO("No GATT Client instances found in this application: Set User data");
1955 count = g_malloc0(sizeof(int));
1958 /* Register event handler for GATT */
1959 _bt_register_event(BT_GATT_CLIENT_EVENT,
1960 (void *)callback_ptr,
1962 _bt_set_user_data(BT_GATT_CLIENT, (void *)callback_ptr, NULL);
1965 BT_ERR("GATT Client Registration failed!! ret [%d]", ret);
1967 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1974 BT_EXPORT_API int bluetooth_gatt_client_get_primary_services(
1975 const bluetooth_device_address_t *address, /* Remote GATT Server */
1976 bt_gatt_handle_info_t *prim_svc) /* UUID & instance_id */
1979 int result = BLUETOOTH_ERROR_NONE;
1980 bt_services_browse_info_t service_props;
1982 BT_CHECK_PARAMETER(address, return);
1983 BT_CHECK_PARAMETER(prim_svc, return);
1984 BT_CHECK_ENABLED(return);
1987 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
1988 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
1990 result = _bt_send_request(BT_BLUEZ_SERVICE,
1991 BT_GATT_GET_PRIMARY_SERVICES,
1992 in_param1, in_param2, in_param3, in_param4, &out_param);
1994 if (BLUETOOTH_ERROR_NONE != result)
1997 memset(&service_props, 0x00, sizeof(bt_services_browse_info_t));
1999 service_props = g_array_index(
2000 out_param, bt_services_browse_info_t, 0);
2002 __bt_fill_service_handle_informations(
2003 &service_props, prim_svc);
2006 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2010 BT_EXPORT_API int bluetooth_gatt_client_get_service_property(
2011 const char *address,
2012 bt_gatt_handle_property_t *service_handle,
2013 bt_gatt_service_property_t *service)
2015 int result = BLUETOOTH_ERROR_NONE;
2016 bluetooth_gatt_client_svc_prop_info_t svc_prop;
2017 bt_char_browse_info_t char_handles_info;
2019 BT_CHECK_PARAMETER(address, return);
2020 BT_CHECK_PARAMETER(service_handle, return);
2021 BT_CHECK_PARAMETER(service, return);
2022 BT_CHECK_ENABLED(return);
2024 /* Call to bt-service (sync) and send address and service_handle info */
2026 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2028 memset(&svc_prop, 0x00, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2029 /* All characteristics handles are discovered */
2030 memset(&char_handles_info, 0x00, sizeof(bt_char_browse_info_t));
2032 svc_prop.svc.instance_id = service_handle->instance_id;
2033 memcpy(&svc_prop.svc.uuid, &service_handle->uuid, 16);
2035 _bt_convert_addr_string_to_type(svc_prop.device_address.addr, address);
2037 g_array_append_vals(in_param1, &svc_prop, sizeof(bluetooth_gatt_client_svc_prop_info_t));
2039 result = _bt_send_request(BT_BLUEZ_SERVICE,
2040 BT_GATT_GET_SERVICE_PROPERTIES,
2041 in_param1, in_param2, in_param3, in_param4, &out_param);
2043 if (BLUETOOTH_ERROR_NONE != result)
2046 char_handles_info = g_array_index(
2047 out_param, bt_char_browse_info_t, 0);
2048 __bt_fill_char_handle_informations(&char_handles_info,
2050 /* TODO Get all Included Services */
2053 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
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;
2067 BT_CHECK_PARAMETER(address, return);
2068 BT_CHECK_PARAMETER(service_handle, return);
2069 BT_CHECK_PARAMETER(char_handle, return);
2070 BT_CHECK_PARAMETER(char_property, return);
2071 BT_CHECK_ENABLED(return);
2074 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2076 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2078 memset(&char_prop, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2079 char_prop.svc.instance_id = service_handle->instance_id;
2080 memcpy(&char_prop.svc.uuid, &service_handle->uuid, 16);
2082 char_prop.characteristic.instance_id = char_handle->instance_id;
2083 memcpy(&char_prop.characteristic.uuid, &char_handle->uuid, 16);
2085 _bt_convert_addr_string_to_type(char_prop.device_address.addr, address);
2087 g_array_append_vals(in_param1, &char_prop, sizeof(bluetooth_gatt_client_char_prop_info_t));
2089 result = _bt_send_request(BT_BLUEZ_SERVICE,
2090 BT_GATT_GET_CHARACTERISTIC_PROPERTIES,
2091 in_param1, in_param2, in_param3, in_param4, &out_param);
2093 if (BLUETOOTH_ERROR_NONE != result)
2096 /* All descriptors handles are discovered */
2097 memset(&desc_handles_info, 0x00, sizeof(bt_descriptor_browse_info_t));
2099 desc_handles_info = g_array_index(
2100 out_param, bt_descriptor_browse_info_t, 0);
2102 __bt_fill_desc_handle_informations(&desc_handles_info,
2106 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2108 /* Call to bt-service (sync) and send address, service_handle & char_handle infos */
2110 /* After result is fetched, extract descriptor handles (UUID's & instance_id's) */
2112 /* Fill the info in *char_prop */
2114 /*No: Before returning, call bluetooth_gatt_client_read_characteristic_value as
2115 an asyn function and leave every thing else in the callback */
2118 BT_EXPORT_API int bluetooth_gatt_client_get_char_descriptor_property(
2119 const char *address,
2120 bt_gatt_handle_property_t *service_handle,
2121 bt_gatt_handle_property_t *char_handle,
2122 bt_gatt_handle_property_t *descriptor_handle,
2123 bt_gatt_char_descriptor_property_t *desc_prop)
2125 char uuid_string[BLUETOOTH_UUID_STRING_MAX];
2127 BT_CHECK_PARAMETER(address, return);
2128 BT_CHECK_PARAMETER(service_handle, return);
2129 BT_CHECK_PARAMETER(char_handle, return);
2130 BT_CHECK_PARAMETER(descriptor_handle, return);
2131 BT_CHECK_PARAMETER(desc_prop, return);
2132 /* No Need to Call to bt-service (sync) and send address, service_handle,
2133 char_handle & descriptor handle infos */
2134 /* After result is fetched, extract descriptior handles (UUID's & instance_id's) */
2135 /* Fill the info in *desc_prop */
2136 __bt_uuid_hex_to_string(descriptor_handle->uuid, uuid_string);
2138 /* Before filling all desc handles, fill the charac's UUID and instance ID */
2139 desc_prop->uuid = g_strdup(uuid_string);
2141 return BLUETOOTH_ERROR_NONE;
2142 /* No: Before returning, call bluetooth_gatt_client_read_descriptor_value
2143 as an asyn function and leave every thing else in the callback */
2147 static gboolean bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
2148 GIOCondition cond, gpointer data)
2150 bt_gatt_characteristic_notify_info_t *chr_info = (bt_gatt_characteristic_notify_info_t *)data;
2153 BT_ERR("chr_info is invalid");
2156 if (cond & G_IO_IN) {
2157 GIOStatus status = G_IO_STATUS_NORMAL;
2159 char *buffer = NULL;
2161 bt_event_info_t *event_info;
2163 buffer = g_malloc0(chr_info->mtu + 1);
2164 memset(buffer, 0, chr_info->mtu + 1);
2166 status = g_io_channel_read_chars(gio, buffer,
2167 chr_info->mtu, &len, &err);
2168 if (status != G_IO_STATUS_NORMAL) {
2169 BT_ERR("IO Channel read is failed with %d", status);
2172 BT_ERR("IO Channel read error [%s]", err->message);
2173 if (status == G_IO_STATUS_ERROR) {
2174 BT_ERR("cond : %d", cond);
2176 g_io_channel_shutdown(gio, TRUE, NULL);
2177 g_io_channel_unref(gio);
2179 gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
2188 if (len > 0 && len < chr_info->mtu) {
2189 bt_gatt_char_property_t char_val;
2190 // BT_DBG("FD io sending value changed %x %x %x %x %x %x %x %zd \n", buffer[0], buffer[1], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], len);
2192 memcpy(char_val.prop.uuid, chr_info->UUID, 16);
2193 memcpy(char_val.value, buffer, len);
2194 char_val.val_len = len;
2195 memcpy(char_val.address, chr_info->address, 18);
2197 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
2199 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
2200 BLUETOOTH_ERROR_NONE, &char_val,
2201 event_info->cb, event_info->user_data);
2203 BT_ERR("event_info failed");
2207 BT_ERR("Packet corrupted");
2214 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
2215 BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
2216 g_io_channel_shutdown(gio, TRUE, NULL);
2217 g_io_channel_unref(gio);
2219 gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
2228 #ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
2229 static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_get_characteristic_notify_info(unsigned char *handle , int id)
2233 for (l = gatt_characteristic_notify_list; l != NULL; l = l->next) {
2234 bt_gatt_characteristic_notify_info_t *info = l->data;
2235 if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
2242 static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_create_watch_io(int fd, int id, int mtu, char * address, unsigned char *uuid)
2244 GIOChannel *channel;
2245 bt_gatt_characteristic_notify_info_t *chr_info;
2247 chr_info = g_malloc0(sizeof(bt_gatt_characteristic_notify_info_t));
2248 chr_info->notify_fd = fd;
2250 chr_info->mtu = mtu;
2251 g_strlcpy(chr_info->address, address, 18);
2252 memcpy(chr_info->UUID, uuid, 16);
2254 channel = g_io_channel_unix_new(fd);
2256 chr_info->io_channel = channel;
2258 g_io_channel_set_encoding(channel, NULL, NULL);
2259 g_io_channel_set_buffered(channel, FALSE);
2260 g_io_channel_set_close_on_unref(channel, TRUE);
2261 g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
2263 chr_info->watch_id = g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
2264 bluetooth_gatt_client_notify_channel_watch_cb, chr_info);
2270 BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
2271 const char *address,
2272 bt_gatt_handle_property_t *service_handle,
2273 bt_gatt_handle_property_t *char_handle,
2276 gboolean is_indicate)
2278 int result = BLUETOOTH_ERROR_NONE;
2279 bluetooth_gatt_client_char_prop_info_t param;
2280 bt_gatt_characteristic_notify_info_t *chr_info;
2282 BT_CHECK_PARAMETER(address, return);
2283 BT_CHECK_PARAMETER(service_handle, return);
2284 BT_CHECK_PARAMETER(char_handle, return);
2286 #ifndef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
2287 chr_info = bluetooth_gatt_client_get_characteristic_notify_info(char_handle->uuid , char_handle->instance_id);
2288 if (chr_info && !is_notify) {
2289 BT_INFO("Already CCCD enabled. fd %d", chr_info->notify_fd);
2291 if (chr_info->watch_id > 0)
2292 g_source_remove(chr_info->watch_id);
2294 if (chr_info->io_channel) {
2295 g_io_channel_shutdown(chr_info->io_channel, TRUE, NULL);
2296 g_io_channel_unref(chr_info->io_channel);
2299 gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
2307 /* ASync Function, result expected in callback from bt-service */
2310 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2312 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2314 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2315 param.svc.instance_id = service_handle->instance_id;
2317 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2318 param.characteristic.instance_id = char_handle->instance_id;
2320 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2322 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2323 g_array_append_vals(in_param2, &client_id, sizeof(int));
2324 g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
2325 g_array_append_vals(in_param4, &is_indicate, sizeof(gboolean));
2327 #ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
2328 result = _bt_send_request(BT_BLUEZ_SERVICE,
2329 BT_GATT_WATCH_CHARACTERISTIC,
2330 in_param1, in_param2, in_param3, in_param4, &out_param);
2332 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2334 BT_INFO("Result [%d]", result);
2338 GUnixFDList *out_fd_list = NULL;
2339 char *svc_name = NULL;
2342 _bt_convert_uuid_type_to_string(str_uuid, param.svc.uuid);
2343 bluetooth_get_uuid_name(str_uuid, &svc_name);
2345 _bt_convert_uuid_type_to_string(str_uuid, param.characteristic.uuid);
2347 BT_INFO_C("### Request subscription Notify : %s [%s]", str_uuid, svc_name);
2350 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_WATCH_CHARACTERISTIC,
2351 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
2352 if (result != BLUETOOTH_ERROR_NONE) {
2353 BT_ERR("Fail to get Nofify FD. result %d", result);
2354 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2358 if (is_indicate == false) {
2359 if (NULL == out_fd_list) {
2360 BT_ERR("out_fd_list is NULL");
2361 result = BLUETOOTH_ERROR_INTERNAL;
2368 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
2369 BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
2370 fd = fd_list_array[0];
2371 mtu = g_array_index(out_param, int, 0);
2373 BT_INFO("Acquired characteristic Notify FD %d, mtu %d", fd, mtu);
2374 chr_info = bluetooth_gatt_client_create_watch_io(fd, char_handle->instance_id, mtu, (char *)address, char_handle->uuid);
2376 gatt_characteristic_notify_list = g_slist_append(gatt_characteristic_notify_list, chr_info);
2378 g_free(fd_list_array);
2379 g_object_unref(out_fd_list);
2383 /*result = _bt_send_request(BT_BLUEZ_SERVICE,
2384 BT_GATT_WATCH_CHARACTERISTIC,
2385 in_param1, in_param2, in_param3, in_param4, &out_param);*/
2387 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2392 BT_EXPORT_API int bluetooth_gatt_client_read_characteristic_value(
2393 const char *address,
2394 bt_gatt_handle_property_t *service_handle,
2395 bt_gatt_handle_property_t *char_handle)
2397 int result = BLUETOOTH_ERROR_NONE;
2398 bt_user_info_t *user_info;
2399 bluetooth_gatt_client_char_prop_info_t param;
2401 BT_CHECK_PARAMETER(address, return);
2402 BT_CHECK_PARAMETER(service_handle, return);
2403 BT_CHECK_PARAMETER(char_handle, return);
2405 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2406 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2409 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2411 /* Async Function, result expected in callback from bt-service */
2412 /* Call to bt-service (sync) and send address service_handle info & char handle info */
2413 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2415 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2416 param.svc.instance_id = service_handle->instance_id;
2418 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2419 param.characteristic.instance_id = char_handle->instance_id;
2421 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2423 g_array_append_vals(in_param1, ¶m,
2424 sizeof(bluetooth_gatt_client_char_prop_info_t));
2426 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_CHARACTERISTIC,
2427 in_param1, in_param2, in_param3, in_param4,
2428 user_info->cb, user_info->user_data);
2430 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2434 BT_EXPORT_API int bluetooth_gatt_client_read_descriptor_value(
2435 const char *address,
2436 bt_gatt_handle_property_t *service_handle,
2437 bt_gatt_handle_property_t *char_handle,
2438 bt_gatt_handle_property_t *descriptor_handle)
2440 int result = BLUETOOTH_ERROR_NONE;
2441 bt_user_info_t *user_info;
2442 bluetooth_gatt_client_desc_prop_info_t param;
2444 BT_CHECK_PARAMETER(address, return);
2445 BT_CHECK_PARAMETER(service_handle, return);
2446 BT_CHECK_PARAMETER(char_handle, return);
2447 BT_CHECK_PARAMETER(descriptor_handle, return);
2449 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2450 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2453 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2455 /* Async Function, result expected in callback from bt-service */
2456 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2458 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2459 param.svc.instance_id = service_handle->instance_id;
2461 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2462 param.characteristic.instance_id = char_handle->instance_id;
2464 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2465 param.descriptor.instance_id = descriptor_handle->instance_id;
2467 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2469 g_array_append_vals(in_param1, ¶m,
2470 sizeof(bluetooth_gatt_client_desc_prop_info_t));
2472 result = _bt_send_request_async(BT_BLUEZ_SERVICE, BT_GATT_READ_DESCRIPTOR_VALUE,
2473 in_param1, in_param2, in_param3, in_param4,
2474 user_info->cb, user_info->user_data);
2476 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2481 static bt_gatt_characteristic_write_info_t * bluetooth_gatt_client_get_characteristic_fd(unsigned char *handle, int id)
2486 for (l = gatt_characteristic_write_list; l != NULL; l = l->next) {
2487 bt_gatt_characteristic_write_info_t *info = l->data;
2489 if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
2493 _bt_convert_uuid_type_to_string(str, handle);
2494 BT_ERR("Unable to get characteristic fd. [%s] id [ %d]", str, id);
2498 static gboolean bluetooth_gatt_client_write_channel_watch_cb(GIOChannel *gio,
2499 GIOCondition cond, gpointer data)
2501 bt_gatt_characteristic_write_info_t *chr_info = (bt_gatt_characteristic_write_info_t *)data;
2506 if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
2507 BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
2508 g_io_channel_shutdown(gio, TRUE, NULL);
2509 g_io_channel_unref(gio);
2511 gatt_characteristic_write_list = g_slist_remove(gatt_characteristic_write_list, chr_info);
2520 static int bluetooth_gatt_client_write_characteristics_value_to_fd(
2521 int fd, const guint8 *value, int length, int mtu,
2525 int att_result = BLUETOOTH_ERROR_NONE;
2526 BT_CHECK_PARAMETER(value, return);
2527 written = write(fd, value, length);
2528 if (written != length) {
2529 att_result = BLUETOOTH_ERROR_INTERNAL;
2530 BT_ERR("write data failed. ret : %d ", written);
2536 static void bluetooth_gatt_client_create_write_io_channel(int fd, unsigned char * uuid, int id, int mtu)
2538 bt_gatt_characteristic_write_info_t *chr_info;
2539 GIOChannel *channel;
2541 chr_info = g_malloc0(sizeof(bt_gatt_characteristic_write_info_t));
2542 chr_info->write_fd = fd;
2544 chr_info->mtu = mtu;
2546 memcpy(chr_info->UUID, uuid, 16);
2547 channel = g_io_channel_unix_new(fd);
2548 g_io_channel_set_encoding(channel, NULL, NULL);
2549 g_io_channel_set_buffered(channel, FALSE);
2550 g_io_channel_set_close_on_unref(channel, TRUE);
2551 g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
2552 g_io_add_watch(channel, (G_IO_ERR | G_IO_HUP | G_IO_NVAL),
2553 bluetooth_gatt_client_write_channel_watch_cb, chr_info);
2555 gatt_characteristic_write_list = g_slist_append(gatt_characteristic_write_list, chr_info);
2559 BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
2560 const char *address,
2561 bt_gatt_handle_property_t *service_handle,
2562 bt_gatt_handle_property_t *char_handle,
2563 bluetooth_gatt_att_data_t *data,
2564 bluetooth_gatt_write_type_e write_type)
2566 int result = BLUETOOTH_ERROR_NONE;
2567 bt_user_info_t *user_info;
2568 bluetooth_gatt_client_char_prop_info_t param;
2570 BT_CHECK_PARAMETER(address, return);
2571 BT_CHECK_PARAMETER(service_handle, return);
2572 BT_CHECK_PARAMETER(char_handle, return);
2573 BT_CHECK_PARAMETER(data, return);
2575 /* ASync Function, result expected in callback from bt-service */
2576 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2577 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2580 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2582 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
2584 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2585 param.svc.instance_id = service_handle->instance_id;
2587 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2588 param.characteristic.instance_id = char_handle->instance_id;
2590 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2592 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_char_prop_info_t));
2593 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2594 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2596 #ifdef TIZEN_FEATURE_BT_GATT_CLIENT_FD_DISABLE
2600 if (write_type == BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE) {
2603 bt_gatt_characteristic_write_info_t *info;
2604 info = bluetooth_gatt_client_get_characteristic_fd(char_handle->uuid, service_handle->instance_id);
2607 fd = info->write_fd;
2613 GUnixFDList *out_fd_list = NULL;
2615 result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_ACQUIRE_WRITE,
2616 in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
2618 mtu = g_array_index(out_param, int, 0);
2620 if (result != BLUETOOTH_ERROR_NONE) {
2621 BT_ERR("Fail to get Write FD. result %d", result);
2622 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2624 } else if (NULL == out_fd_list) {
2625 BT_ERR("out_fd_list is NULL");
2626 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2627 return BLUETOOTH_ERROR_INTERNAL;
2632 fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
2633 fd = fd_list_array[0];
2635 g_free(fd_list_array);
2636 g_object_unref(out_fd_list);
2638 BT_INFO("Acquired characteristic Write FD %d, mtu %d", fd, mtu);
2641 bluetooth_gatt_client_create_write_io_channel(fd, char_handle->uuid, service_handle->instance_id, mtu);
2643 result = bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
2646 BT_ERR("characteristic info FD is invalid");
2651 result = bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
2656 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2657 BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
2658 in_param1, in_param2, in_param3, in_param4,
2659 user_info->cb, user_info->user_data);
2662 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2667 BT_EXPORT_API int bluetooth_gatt_client_write_descriptor_value(
2668 const char *address,
2669 bt_gatt_handle_property_t *service_handle,
2670 bt_gatt_handle_property_t *char_handle,
2671 bt_gatt_handle_property_t *descriptor_handle,
2672 bluetooth_gatt_att_data_t *data,
2673 bluetooth_gatt_write_type_e write_type)
2675 int result = BLUETOOTH_ERROR_NONE;
2676 bt_user_info_t *user_info;
2677 bluetooth_gatt_client_desc_prop_info_t param;
2679 BT_CHECK_PARAMETER(address, return);
2680 BT_CHECK_PARAMETER(service_handle, return);
2681 BT_CHECK_PARAMETER(char_handle, return);
2682 BT_CHECK_PARAMETER(descriptor_handle, return);
2683 BT_CHECK_PARAMETER(data, return);
2685 /* Async Function, result expected in callback from bt-service */
2686 user_info = _bt_get_user_data(BT_GATT_CLIENT);
2687 retv_if(user_info->cb == NULL, BLUETOOTH_ERROR_INTERNAL);
2690 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2692 memset(¶m, 0x00, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2694 memcpy(¶m.svc.uuid, service_handle->uuid, 16);
2695 param.svc.instance_id = service_handle->instance_id;
2697 memcpy(¶m.characteristic.uuid, char_handle->uuid, 16);
2698 param.characteristic.instance_id = char_handle->instance_id;
2700 memcpy(¶m.descriptor.uuid, descriptor_handle->uuid, 16);
2701 param.descriptor.instance_id = descriptor_handle->instance_id;
2703 _bt_convert_addr_string_to_type(param.device_address.addr, address);
2705 g_array_append_vals(in_param1, ¶m, sizeof(bluetooth_gatt_client_desc_prop_info_t));
2706 g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
2707 g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
2709 result = _bt_send_request_async(BT_BLUEZ_SERVICE,
2710 BT_GATT_WRITE_DESCRIPTOR_VALUE,
2711 in_param1, in_param2, in_param3, in_param4,
2712 user_info->cb, user_info->user_data);
2714 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2719 BT_EXPORT_API int bluetooth_gatt_client_set_service_change_watcher(
2720 const bluetooth_device_address_t *address, gboolean enable)
2723 bluetooth_device_address_t *addr = NULL;
2724 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2725 char secure_address[BT_ADDRESS_STRING_SIZE] = { 0 };
2726 int result = BLUETOOTH_ERROR_NONE;
2729 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2731 g_array_append_vals(in_param1, address, sizeof(bluetooth_device_address_t));
2732 g_array_append_vals(in_param2, &enable, sizeof(gboolean));
2734 _bt_convert_addr_type_to_string(device_address, (unsigned char *)address->addr);
2735 _bt_convert_addr_string_to_secure_string(secure_address, device_address);
2736 BT_INFO("%s watcher for [%s]", enable ? "Set":"Unset", secure_address);
2738 if (enable == TRUE) {
2739 if (_bluetooth_gatt_check_service_change_watcher_address(address)
2741 BT_INFO("The watcher is already set");
2745 if (service_monitor_list == NULL) {
2746 //_bt_register_manager_subscribe_signal(TRUE);
2748 result = _bt_send_request(BT_BLUEZ_SERVICE,
2749 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2750 in_param1, in_param2, in_param3, in_param4, &out_param);
2753 if (result == BLUETOOTH_ERROR_NONE) {
2754 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2755 memcpy(addr, address, sizeof(bluetooth_device_address_t));
2757 service_monitor_list =
2758 g_slist_append(service_monitor_list, addr);
2761 for (l = service_monitor_list; l != NULL; l = l->next) {
2764 if (!memcmp(address, addr,
2765 sizeof(bluetooth_device_address_t))) {
2766 service_monitor_list =
2767 g_slist_remove(service_monitor_list, addr);
2773 if (service_monitor_list == NULL) {
2774 //_bt_register_manager_subscribe_signal(FALSE);
2775 result = _bt_send_request(BT_BLUEZ_SERVICE,
2776 BT_GATT_WATCH_SERVICE_CHANGED_INDICATION,
2777 in_param1, in_param2, in_param3, in_param4, &out_param);
2783 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2787 BT_EXPORT_API int bluetooth_gatt_client_deinit(
2792 bt_event_info_t *event_info;
2794 BT_CHECK_ENABLED(return);
2796 BT_INFO("GATT Client Deinit Client instance ID [%d]", client_id);
2799 BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
2801 g_array_append_vals(in_param1, &client_id, sizeof(int));
2803 /* Unregistration MUST NOT FAIL */
2804 result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_CLIENT_UNREGISTER,
2805 in_param1, in_param2, in_param3, in_param4, &out_param);
2807 if (result != BLUETOOTH_ERROR_NONE)
2808 BT_ERR("GATT Client Unregistration failed result [%d]", result);
2810 BT_INFO("GATT Client Unregistration successful");
2812 /* Unregister event handler if this is the only instance */
2813 event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
2816 count = (int*)event_info->user_data;
2818 BT_INFO("Total num of GATT client instances [%d]", *count);
2821 BT_DBG("Currently only one GATT client instance, so remove it and unregister GATT client events");
2822 _bt_unregister_event(BT_GATT_CLIENT_EVENT);
2823 _bt_set_user_data(BT_GATT_CLIENT, NULL, NULL);
2827 BT_ERR("Impossible that client is created, but no event handler is registered!!!");
2829 BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);