#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
-
+#include<stdio.h>
#include <gio/gunixfdlist.h>
}
}
+void _bt_convert_uuid_type_to_string(char *str, const unsigned char *uuid)
+{
+ if (!str) {
+ BT_ERR("str == NULL");
+ return;
+ }
+
+ if (!uuid) {
+ BT_ERR("uuid == NULL");
+ return;
+ }
+
+ snprintf(str, 37,
+ "%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
+ uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
+}
+
void _bt_convert_addr_string_to_secure_string(char *addr, const char *address)
{
int len;
{BT_SET_LE_PRIVACY, "BT_SET_LE_PRIVACY"},
{BT_REQ_ATT_MTU, "BT_REQ_ATT_MTU"},
{BT_GET_ATT_MTU, "BT_GET_ATT_MTU"},
+ {BT_GATT_ACQUIRE_WRITE, "BT_GATT_ACQUIRE_WRITE"},
{BT_GET_DEVICE_IDA, "BT_GET_DEVICE_IDA"},
{BT_SET_LE_STATIC_RANDOM_ADDRESS, "BT_SET_LE_STATIC_RANDOM_ADDRESS"},
{BT_HDP_CONNECT, "BT_HDP_CONNECT"},
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
+#include <gio/gunixfdlist.h>
#include "bt-common.h"
#include "bt-event-handler.h"
#ifdef TIZEN_GATT_CLIENT
#include "bluetooth-gatt-client-api.h"
#include <arpa/inet.h>
+static GSList *gatt_characteristic_notify_list;
+static GSList *gatt_characteristic_write_list = NULL;;
#endif
#define GATT_DEFAULT_TIMEOUT (6 * 1000) // Dependent on supervision timeout 6 sec
}
}
-static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props,
- bt_gatt_service_property_t *service)
+static void __bt_fill_char_handle_informations(bt_char_browse_info_t *props, bt_gatt_service_property_t *service)
{
int count;
char uuid_string[BLUETOOTH_UUID_STRING_MAX];
as an asyn function and leave every thing else in the callback */
}
+
+static gboolean bluetooth_gatt_client_notify_channel_watch_cb(GIOChannel *gio,
+ GIOCondition cond, gpointer data)
+{
+ bt_gatt_characteristic_notify_info_t *chr_info = (bt_gatt_characteristic_notify_info_t *)data;
+
+ BT_INFO(" FD io NOTIFICATION recived\n");
+
+ if (!chr_info) {
+ BT_ERR("char INFO nort recieved");
+ return FALSE;
+ }
+ if (cond & G_IO_IN) {
+ GIOStatus status = G_IO_STATUS_NORMAL;
+ GError *err = NULL;
+ char *buffer = NULL;
+ gsize len = 0;
+ bt_event_info_t *event_info;
+
+ buffer = g_malloc0(chr_info->mtu + 1);
+
+ status = g_io_channel_read_chars(gio, buffer,
+ chr_info->mtu, &len, &err);
+ if (status != G_IO_STATUS_NORMAL) {
+ BT_ERR("IO Channel read is failed with %d", status);
+ g_free(buffer);
+ if (err) {
+ BT_ERR("IO Channel read error [%s]", err->message);
+ if (status == G_IO_STATUS_ERROR) {
+ BT_ERR("cond : %d", cond);
+ g_error_free(err);
+ g_io_channel_shutdown(gio, TRUE, NULL);
+ g_io_channel_unref(gio);
+
+ gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+ g_free(chr_info);
+ return FALSE;
+ }
+ g_error_free(err);
+ }
+ return FALSE;
+ }
+
+ if (len > 0) {
+
+ bt_gatt_notify_req_t char_val;
+ BT_INFO("FD io sending value changed %s %d \ni", buffer, len);
+
+ char_val.val = g_malloc0(len + 1);
+
+ memcpy(char_val.UUID, chr_info->UUID, 16);
+ memcpy(char_val.val, buffer, len);
+ char_val.len = len;
+ memcpy(char_val.adress, chr_info->adress, 18);
+
+ event_info = _bt_event_get_cb_data(BT_GATT_CLIENT_EVENT);
+
+ if (event_info) {
+
+ _bt_common_event_cb(BLUETOOTH_EVENT_GATT_CHAR_VAL_CHANGED,
+ BLUETOOTH_ERROR_NONE, &char_val,
+ event_info->cb, event_info->user_data);
+ } else {
+ BT_ERR("eventinfo failed");
+ }
+
+ g_free(char_val.val);
+
+ }
+ g_free(buffer);
+
+ return TRUE;
+ }
+
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+ BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
+ g_io_channel_shutdown(gio, TRUE, NULL);
+ g_io_channel_unref(gio);
+
+ gatt_characteristic_notify_list = g_slist_remove(gatt_characteristic_notify_list, chr_info);
+ g_free(chr_info);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_get_characteristic_notify_info(unsigned char *handle , int id)
+{
+ GSList *l;
+
+ for (l = gatt_characteristic_notify_list; l != NULL; l = l->next) {
+ bt_gatt_characteristic_notify_info_t *info = l->data;
+ if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
+ return info;
+ }
+ return NULL;
+}
+
+static bt_gatt_characteristic_notify_info_t * bluetooth_gatt_client_create_watch_io(int fd, int id, int mtu, char * address, unsigned char *uuid)
+{
+ GIOChannel *channel;
+ bt_gatt_characteristic_notify_info_t *chr_info;
+
+ chr_info = g_malloc0(sizeof(bt_gatt_characteristic_notify_info_t));
+ chr_info->notify_fd = fd;
+ chr_info->id = id;
+ chr_info->mtu = mtu;
+ g_strlcpy(chr_info->adress, address, 18);
+ memcpy(chr_info->UUID, uuid, 16);
+
+ channel = g_io_channel_unix_new(fd);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
+ bluetooth_gatt_client_notify_channel_watch_cb, chr_info);
+
+ return chr_info;
+
+}
+
BT_EXPORT_API int bluetooth_gatt_client_watch_characteristics(
const char *address,
bt_gatt_handle_property_t *service_handle,
{
int result = BLUETOOTH_ERROR_NONE;
bluetooth_gatt_client_char_prop_info_t param;
+ bt_gatt_characteristic_notify_info_t *chr_info;
+
BT_DBG("+");
BT_CHECK_PARAMETER(address, return);
BT_CHECK_PARAMETER(service_handle, return);
BT_CHECK_PARAMETER(char_handle, return);
+ chr_info = bluetooth_gatt_client_get_characteristic_notify_info(char_handle->uuid , char_handle->instance_id);
+ if (chr_info) {
+ BT_INFO("Already CCCD enabled. fd %d", chr_info->notify_fd);
+
+ if (!is_notify)
+ close(chr_info->notify_fd);
+
+ return result;
+ }
+
/* ASync Function, result expected in callback from bt-service */
BT_INIT_PARAMS();
g_array_append_vals(in_param2, &client_id, sizeof(int));
g_array_append_vals(in_param3, &is_notify, sizeof(gboolean));
- result = _bt_send_request(BT_BLUEZ_SERVICE,
+
+ GUnixFDList *out_fd_list = NULL;
+
+ result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_WATCH_CHARACTERISTIC,
+ in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+ BT_DBG("result: %x", result);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to send request");
+ return result;
+ } else if (NULL == out_fd_list) {
+ BT_ERR("out_fd_list is NULL");
+
+ } else {
+
+ int *fd_list_array;
+ int len = 0;
+ int mtu;
+ int fd = -1;;
+
+ if (!out_fd_list)
+ return BLUETOOTH_ERROR_INTERNAL;
+
+ fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+ BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
+ fd = fd_list_array[0];
+ mtu = g_array_index(out_param, int, 0);
+
+ chr_info = bluetooth_gatt_client_create_watch_io(fd, char_handle->instance_id, mtu, (char *)address, char_handle->uuid);
+
+ gatt_characteristic_notify_list = g_slist_append(gatt_characteristic_notify_list, chr_info);
+
+ g_free(fd_list_array);
+ g_object_unref(out_fd_list);
+
+ }
+
+ /*result = _bt_send_request(BT_BLUEZ_SERVICE,
BT_GATT_WATCH_CHARACTERISTIC,
- in_param1, in_param2, in_param3, in_param4, &out_param);
+ in_param1, in_param2, in_param3, in_param4, &out_param);*/
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
return result;
}
+
+static bt_gatt_characteristic_write_info_t * bluetooth_gatt_client_get_characteristic_fd(unsigned char *handle, int id)
+{
+ GSList *l;
+ char str[37];
+ _bt_convert_uuid_type_to_string(str, handle);
+ BT_INFO("request found UUID [%s], sid [ %d]", str, id);
+ for (l = gatt_characteristic_write_list; l != NULL; l = l->next) {
+ bt_gatt_characteristic_write_info_t *info = l->data;
+ _bt_convert_uuid_type_to_string(str, info->UUID);
+ BT_INFO("UUID [%s], sid [ %d]" , str, info->id);
+ if (memcmp(info->UUID, handle, 16) == 0 && info->id == id)
+ return info;
+ }
+ return NULL;
+}
+
+static gboolean bluetooth_gatt_client_write_channel_watch_cb(GIOChannel *gio,
+ GIOCondition cond, gpointer data)
+{
+ bt_gatt_characteristic_write_info_t *chr_info = (bt_gatt_characteristic_write_info_t *)data;
+
+ if (!chr_info)
+ return FALSE;
+
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+ BT_ERR("Error : GIOCondition %d, [%s]", cond, chr_info->UUID);
+ g_io_channel_shutdown(gio, TRUE, NULL);
+ g_io_channel_unref(gio);
+
+ gatt_characteristic_write_list = g_slist_remove(gatt_characteristic_write_list, chr_info);
+ g_free(chr_info);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int bluetooth_gatt_client_write_characteristics_value_to_fd(
+ int fd, const guint8 *value, int length, int mtu,
+ gpointer user_data)
+{
+ int written;
+ int att_result = BLUETOOTH_ERROR_NONE;
+ BT_CHECK_PARAMETER(value, return);
+ written = write(fd, value, length);
+ if (written != length) {
+ att_result = BLUETOOTH_ERROR_INTERNAL;
+ BT_INFO("write data failed %d is ", written);
+ } else
+ BT_INFO("write data %s is sucess ", value);
+
+ return att_result;
+}
+
+static void bluetooth_gatt_client_create_write_io_channel(int fd, unsigned char * uuid, int id, int mtu)
+{
+ bt_gatt_characteristic_write_info_t *chr_info;
+ GIOChannel *channel;
+
+ chr_info = g_malloc0(sizeof(bt_gatt_characteristic_write_info_t));
+ chr_info->write_fd = fd;
+ chr_info->id = id;
+ chr_info->mtu = mtu;
+
+ memcpy(chr_info->UUID, uuid, 16);
+ channel = g_io_channel_unix_new(fd);
+ g_io_channel_set_encoding(channel, NULL, NULL);
+ g_io_channel_set_buffered(channel, FALSE);
+ g_io_channel_set_close_on_unref(channel, TRUE);
+ g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_add_watch(channel, (G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+ bluetooth_gatt_client_write_channel_watch_cb, chr_info);
+
+ gatt_characteristic_write_list = g_slist_append(gatt_characteristic_write_list, chr_info);
+
+}
+
BT_EXPORT_API int bluetooth_gatt_client_write_characteristic_value_by_type(
const char *address,
bt_gatt_handle_property_t *service_handle,
g_array_append_vals(in_param2, data, sizeof(bluetooth_gatt_att_data_t));
g_array_append_vals(in_param3, &write_type, sizeof(bluetooth_gatt_write_type_e));
- result = _bt_send_request_async(BT_BLUEZ_SERVICE,
+ if (write_type == BLUETOOTH_GATT_TYPE_WRITE_NO_RESPONSE) {
+ int fd = -1;
+ int mtu = 0;
+ bt_gatt_characteristic_write_info_t *info;
+ info = bluetooth_gatt_client_get_characteristic_fd(char_handle->uuid, service_handle->instance_id);
+
+ if (info) {
+ fd = info->write_fd;
+ mtu = info->mtu;
+ }
+
+ if (fd < 0) {
+
+ GUnixFDList *out_fd_list = NULL;
+
+ result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_ACQUIRE_WRITE,
+ in_param1, in_param2, in_param3, in_param4, NULL, &out_param, &out_fd_list);
+ BT_DBG("result: %x", result);
+
+ mtu = g_array_index(out_param, int, 0);
+
+ if (result != BLUETOOTH_ERROR_NONE) {
+ BT_ERR("Fail to send request");
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+ return result;
+ } else if (NULL == out_fd_list) {
+ BT_ERR("out_fd_list is NULL");
+ return BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ int *fd_list_array;
+ int len = 0;
+
+ if (!out_fd_list) {
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ fd_list_array = g_unix_fd_list_steal_fds(out_fd_list, &len);
+ BT_INFO("Num fds in fd_list is : %d, fd_list[0]: %d", len, fd_list_array[0]);
+ fd = fd_list_array[0];
+
+ g_free(fd_list_array);
+ g_object_unref(out_fd_list);
+ }
+ BT_INFO("Acquired characteristic fd %d --------------- mtu %d, ", fd, mtu);
+
+ if (fd > -1) {
+
+ bluetooth_gatt_client_create_write_io_channel(fd, char_handle->uuid, service_handle->instance_id, mtu);
+
+ result = bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+
+ } else {
+ BT_INFO(" characteristic info FD is invalid\n");
+ goto done;
+ }
+
+ } else {
+ BT_INFO("Acquired characteristic fd %d --------------- mtu %d, ", fd, mtu);
+ result = bluetooth_gatt_client_write_characteristics_value_to_fd(fd, data->data, data->length, mtu, NULL);
+ }
+
+ } else {
+done:
+ result = _bt_send_request_async(BT_BLUEZ_SERVICE,
BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE,
in_param1, in_param2, in_param3, in_param4,
user_info->cb, user_info->user_data);
+ }
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
gboolean _bt_utf8_validate(char *name);
+void _bt_convert_uuid_type_to_string(char *str, const unsigned char *uuid);
+
typedef struct {
char *obj_path;
char *uuid;
gboolean _bluetooth_gatt_check_service_change_watcher_address(
const bluetooth_device_address_t *device_addr);
+typedef struct {
+ int write_fd;
+ int relpy_fd;
+ int mtu;
+ int id;
+ unsigned char UUID[16];
+ } bt_gatt_characteristic_write_info_t;
+
+typedef struct {
+ int notify_fd;
+ int id;
+ int mtu;
+ unsigned char UUID[16];
+ char adress[BLUETOOTH_ADDRESS_STRING_LENGTH];
+} bt_gatt_characteristic_notify_info_t;
+
+
#ifdef __cplusplus
}
uint8_t char_uuid[16];
} __attribute__((packed));
+#define HAL_EV_GATT_ACQUIRE_WRITE 0XC8
+struct hal_ev_gatt_acquire_write {
+ int32_t fd;
+ int32_t conn_id;
+ int32_t status;
+ uint8_t svc_uuid[16];
+ uint8_t char_uuid[16];
+} __attribute__((packed));
+
#define HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES 0XC9
struct hal_ev_gatt_server_acquire_write_res {
int32_t mtu;
#include <dlog.h>
#include <gio/gio.h>
#include <glib.h>
+#include <gio/gunixfdlist.h>
#include "bt-hal-log.h"
return BT_STATUS_SUCCESS;
}
+
+static int __bluetooth_gatt_acquire_write_fd(const char *chr, int *fd, int *mtu)
+{
+ GDBusConnection *conn;
+ GVariantBuilder *builder = NULL;
+ guint16 offset = 0;
+ GError *err = NULL;
+ GVariant *value;
+ gint32 idx;
+ guint16 att_mtu;
+ GUnixFDList *fd_list = NULL;
+
+ conn = _bt_hal_get_system_gconn();
+ if (NULL == conn) {
+ ERR("_bt_gdbus_get_system_gconn returned NULL");
+ return BT_STATUS_FAIL;
+ }
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+ //val = g_variant_new("ay", builder1);
+
+ g_variant_builder_add(builder, "{sv}", "offset",
+ g_variant_new("q", offset));
+
+ value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
+ "AcquireWrite", g_variant_new("(a{sv})", builder),
+ G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &fd_list, NULL, &err);
+ if (err != NULL) {
+ g_dbus_error_strip_remote_error(err);
+ ERR("Error: %s", err->message);
+ g_error_free(err);
+ g_variant_builder_unref(builder);
+ return BT_STATUS_FAIL;
+ }
+
+ g_variant_get(value, "(hq)", &idx, &att_mtu);
+ *fd = g_unix_fd_list_get(fd_list, idx, NULL);
+
+ INFO("FD is %d index is %d mtu is %d", *fd, idx, att_mtu);
+ *mtu = att_mtu;
+
+ g_object_unref(fd_list);
+ g_variant_unref(value);
+ g_variant_builder_unref(builder);
+
+ return BT_STATUS_SUCCESS;
+}
+
+static int __bluetooth_gatt_acquire_notify_fd(const char *chr, int *fd, int *mtu)
+{
+ GDBusConnection *conn;
+ GVariantBuilder *builder = NULL;
+ guint16 offset = 0;
+ GError *err = NULL;
+ GVariant *value;
+ gint32 idx, notify_fd;
+ guint16 att_mtu;
+ GUnixFDList *fd_list = NULL;
+
+ conn = _bt_hal_get_system_gconn();
+
+ if (NULL == conn) {
+ ERR("_bt_gdbus_get_system_gconn returned NULL");
+ return BT_STATUS_FAIL;
+ }
+
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+
+ g_variant_builder_add(builder, "{sv}", "offset",
+ g_variant_new("q", offset));
+
+ value = g_dbus_connection_call_with_unix_fd_list_sync(conn, BT_HAL_BLUEZ_NAME, chr, BT_HAL_GATT_CHAR_INTERFACE,
+ "AcquireNotify", g_variant_new("(a{sv})", builder),
+ G_VARIANT_TYPE("(hq)"), G_DBUS_CALL_FLAGS_NONE, -1,
+ NULL, &fd_list, NULL, &err);
+ if (err != NULL) {
+ g_dbus_error_strip_remote_error(err);
+ ERR("Error: %s", err->message);
+ g_error_free(err);
+ g_variant_builder_unref(builder);
+ return BT_STATUS_FAIL;
+ }
+
+ g_variant_get(value, "(hq)", &idx, &att_mtu);
+ notify_fd = g_unix_fd_list_get(fd_list, idx, NULL);
+ *mtu = att_mtu;
+
+ INFO("Acquired characteristic Notify fd %d, mtu %d", notify_fd, *mtu);
+
+ *fd = notify_fd;
+
+ g_object_unref(fd_list);
+ g_variant_unref(value);
+ g_variant_builder_unref(builder);
+
+ return BT_STATUS_SUCCESS;
+}
+
+
static bt_status_t _hal_write_characteristic_value(int conn_id, btgatt_srvc_id_t *srvc_id,
btgatt_gatt_id_t *char_id, int write_type, int length, int auth_req, char* value)
{
return BT_STATUS_SUCCESS;
}
+bt_status_t btif_get_acquire_write_fd(int conn_id,
+ btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
+ int auth_req, int *fd, int*mtu)
+{
+ CHECK_BTGATT_INIT();
+
+ DBG("+");
+
+ DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
+
+
+ hal_gattc_service_t *gattc_service = NULL;
+ hal_gattc_server_info_t * conn_info = NULL;
+ hal_gattc_char_t *gattc_char = NULL;
+ char char_uuid_str[BT_HAL_UUID_STRING_LEN];
+
+ bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_WRITE_NO_RESPONSE;
+ int ret = BT_STATUS_SUCCESS;
+
+ DBG("+");
+
+ /* get the connection info */
+ conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
+ if (NULL == conn_info) {
+ DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
+ return BT_STATUS_FAIL;
+ }
+
+ /* find service */
+ gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
+ if (NULL == gattc_service) {
+ DBG("Failed to get the gatt service");
+ return BT_STATUS_FAIL;
+ }
+
+ gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
+ if (NULL == gattc_char) {
+ DBG("Failed to get the gatt char");
+ return BT_STATUS_FAIL;
+ }
+
+ DBG("char path [%s]", gattc_char->chr_path);
+ _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
+ DBG("char uuid [%s]", char_uuid_str);
+
+
+ ret = __bluetooth_gatt_acquire_write_fd(gattc_char->chr_path, fd, mtu);
+ if (ret != BT_STATUS_SUCCESS)
+ return ret;
+
+
+ ERR("Characterstics FD erite characterstics fd is %d", *fd);
+
+ return ret;
+}
+
+bt_status_t btif_get_acquire_notify_fd(int conn_id,
+ btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id, int *fd, int *mtu)
+{
+ CHECK_BTGATT_INIT();
+
+ DBG("+");
+
+ DBG("svc isntance id:[%d]", srvc_id->id.inst_id);
+
+
+ hal_gattc_service_t *gattc_service = NULL;
+ hal_gattc_server_info_t * conn_info = NULL;
+ hal_gattc_char_t *gattc_char = NULL;
+ char char_uuid_str[BT_HAL_UUID_STRING_LEN];
+
+ bt_gatt_characteristic_property_t write_prop = HAL_GATT_CHARACTERISTIC_PROPERTY_NOTIFY;
+ int ret = BT_STATUS_SUCCESS;
+
+ DBG("+");
+
+ /* get the connection info */
+ conn_info = __bt_find_gatt_conn_info_from_conn_id(conn_id);
+ if (NULL == conn_info) {
+ DBG("Failed to get the conn_info for conn_id[%d]", conn_id);
+ return BT_STATUS_FAIL;
+ }
+
+ /* find service */
+ gattc_service = _gattc_find_service_from_uuid(conn_info, &srvc_id->id.uuid);
+ if (NULL == gattc_service) {
+ DBG("Failed to get the gatt service");
+ return BT_STATUS_FAIL;
+ }
+
+ gattc_char = _gattc_find_char_from_uuid(gattc_service, &char_id->uuid, write_prop);
+ if (NULL == gattc_char) {
+ DBG("Failed to get the gatt char");
+ return BT_STATUS_FAIL;
+ }
+
+ DBG("char path [%s]", gattc_char->chr_path);
+ _bt_hal_convert_uuid_type_to_string(char_uuid_str, gattc_char->chr_uuid.uu);
+ DBG("char uuid [%s]", char_uuid_str);
+
+
+ ret = __bluetooth_gatt_acquire_notify_fd(gattc_char->chr_path, fd, mtu);
+ if (ret != BT_STATUS_SUCCESS)
+ return ret;
+
+
+ ERR("Characterstics FD write characterstics fd is %d", *fd);
+
+ return ret;
+
+}
+
+
/** Write a remote characteristic */
bt_status_t btif_write_characteristic(int conn_id,
btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
btif_gattc_get_descriptor,
btif_read_characteristic,
btif_write_characteristic,
+ btif_get_acquire_write_fd,
+ btif_get_acquire_notify_fd,
btif_read_descriptor,
btif_write_descriptor,
execute_write,
/** Attribute change notification parameters */
typedef struct {
+ btgatt_srvc_id_t srvc_id;
+ btgatt_gatt_id_t char_id;
+ int fd;
+ uint8_t status;
+} btgatt_acquire_params_t;
+
+
+/** Attribute change notification parameters */
+typedef struct {
uint8_t value[BTGATT_MAX_ATTR_LEN];
bt_bdaddr_t bda;
btgatt_srvc_id_t srvc_id;
int write_type, int len, int auth_req,
char* p_value);
+ /** acquire fd for writing remote characterstics */
+ bt_status_t (*acquire_write)(int conn_id,
+ btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
+ int auth_req, int *fd , int *mtu);
+
+ /** acquire fd for notifying remote characterstics */
+ bt_status_t (*acquire_notify)(int conn_id,
+ btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
+ int *fd, int *mtu);
+
/** Read the descriptor for a given characteristic */
bt_status_t (*read_descriptor)(int conn_id,
btgatt_srvc_id_t *srvc_id, btgatt_gatt_id_t *char_id,
int len, oal_gatt_auth_req_t auth_req, char* data);
oal_status_t gattc_acquire_notify(int conn_id, oal_gatt_srvc_id_t *srvc_id,
- oal_gatt_id_t *char_id, int *fd , char *path);
+ oal_gatt_id_t *char_id, int *fd, int *mtu);
oal_status_t gattc_acquire_write(int conn_id, oal_gatt_srvc_id_t *srvc_id,
- oal_gatt_id_t *char_id, oal_gatt_auth_req_t auth_req , int *fd , char *path);
+ oal_gatt_id_t *char_id, oal_gatt_auth_req_t auth_req , int *fd, int*mtu);
oal_status_t gattc_write_descriptor(int conn_id, oal_gatt_srvc_id_t *srvc_id, oal_gatt_id_t *char_id, oal_gatt_id_t *desc_id,
oal_gatt_write_type_t write_type, int len, oal_gatt_auth_req_t auth_req, char* data);
return OAL_STATUS_SUCCESS;
}
+oal_status_t gattc_acquire_notify(int conn_id, oal_gatt_srvc_id_t *srvc_id,
+ oal_gatt_id_t *char_id, int *fd, int *mtu)
+{
+ int ret = OAL_STATUS_SUCCESS;
+ char uuid_str1[2*BT_UUID_STRING_MAX];
+ char uuid_str2[2*BT_UUID_STRING_MAX];
+ OAL_CHECK_PARAMETER(srvc_id, return);
+ OAL_CHECK_PARAMETER(char_id, return);
+ uuid_to_stringname(&(srvc_id->id.uuid), uuid_str1);
+ uuid_to_stringname(&(char_id->uuid), uuid_str2);
+ API_TRACE("Client Write Characteristic: Service_uuid: [%s], Char_uuid: [%s]", uuid_str1, uuid_str2);
+ CHECK_OAL_GATT_ENABLED();
+ CHECK_CLIENT_CONNECTION(conn_id);
+
+ ret = gatt_api->client->acquire_notify(conn_id, (btgatt_srvc_id_t *)srvc_id,
+ (btgatt_gatt_id_t *)char_id, fd, mtu);
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("GATT client write characteristic failed: %s", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t gattc_acquire_write(int conn_id, oal_gatt_srvc_id_t *srvc_id,
+ oal_gatt_id_t *char_id, oal_gatt_auth_req_t auth_req , int *fd, int*mtu)
+{
+ int ret = OAL_STATUS_SUCCESS;
+ char uuid_str1[2*BT_UUID_STRING_MAX];
+ char uuid_str2[2*BT_UUID_STRING_MAX];
+ OAL_CHECK_PARAMETER(srvc_id, return);
+ OAL_CHECK_PARAMETER(char_id, return);
+ uuid_to_stringname(&(srvc_id->id.uuid), uuid_str1);
+ uuid_to_stringname(&(char_id->uuid), uuid_str2);
+ API_TRACE("Client Write Characteristic: Service_uuid: [%s], Char_uuid: [%s]", uuid_str1, uuid_str2);
+ CHECK_OAL_GATT_ENABLED();
+ CHECK_CLIENT_CONNECTION(conn_id);
+
+ ret = gatt_api->client->acquire_write(conn_id, (btgatt_srvc_id_t *)srvc_id,
+ (btgatt_gatt_id_t *)char_id, auth_req, fd, mtu);
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("GATT client write characteristic failed: %s", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
oal_status_t gattc_write_characteristic(int conn_id, oal_gatt_srvc_id_t *srvc_id,
oal_gatt_id_t *char_id, oal_gatt_write_type_t write_type,
int len, oal_gatt_auth_req_t auth_req, char* data)
|| service_function == BT_GATT_GET_INCLUDED_SERVICES
|| service_function == BT_GATT_GET_CHARACTERISTIC_PROPERTIES
|| service_function == BT_GATT_WATCH_CHARACTERISTIC
+ || service_function == BT_GATT_ACQUIRE_WRITE
#endif
|| service_function == BT_AUDIO_SELECT_ROLE
|| service_function == BT_OBEX_SERVER_ACCEPT_CONNECTION)
}
/* Async: Remote Interaction */
+ case BT_GATT_ACQUIRE_WRITE: {
+
+ int fd = -1;
+ int mtu = -1;
+ bluetooth_gatt_client_char_prop_info_t param;
+
+ BT_INFO("GATT Client ACQUIRE WRITE recived");
+
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+
+ __bt_service_get_parameters(in_param1, ¶m,
+ sizeof(bluetooth_gatt_client_char_prop_info_t));
+
+
+ result = _bt_gatt_acquire_write(¶m , &fd, &mtu);
+
+ g_array_append_vals(*out_param1, &mtu, sizeof(int));
+
+ if (BLUETOOTH_ERROR_NONE == result)
+ BT_INFO("GATT Client: Save Invocation data for characteristic props app[%s] fd[ %d]", sender, fd);
+ else {
+ BT_ERR("Gatt Client Acqure Write");
+ break;
+ }
+
+ GUnixFDList *fd_list = NULL;
+ GError *error = NULL;
+
+ /* Add socket fd to unix_fd_list */
+ fd_list = g_unix_fd_list_new();
+ g_unix_fd_list_append(fd_list, fd, &error);
+
+ _bt_service_method_return_with_unix_fd_list(
+ context, *out_param1, result, fd_list);
+
+ close(fd);
+ g_object_unref(fd_list);
+
+ break;
+ }
+ /* Async: Remote Interaction */
case BT_CONNECT_LE: {
bluetooth_device_address_t address = { {0} };
gboolean auto_connect;
bluetooth_gatt_client_char_prop_info_t param;
int client_id;
gboolean is_notify;
+ int fd = -1;
+ int mtu = 0;
+
memset(¶m, 0x00, sizeof(bluetooth_gatt_client_char_prop_info_t));
__bt_service_get_parameters(in_param3, &is_notify,
sizeof(gboolean));
- result = _bt_gatt_watch_characteristic(¶m , client_id, is_notify);
- if (BLUETOOTH_ERROR_NONE == result) {
- BT_INFO("GATT Client: Save Invocation data for characteristic props app[%s]", sender);
- /* Save the informations to invocation */
- _bt_save_invocation_context(context, result, sender,
- function_name,
- (gpointer)g_memdup(¶m, sizeof(bluetooth_gatt_client_char_prop_info_t)));
+ if (is_notify == true) {
+ result = _bt_gatt_acquire_notify(¶m , &fd, &mtu);
+ if (BLUETOOTH_ERROR_NONE == result && fd > -1) {
+ BT_INFO("GATT Client: Save Invocation data for characteristic props app[%s] fd[ %d]", sender, fd);
+
+ GUnixFDList *fd_list = NULL;
+ GError *error = NULL;
+
+ g_array_append_vals(*out_param1, &mtu, sizeof(int));
+ /* Add socket fd to unix_fd_list */
+ fd_list = g_unix_fd_list_new();
+ g_unix_fd_list_append(fd_list, fd, &error);
+ g_assert_no_error(error);
+ close(fd);
+ _bt_service_method_return_with_unix_fd_list(
+ context, *out_param1, result, fd_list);
+
+ g_object_unref(fd_list);
+ } else
+ goto normal;
+ } else {
+
+normal:
+ result = _bt_gatt_watch_characteristic(¶m , client_id, is_notify);
+ if (BLUETOOTH_ERROR_NONE == result) {
+ BT_INFO("GATT Client: Save Invocation data for characteristic props app[%s]", sender);
+
+ /* Save the informations to invocation */
+ _bt_save_invocation_context(context, result, sender, function_name,
+ (gpointer)g_memdup(¶m, sizeof(bluetooth_gatt_client_char_prop_info_t)));
+ }
}
break;
}
#ifdef TIZEN_GATT_CLIENT
case BT_GATT_READ_DESCRIPTOR_VALUE: /* GATT Client */
case BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE: /* GATT Client */
+ case BT_GATT_ACQUIRE_WRITE:
case BT_GATT_WRITE_DESCRIPTOR_VALUE: /* GATT Client */
case BT_GATT_WATCH_CHARACTERISTIC: /* GATT Client */
case BT_GATT_CLIENT_REGISTER: /* GATT Client */
case BT_GATT_SERVER_DELETE_SERVICE:
case BT_GATT_SERVER_SEND_RESPONSE:
case BT_GATT_SERVER_ACQURE_WRITE_RESPONSE:
+ case BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE:
case BT_GATT_SERVER_SEND_INDICATION:
case BT_GATT_SERVER_UPDATE_VALUE:
case BT_GATT_SERVER_DEREGISTER:
struct gatt_server_req_info *req_info = NULL;
bluetooth_device_address_t dev_addr;
char adress[BT_ADDRESS_STRING_SIZE] = {'/0',};
- ;
+
BT_INFO("GATT Server ACQUIRE Write Req Connection ID: [%d]", event->attr_trans.conn_id);
BT_INFO("GATT Server ACQUIRE Write Req Transaction ID:[%d]", event->attr_trans.trans_id);
BT_INFO("GATT Server ACQUIRE Write Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
event->mtu, event->attr_trans.offset, adress);
BT_INFO("GATT Server ACQUIRE Write Req Attribute remote adress : [%s]", adress);
-
_bt_send_event(BT_GATT_SERVER_EVENT,
BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
param);
return BLUETOOTH_ERROR_NONE;
}
+/*acquire Notify*/
+int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
+{
+ struct gatt_server_info_t *conn_info = NULL;
+ oal_gatt_srvc_id_t srvc_id;
+ oal_gatt_id_t char_id;
+ int ret = OAL_STATUS_SUCCESS;
+ char *addr;
+
+ BT_CHECK_PARAMETER(chr, return);
+
+ BT_INFO("+");
+
+ addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
+ _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
+
+ /* Check if remote GATT Server is connected or not */
+ conn_info = __bt_find_remote_gatt_server_info(addr);
+ if (conn_info) {
+ BT_INFO("GATT Server [%s] is connected, conn Id [%d]",
+ conn_info->addr, conn_info->connection_id);
+ } else {
+ BT_ERR("GATT Server is not yet connected..");
+ g_free(addr);
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ srvc_id.is_prmry = TRUE;
+ srvc_id.id.inst_id = chr->svc.instance_id;
+ memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+ char_id.inst_id = chr->characteristic.instance_id;
+ memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+ ret = gattc_acquire_notify(conn_info->connection_id, &srvc_id, &char_id, fd, mtu);
+
+ if (ret != OAL_STATUS_SUCCESS) {
+ BT_ERR("ret: %d", ret);
+ g_free(addr);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ BT_INFO("GATT characterstics FD [%d] mtu[%d]", *fd, *mtu);
+ g_free(addr);
+ return BLUETOOTH_ERROR_NONE;
+}
+
+/*acquire Write*/
+int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd, int *mtu)
+{
+
+ struct gatt_server_info_t *conn_info = NULL;
+ oal_gatt_srvc_id_t srvc_id;
+ oal_gatt_id_t char_id;
+ int ret = OAL_STATUS_SUCCESS;
+ char *addr;
+
+ BT_CHECK_PARAMETER(chr, return);
+
+ BT_INFO("+");
+
+ addr = g_malloc0(sizeof(char) * BT_ADDRESS_STRING_SIZE);
+ _bt_convert_addr_type_to_string(addr, chr->device_address.addr);
+
+ /* Check if remote GATT Server is connected or not */
+ conn_info = __bt_find_remote_gatt_server_info(addr);
+ if (conn_info) {
+ BT_INFO("GATT Server [%s] is connected, conn Id [%d]",
+ conn_info->addr, conn_info->connection_id);
+ } else {
+ BT_ERR("GATT Server is not yet connected..");
+ g_free(addr);
+ return BLUETOOTH_ERROR_NOT_CONNECTED;
+ }
+
+ srvc_id.is_prmry = TRUE;
+ srvc_id.id.inst_id = chr->svc.instance_id;
+ memcpy(srvc_id.id.uuid.uuid, chr->svc.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+ char_id.inst_id = chr->characteristic.instance_id;
+ memcpy(char_id.uuid.uuid, chr->characteristic.uuid, BLUETOOTH_UUID_HEX_MAX_LEN);
+
+ ret = gattc_acquire_write(conn_info->connection_id, &srvc_id, &char_id,
+ OAL_GATT_AUTH_REQ_NONE, fd, mtu);
+ if (ret != OAL_STATUS_SUCCESS) {
+ BT_ERR("ret: %d", ret);
+ g_free(addr);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ BT_INFO("GATT characterstics FD [%d] mtu [%d]", *fd, *mtu);
+ g_free(addr);
+ return BLUETOOTH_ERROR_NONE;
+
+}
+
/* Write Characteristic */
int _bt_gatt_write_characteristic_value_by_type(
bluetooth_gatt_att_data_t *data,
bluetooth_gatt_write_type_e write_type);
+int _bt_gatt_acquire_notify(bluetooth_gatt_client_char_prop_info_t *chr, int *fd , int *mtu);
+
+int _bt_gatt_acquire_write(bluetooth_gatt_client_char_prop_info_t *chr, int *fd , int *mtu);
+
int _bt_gatt_write_descriptor_value_by_type(
bluetooth_gatt_client_desc_prop_info_t *desc,
bluetooth_gatt_att_data_t *data,
guint32 val_len;
} bt_gatt_char_value_t;
+typedef struct {
+ unsigned char UUID[16];
+ char adress[18];
+ char *val;
+ int len;
+} bt_gatt_notify_req_t ;
+
/**
* Structure to GATT Read Request
*/
BT_GATT_WRITE_CHARACTERISTIC_VALUE_BY_TYPE, /* GATT Client */
BT_GATT_WRITE_DESCRIPTOR_VALUE, /* GATT Client */
BT_GATT_WATCH_SERVICE_CHANGED_INDICATION, /* GATT Client */
+ BT_GATT_ACQUIRE_WRITE, /* GATT Client */
#endif
BT_GATT_DISCOVER_CHARACTERISTICS_DESCRIPTOR,
#ifndef GATT_NO_RELAY
BT_OTP_ENABLE_NOTIFICATION,
BT_OTP_WRITE_VALUE,
BT_LE_OTC_CONNECT,
- BT_LE_OTC_DISCONNECT
+ BT_LE_OTC_DISCONNECT,
} bt_function_t;
typedef struct {