4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <dbus/dbus.h>
22 #include <dbus/dbus-glib.h>
25 #include "bluetooth-api.h"
26 #include "bt-common.h"
27 #include "bt-internal-types.h"
30 #define BLUEZ_CHAR_INTERFACE "org.bluez.Characteristic"
32 #define GATT_OBJECT_PATH "/org/bluez/gatt_attrib"
36 } BluetoothGattService;
40 } BluetoothGattServiceClass;
47 GType bluetooth_gatt_service_get_type(void);
49 #define BLUETOOTH_GATT_TYPE_SERVICE (bluetooth_gatt_service_get_type())
51 #define BLUETOOTH_GATT_SERVICE(object) \
52 (G_TYPE_CHECK_INSTANCE_CAST((object), \
53 BLUETOOTH_GATT_TYPE_SERVICE, BluetoothGattService))
55 #define BLUETOOTH_GATT_SERVICE_CLASS(klass) \
56 (G_TYPE_CHECK_CLASS_CAST((klass), \
57 BLUETOOTH_GATT_TYPE_SERVICE, BluetoothGattServiceClass))
59 #define BLUETOOTH_GATT_IS_SERVICE(object) \
60 (G_TYPE_CHECK_INSTANCE_TYPE((object), BLUETOOTH_GATT_TYPE_SERVICE))
62 #define BLUETOOTH_GATT_IS_SERVICE_CLASS(klass) \
63 (G_TYPE_CHECK_CLASS_TYPE((klass), BLUETOOTH_GATT_TYPE_SERVICE))
65 #define BLUETOOTH_GATT_SERVICE_GET_CLASS(obj) \
66 (G_TYPE_INSTANCE_GET_CLASS((obj), \
67 BLUETOOTH_GATT_TYPE_SERVICE, BluetoothGattServiceClass))
69 G_DEFINE_TYPE(BluetoothGattService, bluetooth_gatt_service, G_TYPE_OBJECT)
71 static gboolean bluetooth_gatt_value_changed(BluetoothGattService *agent,
74 DBusGMethodInvocation *context);
76 #include "bt-gatt-glue.h"
78 static void bluetooth_gatt_service_init(BluetoothGattService *obj)
80 g_assert(obj != NULL);
83 static void bluetooth_gatt_service_finalize(GObject *obj)
85 G_OBJECT_CLASS(bluetooth_gatt_service_parent_class)->finalize(obj);
88 static void bluetooth_gatt_service_class_init(BluetoothGattServiceClass *klass)
90 GObjectClass *object_class = (GObjectClass *)klass;
92 g_assert(klass != NULL);
94 object_class->finalize = bluetooth_gatt_service_finalize;
96 dbus_g_object_type_install_info(BLUETOOTH_GATT_TYPE_SERVICE,
97 &dbus_glib_bluetooth_gatt_object_info);
100 static gboolean bluetooth_gatt_value_changed(BluetoothGattService *agent,
103 DBusGMethodInvocation *context)
105 bt_gatt_char_value_t char_val;
106 bt_user_info_t *user_info;
109 char_val.char_handle = obj_path;
110 char_val.char_value = &g_array_index(byte_array, guint8, 0);
111 char_val.val_len = byte_array->len;
112 BT_DBG("Byte array length = %d", char_val.val_len);
114 user_info = _bt_get_user_data(BT_COMMON);
117 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
118 BLUETOOTH_ERROR_NONE, &char_val,
119 user_info->cb, user_info->user_data);
127 static void __add_value_changed_method(DBusGConnection *conn)
129 static gboolean method_added = FALSE;
130 BluetoothGattService *bluetooth_gatt_obj = NULL;
133 BT_ERR("Method already added. \n");
139 bluetooth_gatt_obj = g_object_new(BLUETOOTH_GATT_TYPE_SERVICE, NULL);
141 dbus_g_connection_register_g_object(conn, GATT_OBJECT_PATH,
142 G_OBJECT(bluetooth_gatt_obj));
146 static char **__get_string_array_from_gptr_array(GPtrArray *gp)
148 gchar *gp_path = NULL;
155 path = g_malloc0((gp->len + 1) * sizeof(char *));
157 for (i = 0; i < gp->len; i++) {
158 gp_path = g_ptr_array_index(gp, i);
159 path[i] = g_strdup(gp_path);
160 BT_DBG("path[%d] : [%s]", i, path[i]);
166 static void __bluetooth_internal_get_char_cb(DBusGProxy *proxy,
167 DBusGProxyCall *call,
170 GError *error = NULL;
171 GPtrArray *gp_array = NULL;
172 bt_gatt_discovered_char_t svc_char = { 0, };
173 bt_user_info_t *user_info;
175 svc_char.service_handle = user_data;
177 user_info = _bt_get_user_data(BT_COMMON);
179 if (!dbus_g_proxy_end_call(proxy, call, &error,
180 dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
181 &gp_array, G_TYPE_INVALID)) {
182 BT_ERR("Error : %s \n", error->message);
186 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
187 BLUETOOTH_ERROR_NONE, &svc_char,
188 user_info->cb, user_info->user_data);
190 g_free(svc_char.service_handle);
191 g_object_unref(proxy);
195 if (NULL != gp_array) {
196 svc_char.handle_info.count = gp_array->len;
197 svc_char.handle_info.handle = __get_string_array_from_gptr_array(gp_array);
201 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_SVC_CHAR_DISCOVERED,
202 BLUETOOTH_ERROR_NONE, &svc_char,
203 user_info->cb, user_info->user_data);
206 g_ptr_array_free(gp_array, TRUE);
207 g_free(svc_char.service_handle);
208 g_free(svc_char.handle_info.handle);
209 g_object_unref(proxy);
212 static void __free_char_req(char_pty_req_t *char_req)
214 g_free(char_req->char_uuid);
215 g_strfreev(char_req->handle);
219 static gboolean __filter_chars_with_uuid(gpointer data)
222 bt_gatt_char_property_t *char_pty;
223 char_pty_req_t *char_req = data;
224 bt_user_info_t *user_info;
227 user_info = _bt_get_user_data(BT_COMMON);
228 if (user_info == NULL) {
229 __free_char_req(char_req);
233 char_pty = g_new0(bt_gatt_char_property_t, 1);
235 while (char_req->handle[i] != NULL) {
236 BT_DBG("char_pty[%d] = %s", i, char_req->handle[i]);
237 ret = bluetooth_gatt_get_characteristics_property(char_req->handle[i],
239 if (ret != BLUETOOTH_ERROR_NONE) {
240 BT_ERR("get char property failed");
244 if (char_pty->uuid && g_strstr_len(char_pty->uuid, -1,
245 char_req->char_uuid) != NULL) {
246 BT_DBG("Requested Char recieved");
247 ret = BLUETOOTH_ERROR_NONE;
251 bluetooth_gatt_free_char_property(char_pty);
257 if (char_req->handle[i] == NULL)
258 ret = BLUETOOTH_ERROR_NOT_FOUND;
260 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID, ret,
261 char_pty, user_info->cb, user_info->user_data);
264 __free_char_req(char_req);
269 static void __disc_char_from_uuid_cb(DBusGProxy *proxy,
270 DBusGProxyCall *call,
273 GError *error = NULL;
274 GPtrArray *gp_array = NULL;
275 bt_user_info_t *user_info;
276 char_pty_req_t *char_req = user_data;
278 user_info = _bt_get_user_data(BT_COMMON);
280 __free_char_req(char_req);
284 if (!dbus_g_proxy_end_call(proxy, call, &error,
285 dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
286 &gp_array, G_TYPE_INVALID)) {
287 BT_ERR("Error : %s \n", error->message);
290 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
291 BLUETOOTH_ERROR_INTERNAL, NULL,
292 user_info->cb, user_info->user_data);
294 __free_char_req(char_req);
295 g_object_unref(proxy);
299 if (gp_array == NULL) {
300 _bt_common_event_cb(BLUETOOTH_EVENT_GATT_GET_CHAR_FROM_UUID,
301 BLUETOOTH_ERROR_NOT_FOUND, NULL,
302 user_info->cb, user_info->user_data);
304 __free_char_req(char_req);
305 g_object_unref(proxy);
310 char_req->handle = __get_string_array_from_gptr_array(gp_array);
312 __filter_chars_with_uuid(char_req);
314 g_ptr_array_free(gp_array, TRUE);
315 g_object_unref(proxy);
319 static int __discover_char_from_uuid(const char *service_handle,
320 const char *char_uuid){
321 DBusGProxy *service_proxy = NULL;
322 DBusGConnection *conn;
323 char_pty_req_t *char_req;
325 conn = _bt_get_system_gconn();
326 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
328 service_proxy = dbus_g_proxy_new_for_name(conn,
329 BT_BLUEZ_NAME, service_handle,
330 BLUEZ_CHAR_INTERFACE);
331 retv_if(service_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
333 char_req = g_new0(char_pty_req_t, 1);
335 char_req->char_uuid = g_strdup(char_uuid);
336 BT_DBG("Char uuid %s ", char_uuid);
338 if (!dbus_g_proxy_begin_call(service_proxy, "DiscoverCharacteristics",
339 (DBusGProxyCallNotify)__disc_char_from_uuid_cb,
340 char_req, NULL, G_TYPE_INVALID)) {
341 __free_char_req(char_req);
342 g_object_unref(service_proxy);
343 return BLUETOOTH_ERROR_INTERNAL;
346 return BLUETOOTH_ERROR_NONE;
349 BT_EXPORT_API int bluetooth_gatt_free_primary_services(bt_gatt_handle_info_t *prim_svc)
353 BT_CHECK_PARAMETER(prim_svc, return);
355 g_strfreev(prim_svc->handle);
357 memset(prim_svc, 0, sizeof(bt_gatt_handle_info_t));
360 return BLUETOOTH_ERROR_NONE;
363 BT_EXPORT_API int bluetooth_gatt_free_service_property(bt_gatt_service_property_t *svc_pty)
367 BT_CHECK_PARAMETER(svc_pty, return);
369 g_free(svc_pty->uuid);
370 g_free(svc_pty->handle);
371 g_strfreev(svc_pty->handle_info.handle);
373 memset(svc_pty, 0, sizeof(bt_gatt_service_property_t));
376 return BLUETOOTH_ERROR_NONE;
379 BT_EXPORT_API int bluetooth_gatt_free_char_property(bt_gatt_char_property_t *char_pty)
383 BT_CHECK_PARAMETER(char_pty, return);
385 g_free(char_pty->uuid);
386 g_free(char_pty->name);
387 g_free(char_pty->description);
388 g_free(char_pty->val);
389 g_free(char_pty->handle);
391 memset(char_pty, 0, sizeof(bt_gatt_char_property_t));
394 return BLUETOOTH_ERROR_NONE;
397 BT_EXPORT_API int bluetooth_gatt_get_primary_services(const bluetooth_device_address_t *address,
398 bt_gatt_handle_info_t *prim_svc)
400 char device_address[BT_ADDRESS_STRING_SIZE] = { 0 };
401 gchar *device_path = NULL;
402 GError *error = NULL;
403 DBusGProxy *device_proxy = NULL;
404 GHashTable *hash = NULL;
405 GValue *value = NULL;
406 GPtrArray *gp_array = NULL;
407 DBusGProxy *adapter_proxy;
408 DBusGConnection *conn;
409 int ret = BLUETOOTH_ERROR_INTERNAL;
413 BT_CHECK_PARAMETER(address, return);
414 BT_CHECK_PARAMETER(prim_svc, return);
416 BT_CHECK_ENABLED(return);
418 _bt_convert_addr_type_to_string(device_address,
419 (unsigned char *)address->addr);
421 BT_DBG("bluetooth address [%s]\n", device_address);
423 conn = _bt_get_system_gconn();
424 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
426 adapter_proxy = _bt_get_adapter_proxy(conn);
427 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
429 dbus_g_proxy_call(adapter_proxy, "FindDevice", &error,
430 G_TYPE_STRING, device_address, G_TYPE_INVALID,
431 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
433 BT_ERR("FindDevice Call Error %s[%s]", error->message, device_address);
435 g_object_unref(adapter_proxy);
436 return BLUETOOTH_ERROR_INTERNAL;
439 g_object_unref(adapter_proxy);
441 retv_if(device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
443 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
444 device_path, BT_DEVICE_INTERFACE);
446 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
448 dbus_g_proxy_call(device_proxy, "GetProperties", &error, G_TYPE_INVALID,
449 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
450 &hash, G_TYPE_INVALID);
452 BT_ERR("GetProperties Call Error %s[%s]", error->message, device_address);
454 g_object_unref(device_proxy);
455 return BLUETOOTH_ERROR_INTERNAL;
458 g_object_unref(device_proxy);
460 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
462 value = g_hash_table_lookup(hash, "Services");
464 BT_ERR("value == NULL");
468 gp_array = g_value_get_boxed(value);
469 if (gp_array == NULL) {
470 BT_ERR("gp_array == NULL");
474 prim_svc->count = gp_array->len;
475 prim_svc->handle = __get_string_array_from_gptr_array(gp_array);
477 ret = BLUETOOTH_ERROR_NONE;
479 g_hash_table_destroy(hash);
484 BT_EXPORT_API int bluetooth_gatt_discover_service_characteristics(const char *service_handle)
486 DBusGProxy *service_proxy = NULL;
488 DBusGConnection *conn;
490 BT_CHECK_PARAMETER(service_handle, return);
492 BT_CHECK_ENABLED(return);
494 conn = _bt_get_system_gconn();
495 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
497 service_proxy = dbus_g_proxy_new_for_name(conn,
498 BT_BLUEZ_NAME, service_handle,
499 BLUEZ_CHAR_INTERFACE);
501 retv_if(service_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
503 handle = g_strdup(service_handle);
504 BT_DBG("Requested characteristic handle:%s \n ", handle);
506 if (!dbus_g_proxy_begin_call(service_proxy, "DiscoverCharacteristics",
507 (DBusGProxyCallNotify)__bluetooth_internal_get_char_cb,
508 handle, NULL, G_TYPE_INVALID)) {
510 g_object_unref(service_proxy);
511 return BLUETOOTH_ERROR_INTERNAL;
514 return BLUETOOTH_ERROR_NONE;
517 BT_EXPORT_API int bluetooth_gatt_get_service_property(const char *service_handle,
518 bt_gatt_service_property_t *service)
520 DBusGProxy *service_proxy = NULL;
521 GHashTable *hash = NULL;
522 GError *error = NULL;
523 GValue *value = NULL;
524 GPtrArray *gp_array = NULL ;
525 DBusGConnection *conn;
527 BT_CHECK_PARAMETER(service_handle, return);
528 BT_CHECK_PARAMETER(service, return);
530 BT_CHECK_ENABLED(return);
532 conn = _bt_get_system_gconn();
533 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
535 service_proxy = dbus_g_proxy_new_for_name(conn,
536 BT_BLUEZ_NAME, service_handle,
537 BLUEZ_CHAR_INTERFACE);
539 retv_if(service_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
541 dbus_g_proxy_call(service_proxy, "GetProperties", &error, G_TYPE_INVALID,
542 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
543 &hash, G_TYPE_INVALID);
545 BT_ERR("GetProperties Call Error %s\n", error->message);
547 g_object_unref(service_proxy);
548 return BLUETOOTH_ERROR_INTERNAL;
550 g_object_unref(service_proxy);
552 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
554 memset(service, 0, sizeof(bt_gatt_service_property_t));
556 value = g_hash_table_lookup(hash, "UUID");
557 service->uuid = value ? g_value_dup_string(value) : NULL;
559 BT_DBG("svc_pty.uuid = [%s] \n", service->uuid);
562 value = g_hash_table_lookup(hash, "Characteristics");
563 gp_array = value ? g_value_get_boxed(value) : NULL;
565 service->handle_info.count = gp_array->len;
566 service->handle_info.handle = __get_string_array_from_gptr_array(gp_array);
569 service->handle = g_strdup(service_handle);
570 g_hash_table_destroy(hash);
571 return BLUETOOTH_ERROR_NONE;
574 BT_EXPORT_API int bluetooth_gatt_watch_characteristics(const char *service_handle)
576 DBusGProxy *watch_proxy = NULL;
577 GError *error = NULL;
578 DBusGConnection *conn;
580 BT_CHECK_PARAMETER(service_handle, return);
582 BT_CHECK_ENABLED(return);
584 BT_DBG("Entered service handle:%s \n ", service_handle);
586 conn = _bt_get_system_gconn();
587 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
589 watch_proxy = dbus_g_proxy_new_for_name(conn,
590 BT_BLUEZ_NAME, service_handle,
591 BLUEZ_CHAR_INTERFACE);
593 retv_if(watch_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
595 __add_value_changed_method(conn);
597 dbus_g_proxy_call(watch_proxy, "RegisterCharacteristicsWatcher", &error,
598 DBUS_TYPE_G_OBJECT_PATH, GATT_OBJECT_PATH,
599 G_TYPE_INVALID, G_TYPE_INVALID);
601 BT_ERR("Method call Fail: %s", error->message);
603 g_object_unref(watch_proxy);
604 return BLUETOOTH_ERROR_INTERNAL;
607 g_object_unref(watch_proxy);
609 return BLUETOOTH_ERROR_NONE;
612 BT_EXPORT_API int bluetooth_gatt_unwatch_characteristics(const char *service_handle)
614 DBusGProxy *watch_proxy = NULL;
615 GError *error = NULL;
616 DBusGConnection *conn;
618 BT_CHECK_PARAMETER(service_handle, return);
620 BT_CHECK_ENABLED(return);
622 conn = _bt_get_system_gconn();
623 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
625 watch_proxy = dbus_g_proxy_new_for_name(conn,
626 BT_BLUEZ_NAME, service_handle,
627 BLUEZ_CHAR_INTERFACE);
629 retv_if(watch_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
631 dbus_g_proxy_call(watch_proxy, "UnregisterCharacteristicsWatcher", &error,
632 DBUS_TYPE_G_OBJECT_PATH, GATT_OBJECT_PATH,
633 G_TYPE_INVALID, G_TYPE_INVALID);
635 BT_ERR("Method call Fail: %s", error->message);
637 g_object_unref(watch_proxy);
638 return BLUETOOTH_ERROR_INTERNAL;
641 g_object_unref(watch_proxy);
643 return BLUETOOTH_ERROR_NONE;
646 BT_EXPORT_API int bluetooth_gatt_get_characteristics_property(const char *char_handle,
647 bt_gatt_char_property_t *characteristic)
649 DBusGProxy *characteristic_proxy = NULL;
650 GHashTable *hash = NULL;
651 GError *error = NULL;
652 GValue *value = NULL;
653 GByteArray *gb_array = NULL;
654 DBusGConnection *conn;
656 BT_CHECK_PARAMETER(char_handle, return);
657 BT_CHECK_PARAMETER(characteristic, return);
659 BT_CHECK_ENABLED(return);
661 conn = _bt_get_system_gconn();
662 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
664 characteristic_proxy = dbus_g_proxy_new_for_name(conn,
665 BT_BLUEZ_NAME, char_handle,
666 BLUEZ_CHAR_INTERFACE);
668 retv_if(characteristic_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
670 dbus_g_proxy_call(characteristic_proxy, "GetProperties", &error, G_TYPE_INVALID,
671 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
672 &hash, G_TYPE_INVALID);
674 BT_ERR("GetProperties Call Error %s\n", error->message);
676 g_object_unref(characteristic_proxy);
677 return BLUETOOTH_ERROR_INTERNAL;
679 g_object_unref(characteristic_proxy);
681 retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
683 memset(characteristic, 0, sizeof(bt_gatt_char_property_t));
685 value = g_hash_table_lookup(hash, "UUID");
686 characteristic->uuid = value ? g_value_dup_string(value) : NULL;
687 if (characteristic->uuid) {
688 BT_DBG("characteristic->uuid = [%s] \n", characteristic->uuid);
691 value = g_hash_table_lookup(hash, "Name");
692 characteristic->name = value ? g_value_dup_string(value) : NULL;
693 if (characteristic->name) {
694 BT_DBG("characteristic->name = [%s] \n", characteristic->name);
697 value = g_hash_table_lookup(hash, "Description");
698 characteristic->description = value ? g_value_dup_string(value) : NULL;
699 if (characteristic->description) {
700 BT_DBG("characteristic->description = [%s] \n", characteristic->description);
703 value = g_hash_table_lookup(hash, "Value");
705 gb_array = value ? g_value_get_boxed(value) : NULL;
708 BT_DBG("gb_array->len = %d \n", gb_array->len);
709 characteristic->val_len = gb_array->len;
711 characteristic->val = g_malloc0(gb_array->len * sizeof(unsigned char));
712 memcpy(characteristic->val, gb_array->data, gb_array->len);
714 characteristic->val = NULL;
715 characteristic->val_len = 0;
718 characteristic->val = NULL;
719 characteristic->val_len = 0;
721 characteristic->handle = g_strdup(char_handle);
722 g_hash_table_destroy(hash);
723 return BLUETOOTH_ERROR_NONE;
726 BT_EXPORT_API int bluetooth_gatt_set_characteristics_value(const char *char_handle,
727 const guint8 *value, int length)
729 DBusGProxy *characteristic_proxy = NULL;
732 GError *error = NULL;
733 DBusGConnection *conn;
735 BT_CHECK_PARAMETER(char_handle, return);
736 BT_CHECK_PARAMETER(value, return);
737 retv_if(length == 0, BLUETOOTH_ERROR_INVALID_PARAM);
739 BT_CHECK_ENABLED(return);
741 conn = _bt_get_system_gconn();
742 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
744 BT_DBG("Requested characteristic handle:%s \n ", char_handle);
746 characteristic_proxy = dbus_g_proxy_new_for_name(conn,
747 BT_BLUEZ_NAME, char_handle,
748 BLUEZ_CHAR_INTERFACE);
750 retv_if(characteristic_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
752 gbarray = g_byte_array_new();
753 g_byte_array_append(gbarray, (guint8 *)value, length);
755 val = g_new0(GValue, 1);
756 g_value_init(val, DBUS_TYPE_G_UCHAR_ARRAY);
757 g_value_take_boxed(val, gbarray);
759 dbus_g_proxy_call(characteristic_proxy, "SetProperty",
760 &error, G_TYPE_STRING, "Value",
761 G_TYPE_VALUE, val, G_TYPE_INVALID, G_TYPE_INVALID);
763 g_object_unref(characteristic_proxy);
767 BT_ERR("Set value Fail: %s", error->message);
769 return BLUETOOTH_ERROR_INTERNAL;
772 return BLUETOOTH_ERROR_NONE;
775 BT_EXPORT_API int bluetooth_gatt_get_service_from_uuid(bluetooth_device_address_t *address,
776 const char *service_uuid,
777 bt_gatt_service_property_t *service)
781 bt_gatt_handle_info_t prim_svc;
783 BT_CHECK_PARAMETER(address, return);
784 BT_CHECK_PARAMETER(service_uuid, return);
785 BT_CHECK_PARAMETER(service, return);
787 BT_CHECK_ENABLED(return);
789 ret = bluetooth_gatt_get_primary_services(address, &prim_svc);
790 if (ret != BLUETOOTH_ERROR_NONE) {
791 BT_ERR("Get primary service failed ");
795 for (i = 0; i < prim_svc.count; i++) {
797 BT_DBG("prim_svc [%d] = %s", i, prim_svc.handle[i]);
799 ret = bluetooth_gatt_get_service_property(prim_svc.handle[i],
801 if (ret != BLUETOOTH_ERROR_NONE) {
802 BT_ERR("Get service property failed ");
803 bluetooth_gatt_free_primary_services(&prim_svc);
807 BT_DBG("Service uuid %s", service->uuid);
809 if (g_strstr_len(service->uuid, -1, service_uuid)) {
810 BT_DBG("Found requested service");
811 ret = BLUETOOTH_ERROR_NONE;
815 bluetooth_gatt_free_service_property(service);
818 if (i == prim_svc.count)
819 ret = BLUETOOTH_ERROR_NOT_FOUND;
821 bluetooth_gatt_free_primary_services(&prim_svc);
826 BT_EXPORT_API int bluetooth_gatt_get_char_from_uuid(const char *service_handle,
827 const char *char_uuid)
830 char_pty_req_t *char_pty;
832 bt_gatt_service_property_t svc_pty;
834 BT_CHECK_PARAMETER(service_handle, return);
835 BT_CHECK_PARAMETER(char_uuid, return);
837 BT_CHECK_ENABLED(return);
839 if (bluetooth_gatt_get_service_property(service_handle, &svc_pty) !=
840 BLUETOOTH_ERROR_NONE) {
841 BT_ERR("Invalid service");
842 return BLUETOOTH_ERROR_NOT_FOUND;
845 char_handles = svc_pty.handle_info.handle;
847 if (char_handles == NULL)
848 return __discover_char_from_uuid(svc_pty.handle, char_uuid);
850 char_pty = g_new0(char_pty_req_t, 1);
852 char_pty->handle = g_malloc0((svc_pty.handle_info.count + 1) *
854 for (i = 0; i < svc_pty.handle_info.count; i++) {
855 char_pty->handle[i] = char_handles[i];
856 BT_DBG("char_path[%d] : [%s]", i, char_pty->handle[i]);
858 char_pty->char_uuid = g_strdup(char_uuid);
860 g_idle_add(__filter_chars_with_uuid, char_pty);
862 return BLUETOOTH_ERROR_NONE;