[OTP] Handle Object Execute request
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
index 2e88aa6..5361c71 100644 (file)
@@ -27,6 +27,7 @@
 #include <inttypes.h>
 #include <errno.h>
 #include <gio/gunixfdlist.h>
+#include <dlfcn.h>
 
 #include "bt-otpserver.h"
 #include "bluetooth-api.h"
@@ -297,7 +298,7 @@ int _bt_otp_prepare_ots(void)
        char *desc_uuid;
        bt_gatt_characteristic_property_t props;
        bt_gatt_permission_t perms;
-       char supp_feat[OTP_FEATURE_LENGTH] = { 0x8C, 0x00, 0x00, 0x00,
+       char supp_feat[OTP_FEATURE_LENGTH] = { 0x9C, 0x00, 0x00, 0x00,
                                                0x80, 0x00, 0x00, 0x00 };
 
        ret = bluetooth_gatt_init();
@@ -685,7 +686,7 @@ static void _bt_otp_method(GDBusConnection *connection,
                GDir *dir = NULL;
                GError *error = NULL;
                const gchar *filename = NULL;
-               char absolute_path[ABSOLUTE_PATH_MAX_LENGTH];
+               char absolute_path[BT_FILE_PATH_MAX_LEN];
                GSList *list = NULL, *l = NULL;
                struct stat st;
                struct object_metadata *object = NULL;
@@ -738,7 +739,7 @@ static void _bt_otp_method(GDBusConnection *connection,
                        object->curr_size = (uint32_t) st.st_size;
                        object->alloc_size = (uint32_t) st.st_size;
                        object->id = object_id;
-                       object->props = OBJECT_READ;
+                       object->props = OBJECT_READ | OBJECT_WRITE | OBJECT_EXECUTE;
 
                        otp_object_list = g_slist_append(otp_object_list,
                                                                object);
@@ -1072,6 +1073,43 @@ static void _bt_otp_free_oacp_op()
        }
 }
 
+int _bt_otp_send_launch_request(char *absolute_path)
+{
+       void *handle;
+       char *error;
+       int ret;
+
+       /* check ARCH 64 or 32*/
+       if (!access(FILEPATH_ARCH_64, 0)) {
+               BT_INFO("plugin loading for ARCH 64");
+               handle = dlopen(HEADED_PLUGIN_FILEPATH64, RTLD_NOW);
+       } else {
+               BT_INFO("plugin loading for ARCH 32");
+               handle = dlopen(HEADED_PLUGIN_FILEPATH, RTLD_NOW);
+       }
+
+       if (!handle) {
+               BT_ERR("Can not load plugin %s", dlerror());
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       dlerror();      /* Clear any existing error */
+
+       int (*fun)(char *) = (int (*)(char *))dlsym(handle,
+                                       "bt_app_control_send_launch_request");
+
+       if ((error = dlerror()) != NULL)  {
+               BT_ERR("Can not load symbol : %s", dlerror());
+               dlclose(handle);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       ret = fun(absolute_path);
+       dlclose(handle);
+
+       return ret;
+}
+
 int _bt_otp_oacp_write_cb(char *value, int len, int offset,
                                                        char *remote_addr, struct indicate_info *info)
 {
@@ -1081,6 +1119,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
        uint32_t object_offset, length, object_size;
        uint8_t mode = 0;
        char *uuid;
+       char absolute_path[BT_FILE_PATH_MAX_LEN] = {0, };
 
        BT_INFO("OACP Opcode 0x%d", opcode);
 
@@ -1122,7 +1161,22 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
                ret = OACP_OPCODE_NOT_SUPPORTED;
                break;
        case OACP_EXECUTE:
-               ret = OACP_OPCODE_NOT_SUPPORTED;
+               if (!selected_object) {
+                       BT_DBG("Object not selected");
+                       ret = OACP_OPERATION_FAILED;
+                       goto fail;
+               }
+
+               snprintf(absolute_path, sizeof(absolute_path), "file://%s%s", directory,
+                                                       selected_object->name);
+
+               BT_DBG("absolute_path = [%s]", absolute_path);
+
+               app_err = _bt_otp_send_launch_request(absolute_path);
+               if (app_err == BLUETOOTH_ERROR_NONE)
+                       ret = OACP_SUCCESS;
+               else
+                       ret = OACP_OPERATION_FAILED;
                break;
        case OACP_READ:
        case OACP_WRITE: