Add container request check logic
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / services / bt-request-handler.c
index 261cd37..7c54dd0 100644 (file)
@@ -51,6 +51,7 @@
 #include "bt-service-hidhost.h"
 #include "bt-service-rfcomm.h"
 #include "bt-service-hdp.h"
+#include "bt-service-tds.h"
 
 /*Obex*/
 #include "bt-service-obex-server.h"
 /* For maintaining Application Sync API call requests */
 static GSList *invocation_list = NULL;
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+struct nspid_t {
+       char *unique_name;
+       gboolean is_container;
+};
+static GSList *nspid_list = NULL;
+#endif
+
 static GDBusConnection *bt_service_conn;
 static guint owner_id = 0;
 static guint owner_sig_id = 0;
@@ -1620,9 +1629,13 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AUDIO_A2DP, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AV_CONNECT, &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AUDIO_A2DP, &address);
 
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("AV Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1640,9 +1653,13 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AUDIO_ALL, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AUDIO_CONNECT, &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AUDIO_ALL, &address);
 
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("Audio All Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1700,9 +1717,13 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AUDIO_HSP, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AG_CONNECT, &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AUDIO_HSP, &address);
 
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("AG Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1742,8 +1763,14 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AUDIO_A2DP_SOURCE, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AV_SOURCE_CONNECT,
+                               &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AUDIO_A2DP_SOURCE, &address);
+
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("A2DP Source Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1782,8 +1809,14 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_hf_connect(&address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_HF_CONNECT,
+                               &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_hf_connect(&address);
+
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("HF Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1822,8 +1855,14 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AVRCP_TARGET, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AVRCP_TARGET_CONNECT,
+                               &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AVRCP_TARGET, &address);
+
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("AVRCP Target Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -1862,8 +1901,14 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param1,
                                &address, sizeof(bluetooth_device_address_t));
 
-               result = _bt_audio_connect(BT_AVRCP, &address);
+               result = _bt_audio_is_profile_connection_in_progress(BT_AVRCP_CONTROL_CONNECT,
+                               &address);
+
+               if (result == BLUETOOTH_ERROR_NONE)
+                       result = _bt_audio_connect(BT_AVRCP, &address);
+
                if (result != BLUETOOTH_ERROR_NONE) {
+                       BT_ERR("AVRCP Control Connect Request has failed to execute");
                        char addr[BT_ADDRESS_STRING_SIZE];
                        _bt_convert_addr_type_to_string(addr, address.addr);
                        g_array_append_vals(*out_param1, addr, BT_ADDRESS_STRING_SIZE);
@@ -2331,7 +2376,7 @@ int __bt_bluez_request(int function_name,
                __bt_service_get_parameters(in_param4, &use_reserved_slot,
                                sizeof(gboolean));
 
-               BT_DBG("bluetooth_advertising_params_t [%f %f %d %d %d]",
+               BT_DBG("bluetooth_advertising_params_t [%d %d %d %d %d]",
                                adv_params.interval_min, adv_params.interval_max,
                                adv_params.filter_policy, adv_params.type, adv_params.tx_power_level);
                result = _bt_set_custom_advertising(app, *adv_handle,
@@ -3355,6 +3400,107 @@ normal:
                break;
        }
 
+       case BT_TDS_PROVIDER_REGISTER: {
+               char *sender = NULL;
+
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               result = _bt_tds_provider_register(sender);
+
+               break;
+       }
+
+       case BT_TDS_PROVIDER_UNREGISTER: {
+               char *sender = NULL;
+
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               result = _bt_tds_provider_unregister(sender);
+
+               break;
+       }
+
+       case BT_TDS_PROVIDER_SET_MANUF_DATA: {
+               char *sender = NULL;
+               unsigned int length = 0;
+               bluetooth_advertising_data_t manuf_data;
+
+               __bt_service_get_parameters(in_param1,
+                               &length, sizeof(unsigned int));
+               __bt_service_get_parameters(in_param2,
+                               &manuf_data, sizeof(bluetooth_advertising_data_t));
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+               result = _bt_tds_provider_set_manuf_data(sender, manuf_data.data, length);
+               break;
+       }
+
+       case BT_TDS_PROVIDER_CREATE: {
+               char *sender = NULL;
+               unsigned int tds_handle = 0;
+               int transport;
+
+               __bt_service_get_parameters(in_param1,
+                               &tds_handle, sizeof(unsigned int));
+               __bt_service_get_parameters(in_param2,
+                               &transport, sizeof(int));
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               result = _bt_tds_provider_transport_create(sender, transport, tds_handle);
+
+               break;
+       }
+
+       case BT_TDS_PROVIDER_DESTROY: {
+               char *sender = NULL;
+               unsigned int tds_handle = 0;
+
+               __bt_service_get_parameters(in_param1,
+                               &tds_handle, sizeof(unsigned int));
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               result = _bt_tds_provider_transport_remove(sender, tds_handle);
+
+               break;
+       }
+
+       case BT_TDS_PROVIDER_SET_TRANSPORT_DATA: {
+               char *sender = NULL;
+               unsigned int tds_handle = 0;
+               int transport_state = 0;
+               bluetooth_tds_data_t tds_data;
+
+               __bt_service_get_parameters(in_param1,
+                               &tds_handle, sizeof(unsigned int));
+               __bt_service_get_parameters(in_param2,
+                               &transport_state, sizeof(int));
+               __bt_service_get_parameters(in_param3,
+                               &tds_data, sizeof(bluetooth_tds_data_t));
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+               result = _bt_tds_provider_set_transport_data(sender, tds_handle,
+                               transport_state, tds_data.data, tds_data.length);
+               break;
+       }
+
+       case BT_TDS_SEND_ACTIVATION_RESPONSE: {
+               bluetooth_device_address_t address = { {0} };
+               bluetooth_tds_data_t tds_data;
+               char *sender = NULL;
+               unsigned int tds_handle = 0;
+               int response;
+
+               __bt_service_get_parameters(in_param1,
+                               &tds_handle, sizeof(unsigned int));
+               __bt_service_get_parameters(in_param2,
+                               &response, sizeof(int));
+               __bt_service_get_parameters(in_param3, &address,
+                       sizeof(bluetooth_device_address_t));
+               __bt_service_get_parameters(in_param4,
+                               &tds_data, sizeof(bluetooth_tds_data_t));
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+
+               result = _bt_tds_provider_send_activation_response(sender, tds_handle,
+                               &address, response, tds_data.data, tds_data.length);
+               break;
+       }
+
        case BT_MESH_INIT:
                sender = (char*)g_dbus_method_invocation_get_sender(context);
                BT_INFO("Mesh: Init by [%s]", sender);
@@ -3505,6 +3651,64 @@ normal:
                                sender, &network);
                break;
        }
+       case BT_MESH_NETWORK_JOIN: {
+               bluetooth_mesh_node_t node;
+               GSList *model_list = NULL;
+               int total_models = 0;
+               GArray *param2;
+               int i = 0;
+
+               memset(&node, 0x00, sizeof(bluetooth_mesh_node_t));
+               sender = (char*)g_dbus_method_invocation_get_sender(context);
+
+               __bt_service_get_parameters(in_param1,
+                               &node, sizeof(bluetooth_mesh_node_t));
+
+               param2 = g_array_new(TRUE, TRUE, sizeof(gchar));
+               __bt_fill_garray_from_variant(in_param2, param2);
+
+               total_models = (param2->len) / sizeof(bluetooth_mesh_model_t);
+               for (i = 0; i < total_models; i++) {
+                       bluetooth_mesh_model_t *info = NULL;
+                       bluetooth_mesh_model_t *mod = NULL;
+                       info = &g_array_index(param2,
+                               bluetooth_mesh_model_t, i);
+                       mod = g_memdup(info, sizeof(bluetooth_mesh_model_t));
+
+                       if (mod)
+                               model_list = g_slist_append(model_list,
+                                       (gpointer)mod);
+               }
+
+               BT_INFO("MESH: Network Join bt-service");
+               //result = BLUETOOTH_ERROR_NONE;
+               result = _bt_mesh_network_join(requester_unique_creds,
+                               sender, &node, model_list);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       g_array_append_vals(*out_param1, &node, sizeof(bluetooth_mesh_node_t));
+                       BT_ERR("Mesh: Mesh Join Network schedule failed");
+                       g_slist_free_full(model_list, g_free);
+               }
+
+               BT_INFO("return of _bt_mesh_network_join : [%d]", result);
+               break;
+       }
+       case BT_MESH_CANCEL_JOIN: {
+               bluetooth_mesh_node_info_t node;
+               memset(&node, 0x00, sizeof(bluetooth_mesh_node_info_t));
+
+               __bt_service_get_parameters(in_param1,
+                               &node, sizeof(bluetooth_mesh_node_info_t));
+
+               BT_INFO("Mesh: Cancel Join request");
+               result = _bt_mesh_cancel_join(requester_unique_creds,
+                               sender, &node);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       g_array_append_vals(*out_param1,
+                                       &node, sizeof(bluetooth_mesh_node_t));
+               }
+               break;
+       }
        case BT_MESH_NETWORK_SCAN: {
                bluetooth_mesh_network_t network;
                bluetooth_mesh_scan_param_t param;
@@ -3966,6 +4170,18 @@ normal:
                }
                break;
        }
+       case BT_MESH_MODEL_RESPONSE_MSG: {
+               bluetooth_mesh_model_msg_t req;
+               memset(&req, 0x00, sizeof(bluetooth_mesh_model_msg_t));
+               __bt_service_get_parameters(in_param1,
+                               &req, sizeof(bluetooth_mesh_model_msg_t));
+
+               result = _bt_mesh_model_send_response(
+                               requester_unique_creds, sender, &req);
+               if (result != BLUETOOTH_ERROR_NONE)
+                       g_array_append_vals(*out_param1, &req, sizeof(bluetooth_mesh_model_msg_t));
+               break;
+       }
        case BT_MESH_NODE_GET_NETKEYS: {
                bluetooth_mesh_node_discover_t node;
                memset(&node, 0x00, sizeof(bluetooth_mesh_node_discover_t));
@@ -4797,6 +5013,81 @@ static int __bt_service_get_requester_app_id(const char *unique_name, char *app_
        return BLUETOOTH_ERROR_NONE;
 }
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+static void __bt_service_free_nspid(struct nspid_t *nspid)
+{
+       g_free(nspid->unique_name);
+       g_free(nspid);
+}
+
+static void __bt_service_cleanup_nspid_list(const char *unique_name)
+{
+       GSList *l;
+       struct nspid_t *nspid;
+
+       for (l = nspid_list; l; l = g_slist_next(l)) {
+               nspid = l->data;
+               if (!nspid)
+                       continue;
+               if (!g_strcmp0(nspid->unique_name, unique_name)) {
+                       nspid_list = g_slist_remove(nspid_list, nspid);
+                       __bt_service_free_nspid(nspid);
+                       return;
+               }
+       }
+}
+
+static gboolean __bt_service_is_container_request(const char *unique_name)
+{
+       int ret;
+       pid_t pid;
+       char path[1024], buf[1024];
+       FILE *fp;
+       gboolean is_container = FALSE;
+       GSList *l;
+       struct nspid_t *nspid;
+
+       for (l = nspid_list; l; l = g_slist_next(l)) {
+               nspid = l->data;
+               if (!nspid)
+                       continue;
+               if (!g_strcmp0(nspid->unique_name, unique_name))
+                       return nspid->is_container;
+       }
+
+       ret = __bt_service_get_sender_pid(unique_name, &pid);
+       if (ret != BLUETOOTH_ERROR_NONE)
+               return FALSE;
+
+       sprintf(path, "/proc/%d/status", pid);
+       fp = fopen(path, "r");
+       if (fp == NULL) {
+               BT_ERR("fopen() failed. %d(%s)", errno, strerror(errno));
+               return FALSE;
+       }
+
+       while (fgets(buf, sizeof(buf), fp)) {
+               if (strstr(buf, "NSpid:")) {
+                       char *p = strchr(buf + 7, '\t'); /* find 2nd '\t' */
+                       if (p) {
+                               BT_DBG("caller is container process");
+                               is_container = TRUE;
+                               goto out;
+                       }
+                       break;
+               }
+       }
+
+out:
+       nspid = g_malloc0(sizeof(struct nspid_t));
+       nspid->unique_name = g_strdup(unique_name);
+       nspid->is_container = is_container;
+       nspid_list = g_slist_append(nspid_list, nspid);
+       fclose(fp);
+       return is_container;
+}
+#endif
+
 gboolean __bt_service_check_privilege(int function_name,
                                        int service_type,
                                        const char *unique_name)
@@ -4813,6 +5104,14 @@ gboolean __bt_service_check_privilege(int function_name,
        retv_if(unique_name == NULL, FALSE);
        retv_if(bt_service_conn == NULL, FALSE);
 
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       /* Privilege will be checked in container if the request is from container */
+       if (__bt_service_is_container_request(unique_name)) {
+               BT_DBG("This request is from container, temporarily allow");
+               return TRUE;
+       }
+#endif
+
        ret_val = cynara_creds_get_default_client_method(&client_creds_method);
        if (ret_val != CYNARA_API_SUCCESS) {
                cynara_strerror(ret_val, err_msg, sizeof(err_msg));
@@ -4860,6 +5159,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_STOP_LE_DISCOVERY:
        case BT_SET_SCAN_PARAMETERS:
        case BT_SET_SCAN_TYPE:
+       case BT_UPDATE_LE_CONNECTION_MODE:
 
        case BT_BOND_DEVICE:
        case BT_CANCEL_BONDING:
@@ -5080,8 +5380,6 @@ gboolean __bt_service_check_privilege(int function_name,
 
        case BT_HID_ENABLE_BARCODE_FEATURE:
 
-       case BT_AVRCP_CONTROL_GET_PROPERTY:
-       case BT_AVRCP_GET_TRACK_INFO:
        case BT_AVRCP_TRANSPORT_SET_PROPERTY:
        case BT_AVRCP_HANDLE_CONTROL_TO_DEST:
 
@@ -5090,7 +5388,6 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_SET_LE_PRIVACY:
        case BT_SET_LE_STATIC_RANDOM_ADDRESS:
        case BT_LE_CONN_UPDATE:
-       case BT_UPDATE_LE_CONNECTION_MODE:
        case BT_GET_DEVICE_IDA:
        case BT_LE_READ_MAXIMUM_DATA_LENGTH:
        case BT_LE_WRITE_HOST_SUGGESTED_DATA_LENGTH:
@@ -5151,6 +5448,8 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_MESH_NETWORK_DESTROY:
        case BT_MESH_NETWORK_LOAD:
        case BT_MESH_NETWORK_UNLOAD:
+       case BT_MESH_NETWORK_JOIN:
+       case BT_MESH_CANCEL_JOIN:
        case BT_MESH_NETWORK_SCAN:
        case BT_MESH_NETWORK_CANCEL_SCAN:
        case BT_MESH_NETWORK_SET_CAPABILITIES:
@@ -5177,6 +5476,7 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_MESH_MODEL_CONFIGURE_APPKEY:
        case BT_MESH_MODEL_GET_APPKEY_LIST:
        case BT_MESH_MODEL_EXECUTE_MSG:
+       case BT_MESH_MODEL_RESPONSE_MSG:
        case BT_MESH_NETWORK_CREATE_GROUP:
        case BT_MESH_NETWORK_REMOVE_GROUP:
        case BT_MESH_MODEL_CONFIG_GROUP_SUB:
@@ -5235,6 +5535,8 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_OBEX_SERVER_DEALLOCATE:
        case BT_OBEX_SERVER_IS_ACTIVATED:
        case BT_OPP_GET_TRANSFER_PROGRESS:
+       case BT_AVRCP_CONTROL_GET_PROPERTY:
+       case BT_AVRCP_GET_TRACK_INFO:
                /* Non-privilege control */
                break;
        default:
@@ -5345,6 +5647,14 @@ static void __name_owner_changed(GDBusConnection *connection,
 
        /* Mesh App Termination */
        _bt_check_mesh_app_termination(name);
+
+       /* Stop the Transport Discovery service */
+       _bt_tds_stop_by_terminated_process(name);
+
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       /* Cleanup the NSpid list */
+       __bt_service_cleanup_nspid_list(name);
+#endif
 }
 
 static void __bt_service_bus_acquired_handler(GDBusConnection *connection,
@@ -5454,6 +5764,13 @@ void _bt_service_unregister(void)
 
                __bt_service_register_object(bt_service_conn, NULL, FALSE);
        }
+
+#ifdef TIZEN_FEATURE_BT_CONTAINER
+       if (nspid_list) {
+               g_slist_free_full(nspid_list, (GDestroyNotify)__bt_service_free_nspid);
+               nspid_list = NULL;
+       }
+#endif
 }
 
 int _bt_service_cynara_init(void)