summaryrefslogtreecommitdiff
path: root/src/bluetooth-gatt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth-gatt.c')
-rwxr-xr-xsrc/bluetooth-gatt.c415
1 files changed, 415 insertions, 0 deletions
diff --git a/src/bluetooth-gatt.c b/src/bluetooth-gatt.c
new file mode 100755
index 0000000..d2fa1c4
--- /dev/null
+++ b/src/bluetooth-gatt.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <dlog.h>
+#include <bluetooth-api.h>
+
+#include "bluetooth.h"
+#include "bluetooth_private.h"
+
+int bt_gatt_foreach_primary_services(const char *remote_address,
+ bt_gatt_primary_service_cb callback,
+ void *user_data)
+{
+ int i;
+ int ret;
+ bool foreach_call = true;
+ bluetooth_device_address_t addr_hex = { {0,} };
+ bt_gatt_handle_info_t *prim_svc;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(remote_address);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ prim_svc = g_new0(bt_gatt_handle_info_t, 1);
+
+ _bt_convert_address_to_hex(&addr_hex, remote_address);
+
+ ret = _bt_get_error_code(bluetooth_gatt_get_primary_services(&addr_hex,
+ prim_svc));
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x) : Failed to run function",
+ _bt_convert_error_to_string(ret), ret);
+ g_free(prim_svc);
+ return ret;
+ }
+
+ for (i = 0; i < prim_svc->count; i++) {
+ if (prim_svc->handle[i] == NULL)
+ continue;
+
+ BT_INFO("handle: %s", prim_svc->handle[i]);
+
+ if (foreach_call == true &&
+ !callback((bt_gatt_attribute_h)prim_svc->handle[i], user_data)) {
+ foreach_call = false;
+ }
+
+ /* Application should clone the handle using API in callback */
+ /* bt_gatt_clone_attribute_handle */
+ g_free(prim_svc->handle[i]);
+ }
+
+ g_free(prim_svc->handle);
+ g_free(prim_svc);
+
+ return ret;
+}
+
+int bt_gatt_discover_characteristics(bt_gatt_attribute_h service,
+ bt_gatt_characteristics_discovered_cb callback,
+ void *user_data)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(service);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ ret = _bt_get_error_code(bluetooth_gatt_discover_service_characteristics((const char *)service));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ _bt_set_cb(BT_EVENT_GATT_CHARACTERISTIC_DISCOVERED, callback, user_data);
+ }
+
+ return ret;
+}
+
+int bt_gatt_get_service_uuid(bt_gatt_attribute_h service, char **uuid)
+{
+ int i;
+ int ret;
+ bt_gatt_service_property_t property;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(service);
+
+ memset(&property, 0x00, sizeof(bt_gatt_service_property_t));
+
+ ret = _bt_get_error_code(bluetooth_gatt_get_service_property((const char *)service, &property));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ *uuid = g_strdup(property.uuid);
+
+ if (property.handle_info.count != 0 && property.handle_info.handle) {
+ for (i = 0; i < property.handle_info.count; i++) {
+ g_free(property.handle_info.handle[i]);
+ }
+ g_free(property.handle_info.handle);
+ }
+ }
+
+ return ret;
+}
+
+int bt_gatt_foreach_included_services(bt_gatt_attribute_h service,
+ bt_gatt_included_service_cb callback,
+ void *user_data)
+{
+ int i;
+ int ret;
+ bool foreach_call = true;
+ bt_gatt_service_property_t property;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(service);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ memset(&property, 0x00, sizeof(bt_gatt_service_property_t));
+
+ ret = _bt_get_error_code(bluetooth_gatt_get_service_property((const char *)service, &property));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ if (property.handle_info.count == 0 ||
+ property.handle_info.handle == NULL) {
+ return ret;
+ }
+
+ for (i = 0; i < property.handle_info.count; i++) {
+ if (property.handle_info.handle[i] == NULL)
+ continue;
+
+ if (foreach_call == true &&
+ !callback((bt_gatt_attribute_h)property.handle_info.handle[i],
+ user_data)) {
+ foreach_call = false;
+ }
+
+ g_free(property.handle_info.handle[i]);
+ }
+ g_free(property.handle_info.handle);
+ }
+ return ret;
+}
+
+int bt_gatt_set_characteristic_changed_cb(bt_gatt_characteristic_changed_cb callback,
+ void *user_data)
+{
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ _bt_set_cb(BT_EVENT_GATT_VALUE_CHANGED, callback, user_data);
+
+ return BT_ERROR_NONE;
+}
+
+int bt_gatt_unset_characteristic_changed_cb()
+{
+ BT_CHECK_INIT_STATUS();
+
+ _bt_unset_cb(BT_EVENT_GATT_VALUE_CHANGED);
+
+ return BT_ERROR_NONE;
+}
+
+int bt_gatt_watch_characteristic_changes(bt_gatt_attribute_h service)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(service);
+
+ ret = _bt_get_error_code(bluetooth_gatt_watch_characteristics((const char *)service));
+
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ return ret;
+}
+
+int bt_gatt_unwatch_characteristic_changes(bt_gatt_attribute_h service)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(service);
+
+ ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics((const char *)service));
+
+ if (ret != BT_ERROR_NONE)
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+
+ return ret;
+}
+
+int bt_gatt_get_characteristic_declaration(bt_gatt_attribute_h characteristic,
+ char **uuid, unsigned char **value,
+ int *value_length)
+{
+ int ret;
+ bt_gatt_char_property_t property;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(characteristic);
+
+ memset(&property, 0x00, sizeof(bt_gatt_char_property_t));
+
+ ret = _bt_get_error_code(bluetooth_gatt_get_characteristics_property((const char *)characteristic, &property));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ if (property.uuid) {
+ *uuid = g_strdup(property.uuid);
+ g_free(property.uuid);
+ }
+
+ if (property.val && property.val_len != 0) {
+ *value = g_memdup(property.val, property.val_len);
+ *value_length = property.val_len;
+ g_free(property.val);
+ }
+
+ g_free(property.name);
+
+ }
+
+ return ret;
+}
+
+int bt_gatt_set_characteristic_value(bt_gatt_attribute_h characteristic,
+ const unsigned char *value,
+ int value_length)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(characteristic);
+ BT_CHECK_INPUT_PARAMETER(value);
+
+ if (value_length <= 0)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value((const char *)characteristic,
+ (const guint8 *)value, value_length));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+
+ return ret;
+}
+
+int bt_gatt_set_characteristic_value_request(bt_gatt_attribute_h characteristic,
+ const unsigned char *value, int value_length,
+ bt_gatt_characteristic_write_cb callback)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(characteristic);
+ BT_CHECK_INPUT_PARAMETER(value);
+
+ if (value_length <= 0)
+ return BT_ERROR_INVALID_PARAMETER;
+
+ ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value_request(
+ (const char *)characteristic,
+ (const guint8 *)value, value_length));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ _bt_set_cb(BT_EVENT_GATT_WRITE_CHARACTERISTIC, callback, characteristic);
+ }
+
+ return ret;
+}
+
+int bt_gatt_clone_attribute_handle(bt_gatt_attribute_h *clone,
+ bt_gatt_attribute_h origin)
+{
+ int error = BT_ERROR_NONE;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(origin);
+
+ *clone = g_strdup((char *)origin);
+
+ return error;
+}
+
+int bt_gatt_destroy_attribute_handle(bt_gatt_attribute_h handle)
+{
+ int error = BT_ERROR_NONE;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(handle);
+
+ g_free(handle);
+
+ return error;
+}
+
+int bt_gatt_read_characteristic_value(bt_gatt_attribute_h characteristic,
+ bt_gatt_characteristic_read_cb callback)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(characteristic);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ ret = _bt_get_error_code(bluetooth_gatt_read_characteristic_value((const char *)characteristic));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ _bt_set_cb(BT_EVENT_GATT_READ_CHARACTERISTIC, callback, NULL);
+ }
+
+ return ret;
+}
+
+int bt_gatt_discover_characteristic_descriptor(bt_gatt_attribute_h characteristic_handle,
+ bt_gatt_characteristic_descriptor_discovered_cb callback,
+ void *user_data)
+{
+ int ret;
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(characteristic_handle);
+ BT_CHECK_INPUT_PARAMETER(callback);
+
+ ret = _bt_get_error_code(bluetooth_gatt_discover_characteristic_descriptor
+ ((const char *)characteristic_handle));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ } else {
+ _bt_set_cb(BT_EVENT_GATT_CHARACTERISTIC_DESCRIPTOR_DISCOVERED, callback, user_data);
+ }
+
+ return ret;
+}
+
+int bt_gatt_connect(const char *address, bool auto_connect)
+{
+ int ret;
+ bluetooth_device_address_t bd_addr = { {0,} };
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(address);
+ _bt_convert_address_to_hex(&bd_addr, address);
+
+ ret = _bt_get_error_code(bluetooth_connect_le(&bd_addr, auto_connect ? TRUE : FALSE));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ return ret;
+}
+
+int bt_gatt_disconnect(const char *address)
+{
+ int ret;
+ bluetooth_device_address_t bd_addr = { {0,} };
+
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(address);
+ _bt_convert_address_to_hex(&bd_addr, address);
+
+ ret = _bt_get_error_code(bluetooth_disconnect_le(&bd_addr));
+
+ if (ret != BT_ERROR_NONE) {
+ BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
+ }
+ return ret;
+}
+
+int bt_gatt_set_connection_state_changed_cb(bt_gatt_connection_state_changed_cb callback, void *user_data)
+{
+ BT_CHECK_INIT_STATUS();
+ BT_CHECK_INPUT_PARAMETER(callback);
+ _bt_set_cb(BT_EVENT_GATT_CONNECTION_STATUS, callback, user_data);
+
+ return BT_ERROR_NONE;
+}
+
+int bt_gatt_unset_connection_state_changed_cb(void)
+{
+ BT_CHECK_INIT_STATUS();
+ _bt_unset_cb(BT_EVENT_GATT_CONNECTION_STATUS);
+ return BT_ERROR_NONE;
+}
+