+
+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;
+
+}
+