[OTP] Fix PTS fail cases
[platform/core/connectivity/bluetooth-frwk.git] / bt-otp / bt-otpserver.c
index c68068d..8cc4493 100644 (file)
@@ -28,6 +28,7 @@
 #include <errno.h>
 #include <gio/gunixfdlist.h>
 #include <dlfcn.h>
+#include <arpa/inet.h>
 
 #include "bt-otpserver.h"
 #include "bluetooth-api.h"
@@ -397,8 +398,10 @@ int _bt_otp_prepare_ots(void)
        }
 
        /* Characteristic Object Properties */
-       props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ;
-       perms = BLUETOOTH_GATT_PERMISSION_READ;
+       props = BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_READ |
+                       BLUETOOTH_GATT_CHARACTERISTIC_PROPERTY_WRITE;
+       perms = BLUETOOTH_GATT_PERMISSION_READ |
+                       BLUETOOTH_GATT_PERMISSION_WRITE;
        char_uuid = _otp_convert_uuid_to_uuid128(OTP_OBJECT_PROP_UUID);
        ret = add_new_characteristic(char_uuid, perms, props,
                                        &otp_object_prop_obj_path);
@@ -1151,6 +1154,11 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
                g_free(uuid);
                break;
        case OACP_DELETE:
+               if (opcode == OACP_DELETE &&
+                               ~(selected_object->props & OBJECT_DELETE)) {
+                       ret = OACP_PROCEDURE_NOT_SUPPORTED;
+                       goto fail;
+               }
                snprintf(absolute_file_path, sizeof(absolute_file_path),
                                                "%s%s", directory, selected_object->name);
 
@@ -1169,6 +1177,11 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
                ret = OACP_OPCODE_NOT_SUPPORTED;
                break;
        case OACP_EXECUTE:
+               if (opcode == OACP_EXECUTE &&
+                               ~(selected_object->props & OBJECT_EXECUTE)) {
+                       ret = OACP_PROCEDURE_NOT_SUPPORTED;
+                       goto fail;
+               }
                snprintf(absolute_file_path, sizeof(absolute_file_path),
                                        "file://%s%s", directory, selected_object->name);
 
@@ -1185,6 +1198,18 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
                break;
        case OACP_READ:
        case OACP_WRITE:
+               if (opcode == OACP_WRITE &&
+                               ~(selected_object->props & OBJECT_WRITE)) {
+                       ret = OACP_PROCEDURE_NOT_SUPPORTED;
+                       goto fail;
+               }
+
+               if (opcode == OACP_READ &&
+                               ~(selected_object->props & OBJECT_READ)) {
+                       ret = OACP_PROCEDURE_NOT_SUPPORTED;
+                       goto fail;
+               }
+
                object_offset = (uint32_t)(value[4] & 0xFF) << 24 |
                                (uint32_t)(value[3] & 0xFF) << 16 |
                                (uint32_t)(value[2] & 0xFF) << 8  |
@@ -1219,7 +1244,7 @@ int _bt_otp_oacp_write_cb(char *value, int len, int offset,
 
                err = _bt_otp_open_otc_and_listen(remote_addr, "ListenOtc");
                if (err != BLUETOOTH_ERROR_NONE) {
-                       ret = OACP_OPERATION_FAILED;
+                       ret = OACP_CHANNEL_UNAVAILABLE;
                        _bt_otp_free_oacp_op();
                        goto fail;
                }
@@ -1239,15 +1264,42 @@ fail:
        return BLUETOOTH_ERROR_NONE;
 }
 
-void convert_to_hex(struct object_metadata *object, char *type, char *value)
+void convert_to_hex(struct object_metadata *object, char *metadata, char *value)
 {
        struct tm fc_tm;
 
-       BT_DBG("type : %s", type);
+       BT_DBG("Metadata : %s", metadata);
+
+       memset(value, 0, 16);
+
+       if (!g_strcmp0(metadata, "type")) {
+               /* Convert UUID string to 128 bit UUID */
+               uint32_t data0, data4;
+               uint16_t data1, data2, data3, data5;
 
-       memset(value, 0, 8);
+               if (!object->type || sscanf(object->type,
+                               "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+                               &data0, &data1, &data2,
+                               &data3, &data4, &data5) != 6) {
+                       BT_ERR("Object Type UUID not updated");
+                       return;
+               }
+
+               data0 = htonl(data0);
+               data1 = htons(data1);
+               data2 = htons(data2);
+               data3 = htons(data3);
+               data4 = htonl(data4);
+               data5 = htons(data5);
 
-       if (!g_strcmp0(type, "size")) {
+               memcpy(value, &data0, 4);
+               memcpy(value+4, &data1, 2);
+               memcpy(value+6, &data2, 2);
+               memcpy(value+8, &data3, 2);
+               memcpy(value+10, &data4, 4);
+               memcpy(value+14, &data5, 2);
+
+       } else if (!g_strcmp0(metadata, "size")) {
 
                value[3] = (object->curr_size >> 24) & 0xFF;
                value[2] = (object->curr_size >> 16) & 0xFF;
@@ -1259,7 +1311,7 @@ void convert_to_hex(struct object_metadata *object, char *type, char *value)
                value[5] = (object->alloc_size >> 8) & 0xFF;
                value[4] = object->alloc_size & 0xFF;
 
-       } else if (!g_strcmp0(type, "date")) {
+       } else if (!g_strcmp0(metadata, "date")) {
 
                localtime_r(&(object->first_created), &fc_tm);
 
@@ -1271,7 +1323,7 @@ void convert_to_hex(struct object_metadata *object, char *type, char *value)
                value[5] = fc_tm.tm_min & 0xFF;
                value[6] = fc_tm.tm_sec & 0xFF;
 
-       } else if (!g_strcmp0(type, "id")) {
+       } else if (!g_strcmp0(metadata, "id")) {
 
                value[5] = (object->id >> 48) & 0xFF;
                value[4] = (object->id >> 32) & 0xFF;
@@ -1280,7 +1332,7 @@ void convert_to_hex(struct object_metadata *object, char *type, char *value)
                value[1] = (object->id >> 8) & 0xFF;
                value[0] = object->id & 0xFF;
 
-       } else if (!g_strcmp0(type, "props")) {
+       } else if (!g_strcmp0(metadata, "props")) {
                value[3] = (object->props >> 24) & 0xFF;
                value[2] = (object->props >> 16) & 0xFF;
                value[1] = (object->props >> 8) & 0xFF;
@@ -1290,13 +1342,14 @@ void convert_to_hex(struct object_metadata *object, char *type, char *value)
 
 void update_obj_metadata_charc_value(struct object_metadata *object)
 {
-       /* Value can be of maximum eight bytes */
-       char value[8];
+       /* Value can be of maximum 16 bytes */
+       char value[16];
 
        _bt_otp_set_char_value(otp_object_name_obj_path, object->name,
                                                        strlen(object->name));
-       _bt_otp_set_char_value(otp_object_type_obj_path, object->type,
-                                                       strlen(object->type));
+
+       convert_to_hex(object, "type", value);
+       _bt_otp_set_char_value(otp_object_type_obj_path, value, 16);
 
        convert_to_hex(object, "size", value);
        _bt_otp_set_char_value(otp_object_size_obj_path, value, 8);
@@ -1622,6 +1675,7 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
                                guint16 offset = 0;
                                char *value = NULL;
                                struct indicate_info info;
+
                                g_variant_get(var, "(&s&s&syq@ay)",
                                                &char_path, &svc_handle,
                                                &addr, &req_id, &offset, &val);
@@ -1635,9 +1689,15 @@ void _bt_otp_gatt_char_property_changed_event(GVariant *msg,
 
                                if (len != 0) {
                                        if (!g_strcmp0(char_path, otp_oacp_obj_path)) {
-                                               result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
+                                               if (!OACP_indicate)
+                                                       result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED;
+                                               else
+                                                       result = _bt_otp_oacp_write_cb(value, len, offset, addr, &info);
                                        } else if (!g_strcmp0(char_path, otp_olcp_obj_path)) {
-                                               result = _bt_otp_olcp_write_cb(value, len, offset, &info);
+                                               if (!OLCP_indicate)
+                                                       result = BLUETOOTH_ERROR_CCC_IMPROPERLY_CONFIGURED;
+                                               else
+                                                       result = _bt_otp_olcp_write_cb(value, len, offset, &info);
                                        } else if (!g_strcmp0(char_path, otp_object_name_obj_path)) {
                                                if (oacp_create) {
                                                        /* OACP_CREATE is ongoing */