Fix the issue on AppControl share (BT) operation
[platform/core/connectivity/bluetooth-frwk.git] / bt-api / bt-gatt-service.c
index e39c3a0..60c58ff 100644 (file)
@@ -155,15 +155,15 @@ int bluetooth_gatt_convert_perm2string(
 
 #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[] =
@@ -343,39 +343,37 @@ static struct gatt_desc_info *__bt_gatt_find_gatt_desc_info(
 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;
 
-       BT_INFO("request found  path [%s] att_handle [ %d]", path, att_handle);
+       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 -1;
+       }
+
        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 -2;
 }
 
 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;
        }
@@ -400,8 +398,13 @@ static gboolean bluetooth_gatt_write_channel_watch_cb(GIOChannel *gio,
                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);
 
@@ -435,9 +438,8 @@ static int bluetooth_gatt_write_characteristics_value_to_fd_(
                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;
 }
@@ -1566,12 +1568,18 @@ BT_EXPORT_API int bluetooth_gatt_unregister_application(void)
                        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");
@@ -2690,41 +2698,6 @@ BT_EXPORT_API int bluetooth_gatt_server_set_notification(const char *char_path,
        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)
 {
@@ -2823,12 +2796,8 @@ BT_EXPORT_API int bluetooth_gatt_server_add_new_characteristic(const char *char_
 
        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);
@@ -2933,7 +2902,7 @@ BT_EXPORT_API int bluetooth_gatt_server_send_response(const bluetooth_gatt_serve
 }
 
 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);
@@ -2951,13 +2920,21 @@ BT_EXPORT_API int bluetooth_gatt_server_send_indication(bluetooth_device_address
        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("Send Multicast");
                result  = bluetooth_gatt_write_characteristics_value_to_fd_(fd, att_value->data, att_value->length, NULL);
-       else
+               param->fd = fd;
+       } else if (fd == -2) {
+               BT_ERR("Acquire Notify FD not found for charatcristic handle");
+               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+               return BLUETOOTH_ERROR_INVALID_PARAM;
+       } else if (fd == -1) {
                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);
 
@@ -3053,7 +3030,20 @@ static gboolean bluetooth_gatt_server_acquire_channel_write_cb(GIOChannel *gio,
 
        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;
@@ -3086,10 +3076,6 @@ static gboolean bluetooth_gatt_server_acquire_channel_write_cb(GIOChannel *gio,
                }
 
                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);
@@ -3103,8 +3089,6 @@ static gboolean bluetooth_gatt_server_acquire_channel_write_cb(GIOChannel *gio,
                        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);
 
@@ -3116,22 +3100,12 @@ static gboolean bluetooth_gatt_server_acquire_channel_write_cb(GIOChannel *gio,
                        } 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;
 }
 
@@ -3179,7 +3153,7 @@ void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
        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;
@@ -3189,7 +3163,6 @@ void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
 
        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);
@@ -3198,9 +3171,8 @@ void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
        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);
@@ -3214,121 +3186,120 @@ void  bluetooth_gatt_server_send_acquire_write_response(GVariant * parameters)
                        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, "(iiiiiis)",
-                                                       &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);
-
-
-                       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);
+       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;
 
-                               //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_variant_get(parameters, "(iiiiii&s)",
+                                       &result,
+                                       &con_id,
+                                       &tran_id,
+                                       &att_han,
+                                       &mtu,
+                                       &offset,
+                                       &address);
 
-                               BT_INFO("FD write %d   characterstics path   \n", pipefd[0]);
+               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);
 
-                               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;
+       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_INFO("setting up g_io channel");
-                               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);
+       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);
 
-                                GUnixFDList *fd_list = g_unix_fd_list_new();
-                                GError *error = NULL;
+               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;
+       }
 
-                               g_unix_fd_list_append(fd_list, pipefd[1], &error);
-                               g_assert_no_error(error);
-                               close(pipefd[1]);
+       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);
 
-                               g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
+       GUnixFDList *fd_list = g_unix_fd_list_new();
+       GError *error = NULL;
 
-                               BT_INFO("Sending event BT_GATT_SERVER_ACQUIRE_NOTIFY_RESPONSE file descriptor value [%d] ", data.fd);
+       g_unix_fd_list_append(fd_list, pipefd[1], &error);
+       g_assert_no_error(error);
+       close(pipefd[1]);
 
-                               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);
+       g_array_append_vals(in_param1, &data, sizeof(bluetooth_gatt_server_acquire_response_params_t));
 
-                               BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       BT_DBG("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);
 
-                               //send
-                               if (result == BLUETOOTH_ERROR_NONE) {
+       BT_FREE_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
+       g_object_unref(fd_list);
 
-                                       BT_INFO("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));
+       //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_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);
+               _bt_gatt_server_event_cb(BLUETOOTH_EVENT_GATT_SERVER_NOTIFICATION_STATE_CHANGED,
+                               result, &info,
+                               event_info->cb, event_info->user_data);
 
-                               }
+       }
 }
 
 void cleanup_gatt_acquire_fd(int handle)
@@ -3340,11 +3311,14 @@ void cleanup_gatt_acquire_fd(int handle)
        chr_info = bluetooth_get_characteristic_info_from_path(handle);
 
        if (chr_info != NULL) {
-               BT_INFO("GATT Server: acquire notification char info found");
+               BT_INFO("GATT Server: acquire notification char info found [%s]", chr_info->path);
+
+               if (chr_info->watch_id > 0)
+                       g_source_remove(chr_info->watch_id);
 
-               if (chr_info->write_fd >= 0) {
-                       BT_INFO("closing fd");
-                       close(chr_info->write_fd);
+               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");