#define NUMBER_OF_FLAGS 10
-GDBusConnection *g_conn;
-guint owner_id;
-guint manager_id;
+static GDBusConnection *g_conn;
+static guint owner_id;
+static guint manager_id;
static gboolean new_service = FALSE;
static gboolean new_char = FALSE;
static int serv_id = 1;
static bool is_server_started = false;
-GCancellable *register_cancel;
+static GCancellable *register_cancel;
/* Introspection data for the service we are exporting */
static const gchar service_introspection_xml[] =
static struct gatt_req_info *__bt_gatt_find_request_info(guint request_id);
static int __bt_gatt_unregister_service(struct gatt_service_info *svc_info);
-
-
-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)
+static int bluetooth_get_characteristic_fd(int att_handle , char *address)
{
GSList *l;
+ int ret = -1;
+
+ BT_DBG("Find FD for address [%s] att_handle [ %d]", address, att_handle);
+
+ /* Check for NULL address */
+ if (g_strcmp0(address, "00:00:00:00:00:00") != 0) {
+ BT_INFO("Unicast address: Use DBUS send indication");
+ return ret;
+ }
- 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)
+
+ if (info->att_hand == att_handle) {
+ BT_INFO("ATT handle Matched: AquireNotify Set: Remote addr[%s]", info->address);
return info->write_fd;
+ }
}
- return -1;
+ return ret;
}
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);
+ BT_DBG("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);
+ BT_DBG(" sid [ %d]" , info->att_hand);
if (info->att_hand == att_handle)
return info;
}
static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
GIOCondition cond, gpointer data)
{
+ BT_INFO("+");
+
bluetooth_gatt_acquire_notify_info_t *chr_info = (bluetooth_gatt_acquire_notify_info_t *)data;
- if (!chr_info)
+ if (!chr_info) {
+ BT_INFO("chr_info is NULL");
return FALSE;
+ }
- if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) {
- BT_ERR("Error : GIOCondition %d, []", cond);;
+ if (cond & G_IO_NVAL) {
+ BT_ERR("Invalid channel");
+ return FALSE;
+ }
+
+ if (cond & (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);
+ if (g_slist_find(gatt_characteristic_server_notify_list, chr_info)) {
+ BT_INFO("found char_info in the list");
+ gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+ bluetooth_characteristic_info_free(chr_info);
+ }
+
+ return FALSE;
+ }
+ if (g_slist_find(gatt_characteristic_server_notify_list, chr_info) == NULL) {
+ BT_INFO("chr_info is not in the list");
return FALSE;
}
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);
+ BT_ERR("write data failed %d is ", written);
+ }
return att_result;
}
GDBusProxy *proxy;
GError *err = NULL;
- g_conn = _bt_init_system_gdbus_conn();
+ g_conn = _bt_get_system_shared_conn();
if (!g_conn) {
BT_ERR("Unable to get connection");
return NULL;
if (err != NULL) {
BT_ERR("D-Bus API failure: errCode[%x], message[%s]",
err->code, err->message);
+ if (err->code == G_DBUS_ERROR_SERVICE_UNKNOWN ||
+ g_strrstr(err->message, BT_ERROR_DOES_NOT_EXIST)) {
+ g_clear_error(&err);
+ goto done;
+ }
g_clear_error(&err);
}
return BLUETOOTH_ERROR_INTERNAL;
}
g_variant_unref(ret);
+done:
is_server_started = false;
BT_INFO("UnregisterApplication is completed");
return BLUETOOTH_ERROR_ALREADY_INITIALIZED;
}
- g_conn = _bt_init_system_gdbus_conn();
+ g_conn = _bt_get_system_shared_conn();
if (!g_conn) {
BT_ERR("Unable to get connection");
goto failed;
return err;
}
-
-#if 0
-BT_EXPORT_API int bluetooth_gatt_register_application(int instance_id)
-{
- BT_INIT_PARAMS();
-
- if (!is_server_started) {
-
- if (_bt_check_privilege(BT_CHECK_PRIVILEGE, BT_GATT_REGISTER_APPLICATION)
- == BLUETOOTH_ERROR_PERMISSION_DEINED) {
- BT_ERR("Don't have aprivilege to use this API");
- return BLUETOOTH_ERROR_PERMISSION_DEINED;
- }
-
- BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
- g_array_append_vals(in_param1, &instance_id, sizeof(int));
-
- ret = _bt_send_request(BT_BLUEZ_SERVICE, BT_GATT_REGISTER_APPLICATION,
- in_param1, in_param2, in_param3, in_param4, &out_param);
- BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
-
- if (ret != BLUETOOTH_ERROR_NONE) {
- BT_ERR("Register application failed");
- return ret;
- }
- is_server_started = true;
-
- return BLUETOOTH_ERROR_NONE;
- }
-
- BT_INFO("Already RegisterApplication");
- return BLUETOOTH_ERROR_NONE;
-}
-#endif
-
BT_EXPORT_API int bluetooth_gatt_server_init(int *instance_id, gatt_server_cb_func_ptr callback_ptr,
void *user_data)
{
int result;
char uuid[BT_GATT_ATT_UUID_LEN_MAX + 1];
- int flag_count = 0;
- char *char_flags[NUMBER_OF_FLAGS];
g_strlcpy(uuid, char_uuid, sizeof(uuid));
- flag_count = bluetooth_gatt_convert_prop2string(param->properties, char_flags);
- BT_INFO("Flag count [%d]", flag_count);
BT_INIT_PARAMS();
BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
}
BT_EXPORT_API int bluetooth_gatt_server_send_indication(bluetooth_device_address_t *addr_hex,
- const bluetooth_gatt_server_indication_params_t *param,
+ bluetooth_gatt_server_indication_params_t *param,
const bluetooth_gatt_att_data_t *att_value)
{
BT_CHECK_PARAMETER(param, return);
g_array_append_vals(in_param3, addr_hex, sizeof(bluetooth_device_address_t));
_bt_convert_addr_type_to_string(addr, addr_hex->addr);
+ BT_INFO("Send Indication to address [%s]", addr);
fd = bluetooth_get_characteristic_fd(param->atrribute_handle, addr);
- if (fd > -1)
+ if (fd > -1) {
+ BT_INFO("Acquire Notify FD found: Send Multicast Indication over Socket");
result = bluetooth_gatt_write_characteristics_value_to_fd_(fd, att_value->data, att_value->length, NULL);
- else
+ param->fd = fd;
+ } else {
+ BT_ERR("Acquire Notify FD not found for charatcristic handle: Send DBUS indication");
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);
bluetooth_gatt_server_acquire_write_info_t *write_data = (bluetooth_gatt_server_acquire_write_info_t*)data;
- BT_INFO("FD io write data received remote adress [%s]\n", write_data->address);
+ BT_DBG("FD io write data received [%s]", write_data->address);
+
+ if (cond & G_IO_NVAL) {
+ BT_ERR("Invalid channel");
+ return FALSE;
+ }
+
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ BT_ERR("Error : GIOCondition %d", cond);
+ g_io_channel_shutdown(gio, TRUE, NULL);
+ g_io_channel_unref(gio);
+
+ return FALSE;
+ }
if (cond & G_IO_IN) {
GIOStatus status = G_IO_STATUS_NORMAL;
}
if (len > 0) {
-
- BT_INFO(" FD io sending value changed %s %zd \n", buffer, len);
-
-
bluetooth_gatt_server_write_requested_info_t write_info;
if (len < BLUETOOTH_GATT_ATT_DATA_LENGTH_MAX)
memcpy(write_info.data.data, buffer, len);
write_info.offset = write_data->offset;
write_info.request_id = -2;
- BT_INFO("ACQUIRING EVENT \n");
-
bt_event_info_t *event_info;
event_info = _bt_event_get_cb_data(BT_GATT_SERVER_EVENT);
} else {
BT_ERR("eventinfo failed");
}
-
-
}
g_free(buffer);
return TRUE;
}
- 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);
-
- return FALSE;
- }
-
return TRUE;
}
BT_DBG("GATT Server Acquire Write Offset: [%d]", offset);
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd) < 0) {
+ if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pipefd) < 0) {
strerror_r(errno, err_msg, sizeof(err_msg));
BT_ERR("socketpair(): %s", err_msg);
return ;
data.mtu = mtu;
data.request_id = tran_id;
- bluetooth_gatt_server_acquire_write_info_t *write_info = g_malloc0(sizeof(bluetooth_gatt_server_acquire_write_info_t)) ;
+ bluetooth_gatt_server_acquire_write_info_t *write_info = g_malloc0(sizeof(bluetooth_gatt_server_acquire_write_info_t)) ;
write_info->attribute_handle = att_han;
write_info->connection_id = tran_id;
BT_INFO("FD read %d remote address [%s ] \n", pipefd[0], addr);
-
channel = g_io_channel_unix_new(pipefd[0]);
g_io_channel_set_encoding(channel, NULL, NULL);
g_io_channel_set_buffered(channel, FALSE);
g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP),
bluetooth_gatt_server_acquire_channel_write_cb, write_info);
-
- GUnixFDList *fd_list = g_unix_fd_list_new();
- GError *error = NULL;
+ 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);
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);
-
+ g_object_unref(fd_list);
}
+void bluetooth_gatt_server_send_acquire_notify_response(GVariant * parameters, bt_event_info_t *event_info)
+{
+ 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;
+ const char *address = NULL;
+
+ g_variant_get(parameters, "(iiiiii&s)",
+ &result,
+ &con_id,
+ &tran_id,
+ &att_han,
+ &mtu,
+ &offset,
+ &address);
+
+ 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);
+ BT_DBG("GATT Server Acquire Notify address: [%s]", address);
-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 ;
- }
+ 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", pipefd[0]);
+
+ chr_info = bluetooth_get_characteristic_info_from_path(att_han);
+ if (!chr_info) {
+ BT_INFO("char info not found for ATT handle [%u]", att_han);
+ chr_info = g_malloc0(sizeof(bluetooth_gatt_acquire_notify_info_t));
+ chr_info->write_fd = fd;
+ chr_info->att_hand = att_han;
+ memcpy(chr_info->address, address, BLUETOOTH_ADDRESS_STRING_LENGTH);
+
+ gatt_characteristic_server_notify_list = g_slist_append(gatt_characteristic_server_notify_list, chr_info);
+ } else {
+ BT_INFO("Already AcquireNotify Set for this attribute handle by remote Client [%s]", chr_info->address);
+ chr_info->write_fd = fd;
+ }
- fd = pipefd[0];
+ channel = g_io_channel_unix_new(fd);
+ chr_info->io_channel = channel;
+ 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);
+ chr_info->watch_id =
+ 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);
- BT_INIT_PARAMS();
- BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+ GUnixFDList *fd_list = g_unix_fd_list_new();
+ GError *error = NULL;
- //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;
+ g_unix_fd_list_append(fd_list, pipefd[1], &error);
+ g_assert_no_error(error);
+ close(pipefd[1]);
- BT_INFO("FD write %d characterstics path \n", pipefd[0]);
+ g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
- 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;
+ BT_DBG("Sending event BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE file descriptor value [%d] ", data.fd);
- gatt_characteristic_server_notify_list = g_slist_append(gatt_characteristic_server_notify_list, chr_info);
- } else
- chr_info->write_fd = 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);
+ g_object_unref(fd_list);
- 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);
+ //send
+ if (result == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("sending gatt server notification state changed event");
+ bluetooth_gatt_server_notification_changed_t info;
+ bluetooth_device_address_t dev_address = { {0} };
+ memset(&info, 0x00, sizeof(bluetooth_gatt_server_notification_changed_t));
+ _bt_convert_addr_string_to_type(dev_address.addr, address);
+ memcpy(info.device_address.addr,
+ dev_address.addr,
+ BLUETOOTH_ADDRESS_LENGTH);
+ info.handle = att_han;
+ info.notification = TRUE;
+ _bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
+ result, &info,
+ event_info->cb, event_info->user_data);
+ }
+}
- GUnixFDList *fd_list = g_unix_fd_list_new();
- GError *error = NULL;
+void cleanup_gatt_acquire_fd(int handle)
+{
+ bluetooth_gatt_acquire_notify_info_t *chr_info = NULL;
- g_unix_fd_list_append(fd_list, pipefd[1], &error);
- g_assert_no_error(error);
- close(pipefd[1]);
+ BT_INFO("+");
- g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
+ chr_info = bluetooth_get_characteristic_info_from_path(handle);
- BT_INFO("Sending event BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE file descriptor value [%d] ", data.fd);
+ if (chr_info != NULL) {
+ BT_INFO("GATT Server: acquire notification char info found [%s]", chr_info->path);
- 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);
+ if (chr_info->watch_id > 0)
+ g_source_remove(chr_info->watch_id);
- BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+ if (chr_info->io_channel) {
+ g_io_channel_shutdown(chr_info->io_channel, TRUE, NULL);
+ g_io_channel_unref(chr_info->io_channel);
+ }
+ BT_INFO("Removing char_info from the list");
+ gatt_characteristic_server_notify_list = g_slist_remove(gatt_characteristic_server_notify_list, chr_info);
+ bluetooth_characteristic_info_free(chr_info);
+ }
}