event_info->cb, event_info->user_data);
} else if (strcasecmp(signal_name, BT_GATT_SERVER_ACQUIRE_WRITE) == 0) {
- bluetooth_gatt_server_send_acquire_response(parameters);
+ bluetooth_gatt_server_send_acquire_write_response(parameters);
- } else if (strcasecmp(signal_name, BT_GATT_SERVER_NOTIFICATION_COMPLETED) == 0) {
+ } else if (strcasecmp(signal_name, BT_GATT_SERVER_ACQUIRE_NOTIFICATION) == 0) {
+
+ bluetooth_gatt_server_send_acquire_notify_response(parameters);
+
+ } else if (strcasecmp(signal_name, BT_GATT_SERVER_NOTIFICATION_COMPLETED) == 0) {
const char *address = NULL;
bluetooth_device_address_t dev_address = { {0} };
bluetooth_gatt_server_indicate_confirmed_info_t info;
#define BT_GATT_ATT_UUID_LEN_MAX 50
#define BT_GATT_SERVER_DBUS_NAME_LEN_MAX 50
+static GSList *gatt_characteristic_server_notify_list = NULL;;
/* Common defintions to follow , applicable for both
GATT_DIRECT and RELAY */
#define NUMBER_OF_FLAGS 10
+
+
int bluetooth_gatt_convert_prop2string(
bt_gatt_characteristic_property_t properties,
char *char_properties[])
static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id);
+
+
+typedef struct {
+ int write_fd;
+ int relpy_fd;
+ int mtu;
+ int att_hand;
+ char *path ;
+} bluetooth_gatt_acquire_notify_info_t;
+
+
+static int bluetooth_get_characteristic_fd(int att_handle , char *path)
+{
+ GSList *l;
+
+ BT_INFO("request found path [%s] att_handle [ %d]", path, att_handle);
+ for (l = gatt_characteristic_server_notify_list; l != NULL; l = l->next) {
+ bluetooth_gatt_acquire_notify_info_t *info = l->data;
+ BT_INFO(" sid [ %d]" , info->att_hand);
+ if (info->att_hand == att_handle)
+ return info->write_fd;
+ }
+ return -1;
+}
+
+static bluetooth_gatt_acquire_notify_info_t * bluetooth_get_characteristic_info_from_path(int att_handle)
+{
+ GSList *l;
+
+ BT_INFO("request found att_handle [ %d]", att_handle);
+ for (l = gatt_characteristic_server_notify_list; l != NULL; l = l->next) {
+ bluetooth_gatt_acquire_notify_info_t *info = l->data;
+ BT_INFO(" sid [ %d]" , info->att_hand);
+ if (info->att_hand == att_handle)
+ return info;
+ }
+ return NULL;
+}
+
+
+static void bluetooth_characteristic_info_free(bluetooth_gatt_acquire_notify_info_t *chr_info)
+{
+ g_free(chr_info);
+}
+
+static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
+ GIOCondition cond, gpointer data)
+{
+ bluetooth_gatt_acquire_notify_info_t *chr_info = (bluetooth_gatt_acquire_notify_info_t *)data;
+
+ if (!chr_info)
+ return FALSE;
+
+ if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
+ BT_ERR("Error : GIOCondition %d, []", cond);;
+ g_io_channel_shutdown(gio, TRUE, NULL);
+ g_io_channel_unref(gio);
+
+ gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+ bluetooth_characteristic_info_free(chr_info);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int bluetooth_gatt_write_characteristics_value_to_fd_(
+ int fd, const guint8 *value, int length,
+ 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 __bt_gatt_close_gdbus_connection(void)
{
GError *err = NULL;
BT_CHECK_PARAMETER(param, return);
BT_CHECK_PARAMETER(att_value, return);
BT_CHECK_ENABLED(return);
- int result;
+ int result = 0 ;
+ char addr[BLUETOOTH_ADDRESS_STRING_LENGTH] ;
+ int fd = -1;
BT_INIT_PARAMS();
BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
g_array_append_vals(in_param2, param, sizeof(bluetooth_gatt_server_indication_params_t));
g_array_append_vals(in_param3, addr_hex, sizeof(bluetooth_device_address_t));
- result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_SEND_INDICATION,
- in_param1, in_param2, in_param3, in_param4, &out_param);
+ _bt_convert_addr_type_to_string(addr, addr_hex->addr);
+ fd = bluetooth_get_characteristic_fd(param->atrribute_handle, addr);
+
+ if (fd > -1)
+ result = bluetooth_gatt_write_characteristics_value_to_fd_(fd, att_value->data, att_value->length, NULL);
+ else
+ result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_SEND_INDICATION,
+ in_param1, in_param2, in_param3, in_param4, &out_param);
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
BT_CHECK_ENABLED(return);
BT_CHECK_PARAMETER(value, return);
int result;
+ int fd = -1;
BT_INIT_PARAMS();
BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
g_array_append_vals(in_param1, &instance_id, sizeof(int));
g_array_append_vals(in_param2, value, sizeof(bluetooth_gatt_server_update_value_t));
+ fd = bluetooth_get_characteristic_fd(value->attribute_handle, "no adress");
- result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_UPDATE_VALUE,
+ if (fd > -1)
+ result = bluetooth_gatt_write_characteristics_value_to_fd_(fd, (unsigned char *)value->data.data, value->length, NULL);
+ else
+ result = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_SERVER_UPDATE_VALUE,
in_param1, in_param2, in_param3, in_param4, &out_param);
BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
return TRUE;
}
-void bluetooth_gatt_server_send_acquire_response(GVariant * parameters)
+void bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
{
int con_id = -1;
int tran_id = -1;
}
+
+
+void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters)
+{
+ int con_id = -1;
+ int tran_id = -1;
+ int att_han = -1;
+ int pipefd[2] = {-1,};
+ int mtu = -1;
+ int offset = -1;
+ char err_msg[512] = {'\0'};
+ GIOChannel *channel = NULL;
+ int result = -1;
+ int fd = -1;
+ bluetooth_gatt_acquire_notify_info_t *chr_info;
+
+ g_variant_get(parameters, "(iiiiii)",
+ &result,
+ &con_id,
+ &tran_id,
+ &att_han,
+ &mtu,
+ &offset);
+
+ BT_DBG("GATT ServerAcquire Conn ID: [%d]", con_id);
+ BT_DBG("GATT Server Acquire notify att handle:[%d]", att_han);
+ BT_DBG("GATT Server Acquire Notify Offset: [%d]", offset);
+
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) {
+ strerror_r(errno, err_msg, sizeof(err_msg));
+ BT_ERR("socketpair(): %s", err_msg);
+ return ;
+ }
+
+ fd = pipefd[0];
+
+ BT_INIT_PARAMS();
+ BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+ //param1 = g_array_new(TRUE, TRUE, sizeof(gchar));
+ bluetooth_gatt_server_acquire_response_params_t data;
+ data.req_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
+ data.fd = pipefd[1];
+ data.mtu = mtu;
+ data.request_id = tran_id;
+
+ BT_INFO("FD write %d characterstics path \n", pipefd[0]);
+
+ chr_info = bluetooth_get_characteristic_info_from_path(att_han);
+ if (!chr_info) {
+ chr_info = g_malloc0(sizeof(bluetooth_gatt_acquire_notify_info_t));
+ chr_info->write_fd = fd;
+ chr_info->att_hand = att_han;
+
+ gatt_characteristic_server_notify_list = g_slist_append(gatt_characteristic_server_notify_list, chr_info);
+ } else
+ chr_info->write_fd = fd;
+
+
+ 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 | G_IO_NVAL),
+ bluetooth_gatt_write_channel_watch_cb, chr_info);
+
+
+
+
+ GUnixFDList *fd_list = g_unix_fd_list_new();
+ GError *error = NULL;
+
+ g_unix_fd_list_append(fd_list, pipefd[1], &error);
+ g_assert_no_error(error);
+ close(pipefd[1]);
+
+ g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
+
+ BT_INFO("Sending event BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE file descriptor value [%d] ", data.fd);
+
+ result = _bt_send_request_with_unix_fd_list(BT_BLUEZ_SERVICE, BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE,
+ in_param1, in_param2, in_param3, in_param4, fd_list, &out_param, NULL);
+
+ BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+
+}
extern "C" {
#endif /* __cplusplus */
-void bluetooth_gatt_server_send_acquire_response(GVariant * parameter);
+#define BLUETOOTH_ADDRESS_STRING_LENGTH 18
+
+void bluetooth_gatt_server_send_acquire_write_response(GVariant * parameter);
+
+void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameter);
#ifdef __cplusplus
}
uint8_t bdaddr[6];
} __attribute__((packed));
+#define HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES 0XC10
+struct hal_ev_gatt_server_acquire_notify {
+ int32_t mtu;
+ int32_t trans_id;
+ int32_t conn_id;
+ int32_t char_handl;
+ char *path;
+} __attribute__((packed));
+
#endif //_BT_HAL_MSG_H_
return;
} else if (g_strcmp0(method_name, "AcquireNotify") == 0) {
+ uint16_t mtu = 512;
+ int char_hdl = -1;
+ struct hal_ev_gatt_server_acquire_notify ev;
+ struct gatt_service_info *svc_info = NULL;
+ struct gatt_client_info_t *conn_info = NULL;
+ struct gatt_req_info *req_info = NULL;
+ char * link = 0;
+ int len = 0;
+
+ DBG("AcquireNotify");
+ DBG("Application path = %s", object_path);
+ DBG("Sender = %s", sender);
+
+ GVariantIter* iter;
+ g_variant_get(parameters, "(a{sv})", &iter);
+ char* key = NULL;
+ GVariant* value = NULL;
+ while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+ if (g_strcmp0(key, "MTU") == 0)
+ g_variant_get(value, "q", &mtu);
+ }
+
+ DBG("AcquireNotify values retived");
+ DBG(" MTU = %u", mtu);
+
+ svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
+
+ if (svc_info == NULL) {
+ ERR("svc_info info not found\n");
+ goto done;
+ }
+
+ /* Store requets information */
+ req_info = g_new0(struct gatt_req_info, 1);
+ req_info->attr_path = g_strdup(object_path);
+ req_info->svc_path = g_strdup(svc_info->serv_path);
+ req_info->request_id = 33;
+ req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
+ req_info->offset = mtu;
+ req_info->context = invocation;
+
+ conn_info = g_new0(struct gatt_client_info_t, 1);
+ conn_info->addr = g_strdup(object_path);
+ INFO("Added GATT client path[%s]", conn_info->addr);
+ conn_info->connection_id = 33;
+ conn_info->instance_id = 33;
+ /* Append request info in list of requests for the particular connection */
+ conn_info->gatt_req_info_list = g_slist_append(conn_info->gatt_req_info_list, req_info);
+ gatt_client_info_list = g_slist_append(gatt_client_info_list, conn_info);
+
+ /* Send HAL event */
+ memset(&ev, 0, sizeof(ev));
+ ev.conn_id = 33;
+ ev.char_handl = char_hdl;
+ ev.mtu = mtu;
+ ev.trans_id = 33;
+
+ event_cb(HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES, (void *)&ev, sizeof(ev));
+
+ DBG("HAL_EV_GATT_ACQUIRE_NOTIFY_RES called");
+
+ return;
+ }
- }
done:
g_dbus_method_invocation_return_value(invocation, NULL);
}
req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist);
} else if (req_info->request_type == BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY) {
- g_dbus_method_invocation_return_value(req_info->context,
- g_variant_new("(hq)", fd, mtu));
+
+ INFO("GATT Server Send Response BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY to bluez %d\n", fd);
+ g_dbus_method_invocation_return_value_with_unix_fd_list(
+ req_info->context, g_variant_new("(hq)", 0, mtu), (GUnixFDList*)fdlist);
+
} else {
g_dbus_method_invocation_return_value(req_info->context, NULL);
}
bt_gatt_callbacks->server->request_acquire_write_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl, (bt_bdaddr_t *)ev->bdaddr);
}
+static void __bt_hal_handle_gatt_server_acquire_notify_requested(void *buf, uint16_t len)
+{
+ struct hal_ev_gatt_server_acquire_notify *ev = buf;
+
+ DBG("acquire notify requested event recived");
+
+ if (bt_gatt_callbacks->server->request_acquire_notify_cb)
+ bt_gatt_callbacks->server->request_acquire_notify_cb(ev->mtu, ev->conn_id, ev->trans_id, ev->char_handl);
+}
+
static void __bt_hal_handle_gatt_server_indicate_confirmed(void *buf, uint16_t len)
{
struct hal_ev_gatt_server_indicate_cfm *ev = buf;
__bt_hal_handle_gatt_server_acquire_write_requested(buf, len);
break;
}
+ case HAL_EV_GATT_SERVER_ACQUIRE_NOTIFY_RES:{
+ __bt_hal_handle_gatt_server_acquire_notify_requested(buf, len);
+ break;
+ }
default:
DBG("Event Currently not handled!!");
typedef void (*request_acquire_write_callback)(int mtu, int conn_id, int trans_id,
int attr_handle, bt_bdaddr_t *bda);
+typedef void (*request_acquire_notify_callback)(int fd, int conn_id, int trans_id,
+ int attr_handle);
+
+
/** Callback invoked when a previously prepared write is to be executed */
typedef void (*request_exec_write_callback)(int conn_id, int trans_id,
bt_bdaddr_t *bda, int exec_write);
notification_enabled_callback notif_enabled_cb;
#endif
request_acquire_write_callback request_acquire_write_cb;
+ request_acquire_notify_callback request_acquire_notify_cb;
} btgatt_server_callbacks_t;
/** Represents the standard BT-GATT server interface. */
typedef struct {
gatts_trans_attr_t attr_trans;
int mtu;
+ char *path;
bt_address_t address;
} event_gatts_srvc_acquire_attr_t ;
static void cb_gatts_response_confirmation(int status, int handle);
static void cb_gatts_acquire_write(int fd, int conn_id, int trans_id, int attr_handle, bt_bdaddr_t*);
+static void cb_gatts_acquire_notify(int fd, int conn_id, int trans_id, int attr_handle);
static void cb_indication_confirmation(int conn_id, int trans_id, int attr_handle, bt_bdaddr_t *bda);
static void cb_gatts_connection(int conn_id, int server_if, int connected, bt_bdaddr_t *bda);
#ifdef TIZEN_BT_HAL
cb_notifcation_changed,
#endif
- cb_gatts_acquire_write
+ cb_gatts_acquire_write,
+ cb_gatts_acquire_notify
};
/* Forward declaration for GATT client callbacks */
send_event(OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE, event, sizeof(event_gatts_srvc_acquire_attr_t));
}
+static void cb_gatts_acquire_notify(int mtu, int conn_id, int trans_id, int attr_handle)
+{
+ BT_INFO("BTGATT SERVER REQUEST ACQUIRE NOTIFY conn_id:%d", conn_id);
+
+ event_gatts_srvc_acquire_attr_t* event = g_new0(event_gatts_srvc_acquire_attr_t, 1);
+
+ event->attr_trans.attr_handle = attr_handle;
+ event->attr_trans.conn_id = conn_id;
+ event->attr_trans.trans_id = trans_id;
+ event->mtu = mtu;
+
+ send_event(OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY, event, sizeof(event_gatts_srvc_acquire_attr_t));
+
+}
+
static void cb_gatts_response_confirmation(int status, int handle)
{
BT_INFO("BTGATT SERVER RESPONSE CONFIRMATION CB, status:%d, handle:%d", status, handle);
break;
}
+ case BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE: {
+
+ bluetooth_gatt_server_acquire_response_params_t param;
+ char *app;
+ GDBusMessage *msg;
+ msg = g_dbus_method_invocation_get_message(context);
+ GUnixFDList *fd_list;
+ int fd = -1;
+ int *fd_list_array;
+ int len;
+
+ BT_ERR("sending acquire write respose \n");
+
+ fd_list = g_dbus_message_get_unix_fd_list(msg);
+
+ memset(¶m, 0x00, sizeof(bluetooth_gatt_server_acquire_response_params_t));
+
+ app = (char*)g_dbus_method_invocation_get_sender(context);
+
+ __bt_service_get_parameters(in_param1, ¶m,
+ sizeof(bluetooth_gatt_server_acquire_response_params_t));
+
+ BT_ERR("sending acquire write respose sent \n ");
+
+ fd_list_array = g_unix_fd_list_peek_fds(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];
+
+ param.fd = fd;
+ result = _bt_gatt_server_acquire_send_response(app, ¶m, fd_list);
+
+ break;
+ }
case BT_GATT_SERVER_SEND_INDICATION: {
bluetooth_gatt_server_indication_params_t param;
bluetooth_gatt_att_data_t data;
case BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE:
signal = BT_GATT_SERVER_ACQUIRE_WRITE;
break;
+ case BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY:
+ signal = BT_GATT_SERVER_ACQUIRE_NOTIFICATION;
+ break;
#endif
#ifdef TIZEN_GATT_CLIENT
case BLUETOOTH_EVENT_GATT_READ_CHAR: /* GATT Client */
_bt_send_event(BT_GATT_SERVER_EVENT,
BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_WRITE,
param);
+
+}
+
+static void __bt_handle_gatt_server_acquire_notify_requested(event_gatts_srvc_acquire_attr_t *event)
+{
+ GVariant *param = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+ struct gatt_server_req_info *req_info = NULL;
+
+ BT_INFO("GATT Server ACQUIRE Notify Req Connection ID: [%d]", event->attr_trans.conn_id);
+ BT_INFO("GATT Server ACQUIRE Notify Req Transaction ID:[%d]", event->attr_trans.trans_id);
+ BT_INFO("GATT Server ACQUIRE Notify Req Attribute Handle: [%d]", event->attr_trans.attr_handle);
+
+ req_info = g_new0(struct gatt_server_req_info, 1);
+ req_info->request_id = event->attr_trans.trans_id;
+ req_info->attribute_handle = event->attr_trans.attr_handle;
+ req_info->connection_id = event->attr_trans.conn_id;
+ req_info->request_type = BLUETOOTH_GATT_REQUEST_TYPE_ACQUIRE_NOTIFY;
+ gatt_server_requests = g_slist_append(gatt_server_requests, req_info);
+
+ param = g_variant_new("(iiiiii)", result,
+ event->attr_trans.conn_id,
+ event->attr_trans.trans_id,
+ event->attr_trans.attr_handle,
+ event->mtu, event->attr_trans.offset);
+
+ BT_INFO("GATT Server ACQUIRE Notify Req Attribute : ");
+
+ _bt_send_event(BT_GATT_SERVER_EVENT,
+ BLUETOOTH_EVENT_GATT_SERVER_ACQUIRE_NOTIFY,
+ param);
}
static void __bt_handle_gatt_server_write_requested(event_gatts_srvc_write_attr_t *event)
__bt_handle_gatt_server_acquire_write_requested((event_gatts_srvc_acquire_attr_t*)event_data);
break;
}
+ case OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY: {
+ BT_INFO("OAL Event: GATT ServerAcquire Notify Request");
+ __bt_handle_gatt_server_acquire_notify_requested((event_gatts_srvc_acquire_attr_t*)event_data);
+ break;
+ }
case OAL_EVENT_GATTS_IND_CONFIRM: {
BT_INFO("OAL Event: GATT Server Indication confirmed");
__bt_handle_gatt_server_indicate_confirmed((event_gatts_ind_cnfrm_t *)event_data);
BT_GATT_SERVER_DELETE_SERVICE,
BT_GATT_SERVER_SEND_RESPONSE,
BT_GATT_SERVER_ACQURE_WRITE_RESPONSE,
+ BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE,
BT_GATT_SERVER_SEND_INDICATION,
BT_GATT_SERVER_UPDATE_VALUE,
BT_GATT_SERVER_DEREGISTER,