Fix the coverity issues
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-gatt-server.c
index 3fc25d1..26d15c8 100644 (file)
@@ -40,6 +40,7 @@
 #include "bt-hal-utils.h"
 #include "bt-hal-dbus-common-utils.h"
 
+#include "bt-hal-gatt.h"
 #include "bt-hal-adapter-le.h"
 #include "bt-hal-event-receiver.h"
 
@@ -58,11 +59,10 @@ static GDBusProxy *manager_gproxy = NULL;
  **  Static variables
  ************************************************************************************/
 extern const btgatt_callbacks_t *bt_gatt_callbacks;
-guint owner_id;
-GDBusConnection *g_conn = NULL;
-//GDBusConnection *conn = NULL;
-GDBusNodeInfo *manager_node_info = NULL;
-guint manager_id;
+static guint owner_id;
+static GDBusConnection *g_conn = NULL;
+static GDBusNodeInfo *manager_node_info = NULL;
+static guint manager_id;
 
 /* Global handles which needs to be incremented during each addition */
 static int gatt_service_handle = 10;
@@ -204,7 +204,7 @@ static int assigned_id = 0;
 
 static gboolean instance_id_used[BT_GATTS_MAX];
 
-#define CHECK_BTGATT_INIT() if (bt_gatt_callbacks == NULL)\
+#define CHECK_BTGATT_INIT() if (_bt_hal_gatt_interface_ready() == false)\
 {\
        ERR("%s: BTGATT not initialized", __FUNCTION__);\
        return BT_STATUS_NOT_READY;\
@@ -342,10 +342,35 @@ static const gchar manager_introspection_xml[] =
 "  </interface>"
 "</node>";
 
+static void __bt_free_gatt_server_app(struct gatt_server_app *app)
+{
+       g_free(app->app_path);
+       g_free(app);
+}
+
+static void __bt_hal_gatt_free_service_info(struct gatt_service_info *svc_info)
+{
+       if (!svc_info)
+               return;
+
+       g_free(svc_info->serv_path);
+       g_free(svc_info->service_uuid);
+       g_free(svc_info);
+}
+
 void _bt_hal_gatt_server_init(void)
 {
        assigned_id = 0;
        memset(instance_id_used, 0x00, sizeof(instance_id_used));
+
+       g_slist_free_full(gatt_server_apps, (GDestroyNotify)__bt_free_gatt_server_app);
+       gatt_server_apps = NULL;
+
+       g_slist_free_full(gatt_services, (GDestroyNotify)__bt_hal_gatt_free_service_info);
+       gatt_services = NULL;
+
+       g_slist_free_full(hal_gatts_server_register_list, g_free);
+       hal_gatts_server_register_list = NULL;
 }
 
 static int __bt_hal_gatt_assign_id(void)
@@ -402,6 +427,24 @@ static GSList *_bt_get_service_list_from_server(int instance)
        return NULL;
 }
 
+static char *__bt_get_server_app_path_from_server(int instance)
+{
+       GSList *l;
+       INFO("Number of GATT Server apps [%d]", g_slist_length(gatt_server_apps));
+       INFO("Find App with slot [%d]", instance);
+
+       for (l = gatt_server_apps; l; l = g_slist_next(l)) {
+               struct gatt_server_app *app = (struct gatt_server_app *)l->data;
+
+               if (app->slot == instance) {
+                       INFO("App slot [%d] Found, App path [%s]",
+                                       app->slot, app->app_path);
+                       return app->app_path;
+               }
+       }
+       return NULL;
+}
+
 static void _bt_remote_service_from_gatt_server(int instance, int service_handle)
 {
        GSList *l;
@@ -1372,136 +1415,142 @@ static void __bt_gatt_char_method_call(GDBusConnection *connection,
                event_cb(HAL_EV_GATT_INDICATE_CFM, (void *)&ev, sizeof(ev));
        } else if (g_strcmp0(method_name, "AcquireWrite") == 0) {
 
-                               uint16_t mtu = 512;
-                               int char_hdl = -1;
-                               struct hal_ev_gatt_server_acquire_write_res  ev;
-                               struct gatt_service_info *svc_info = NULL;
-                               struct gatt_req_info *req_info = NULL;
-                               struct gatt_client_info_t *conn_info = NULL;
-                               char * dev_path = NULL;
-                               char * link = 0;
-                               char  addr[BT_HAL_ADDRESS_STRING_SIZE];
-
-                               DBG("AcquireWrite : Application path %s, sender %s", object_path, 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, "i", &mtu);
-                                               else if (g_strcmp0(key, "link") == 0)
-                                                       g_variant_get(value, "s", &link);
-                                               else if (g_strcmp0(key, "device") == 0)
-                                                       g_variant_get(value, "o", &dev_path);
-                               }
+               uint16_t mtu = 512;
+               int char_hdl = -1;
+               struct hal_ev_gatt_server_acquire_write_res  ev;
+               struct gatt_service_info *svc_info = NULL;
+               struct gatt_req_info *req_info = NULL;
+               struct gatt_client_info_t *conn_info = NULL;
+               char *dev_path = NULL;
+               char *link = NULL;
+               char  addr[BT_HAL_ADDRESS_STRING_SIZE];
+
+               DBG("AcquireWrite : Application path %s, sender %s", object_path, 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);
+                               else if (g_strcmp0(key, "link") == 0)
+                                       g_variant_get(value, "s", &link);
+                               else if (g_strcmp0(key, "device") == 0)
+                                       g_variant_get(value, "o", &dev_path);
+               }
 
-                               DBG(" path  %s LINK = %s, MTU = %u", addr, link, mtu);
+               DBG(" path  %s LINK = %s, MTU = %u", dev_path, link, mtu);
 
-                               svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
+               svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
 
-                               _bt_hal_convert_device_path_to_address(dev_path, addr);
+               _bt_hal_convert_device_path_to_address(dev_path, addr);
 
-                               DBG("remote address %s", addr);
+               DBG("remote address %s", addr);
+               g_free(link);
+               g_free(dev_path);
 
-                               /* Check if device is already in connected list */
-                               conn_info = __bt_find_remote_gatt_client_info(addr);
+               /* Check if device is already in connected list */
+               conn_info = __bt_find_remote_gatt_client_info(addr);
+               if (conn_info == NULL) {
+                       ERR("Cleint info not found\n");
+                       g_variant_iter_free(iter);
+                       goto done;
+               }
 
-                               if (conn_info == NULL) {
-                                       ERR("Cleint info not found\n");
-                                       goto done;
-                               }
+               if (svc_info == NULL) {
+                       ERR("svc_info  info not found\n");
+                       g_variant_iter_free(iter);
+                       goto done;
+               }
 
-                               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 = conn_info->connection_id;
+               req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
+               req_info->offset = mtu;
+               req_info->context = invocation;
 
-                               /* 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 = conn_info->connection_id;
-                               req_info->request_type = BT_HAL_GATT_REQUEST_TYPE_ACQUIRE_WRITE;
-                               req_info->offset = mtu;
-                               req_info->context = invocation;
+               /* 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);
 
-                               /* 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);
+               /* Send HAL event */
+               memset(&ev, 0, sizeof(ev));
+               ev.conn_id = conn_info->connection_id;
+               ev.char_handl = char_hdl;
+               ev.mtu = mtu;
+               ev.trans_id = conn_info->connection_id;
+               _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
+               event_cb(HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES, (void *)&ev, sizeof(ev));
+               g_variant_iter_free(iter);
+               return;
+       } else if (g_strcmp0(method_name, "AcquireNotify") == 0) {
 
-                               /* Send HAL event */
-                               memset(&ev, 0, sizeof(ev));
-                               ev.conn_id = conn_info->connection_id;
-                               ev.char_handl = char_hdl;
-                               ev.mtu = mtu;
-                               ev.trans_id = conn_info->connection_id;
-                               _bt_hal_convert_addr_string_to_type(ev.bdaddr, addr);
-                               event_cb(HAL_EV_GATT_SERVER_ACQUIRE_WRITE_RES, (void *)&ev, sizeof(ev));
-                       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;
-
-                               DBG("AcquireNotify : Application path %s, sender %s", object_path, 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);
-                               }
+               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;
 
-                               DBG("MTU = %u",  mtu);
+               DBG("AcquireNotify : Application path %s, sender %s", object_path, sender);
 
-                               svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
+               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);
+               }
 
-                       if (svc_info == NULL) {
-                                       ERR("svc_info  info not found\n");
-                                       goto done;
-                               }
+               DBG("MTU = %u",  mtu);
 
-                               /* 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("AcquireNotify : 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));
-                               return;
+               svc_info = __bt_gatt_find_gatt_service_from_char(object_path, &char_hdl);
+
+               if (svc_info == NULL) {
+                       ERR("svc_info  info not found\n");
+                       g_variant_iter_free(iter);
+                       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("AcquireNotify : 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));
+               g_variant_iter_free(iter);
+               return;
        }
 
 done:
        g_dbus_method_invocation_return_value(invocation, NULL);
 }
 
-static gboolean __bt_hal_gatt_emit_interface_removed(gchar *object_path, gchar *interface)
+static gboolean __bt_hal_gatt_emit_interface_removed(const char *app_path, gchar *object_path, gchar *interface)
 {
        gboolean ret;
        GError *error = NULL;
@@ -1511,8 +1560,8 @@ static gboolean __bt_hal_gatt_emit_interface_removed(gchar *object_path, gchar *
        g_variant_builder_init(array_builder, G_VARIANT_TYPE("as"));
        g_variant_builder_add(array_builder, "s", interface);
 
-       ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
-                       "org.freedesktop.Dbus.Objectmanager",
+       ret = g_dbus_connection_emit_signal(g_conn, NULL, app_path,
+                       "org.freedesktop.DBus.ObjectManager",
                        "InterfacesRemoved",
                        g_variant_new("(oas)",
                                object_path, array_builder),
@@ -1565,17 +1614,6 @@ static void __bt_hal_gatt_free_characteristic_info(struct gatt_char_info *char_i
        g_free(char_info);
 }
 
-
-static void __bt_hal_gatt_free_service_info(struct gatt_service_info *svc_info)
-{
-       if (!svc_info)
-               return;
-
-       g_free(svc_info->serv_path);
-       g_free(svc_info->service_uuid);
-       g_free(svc_info);
-}
-
 static const GDBusInterfaceVTable desc_interface_vtable = {
        __bt_gatt_desc_method_call,
        NULL,
@@ -2163,7 +2201,7 @@ static int __bt_hal_add_service_to_dbus(char *app_path, int slot, btgatt_srvc_id
                        GATT_SERV_INTERFACE, inner_builder);
 
        ret = g_dbus_connection_emit_signal(g_conn, NULL, "/",
-                       "org.freedesktop.Dbus.ObjectManager",
+                       "org.freedesktop.Dbus.ObjectManager", // TODO: need to check Dbus is working or not
                        "InterfacesAdded",
                        g_variant_new("(oa{sa{sv}})",
                                path, builder),
@@ -2289,6 +2327,8 @@ static int __bt_hal_gatt_init(void)
                owner_id = g_bus_own_name_on_connection(g_conn, name,
                                        G_BUS_NAME_OWNER_FLAGS_NONE,
                                        NULL, NULL, NULL, NULL);
+
+               g_free(name);
        }
        INFO("Owner ID [%d]", owner_id);
 
@@ -2335,10 +2375,8 @@ static void _bt_hal_update_gatt_server_path(int slot, char *app_path)
        app->slot = slot;
        gatt_server_apps = g_slist_append(gatt_server_apps, app);
        INFO("GATT Server: Path [%s] Slot [%d]-> Updated", app_path, slot);
-
 }
 
-
 static bt_status_t gatt_server_add_service(int server_if, btgatt_srvc_id_t *srvc_id,
                int num_handles)
 {
@@ -2628,14 +2666,8 @@ static bt_status_t gatt_server_add_descriptor(int slot, int service_handle, bt_u
        char *desc_flags[NUMBER_OF_FLAGS];
        int flag_count = 0;
        int *app_id;
-
        hal_gatt_desc_added *user_data = NULL;
-#if 0
-       if (new_char) {
-               desc_id = 1;
-               new_char = FALSE;
-       }
-#endif
+
        /* Fetch service data for the GATT server */
        serv_info = __bt_gatt_find_gatt_service_info(slot, service_handle);
        if (serv_info == NULL)
@@ -2900,6 +2932,7 @@ static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
        GSList *l1 = NULL;
        int err = BT_STATUS_SUCCESS;
        int ret = BT_STATUS_SUCCESS;
+       char *app_path = NULL;
        INFO("Slot [%d] service handle [%d]", server_if, service_handle);
 
        /* Fetch service data for the GATT server */
@@ -2910,6 +2943,13 @@ static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
                return BT_STATUS_FAIL;
        }
 
+       app_path = __bt_get_server_app_path_from_server(server_if);
+       if (app_path == NULL) {
+               ERR("Could not find service info svc handle [%d] server slot [%d]",
+                               service_handle, server_if);
+               return BT_STATUS_FAIL;
+       }
+
        if (serv_info->is_svc_registered == FALSE) {
                ERR("service Not registered path [%s] handle [%d]",
                        serv_info->serv_path, service_handle);
@@ -2931,6 +2971,7 @@ static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
                                        desc_info->desc_id);
                        if (ret) {
                                __bt_hal_gatt_emit_interface_removed(
+                                               app_path,
                                                desc_info->desc_path,
                                                GATT_DESC_INTERFACE);
                        } else {
@@ -2948,7 +2989,7 @@ static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
                ret = g_dbus_connection_unregister_object(g_conn,
                                char_info->char_id);
                if (ret) {
-                       __bt_hal_gatt_emit_interface_removed(char_info->char_path,
+                       __bt_hal_gatt_emit_interface_removed(app_path, char_info->char_path,
                                        GATT_CHAR_INTERFACE);
                } else {
                        INFO("Err");
@@ -2965,7 +3006,7 @@ static bt_status_t gatt_server_delete_service(int server_if, int service_handle)
 
        ret = g_dbus_connection_unregister_object(g_conn, serv_info->serv_id);
        if (ret) {
-               __bt_hal_gatt_emit_interface_removed(serv_info->serv_path,
+               __bt_hal_gatt_emit_interface_removed(app_path, serv_info->serv_path,
                                GATT_SERV_INTERFACE);
        } else {
                INFO("Failed!!");
@@ -3337,6 +3378,8 @@ static bt_status_t gatt_server_update_att_value(int server_if, int attribute_han
        }
 
        g_free(serv_path);
+       g_strfreev(line_argv);
+
        line_argv = g_strsplit_set(char_path, "/", 0);
        serv_path = g_strdup_printf("/%s/%s/%s", line_argv[1], line_argv[2], line_argv[3]);