/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "bootcontrolhal"

#include "BootControl.h"

#include <android-base/file.h>
#include <android-base/unique_fd.h>
#include <bootloader_message/bootloader_message.h>
#include <cutils/properties.h>
#include <libboot_control/libboot_control.h>
#include <log/log.h>
#include <trusty/tipc.h>

#include "DevInfo.h"
#include "GptUtils.h"

namespace android {
namespace hardware {
namespace boot {
namespace V1_2 {
namespace implementation {

using android::bootable::GetMiscVirtualAbMergeStatus;
using android::bootable::InitMiscVirtualAbMessageIfNeeded;
using android::bootable::SetMiscVirtualAbMergeStatus;
using android::hardware::boot::V1_0::BoolResult;
using android::hardware::boot::V1_0::CommandResult;
using android::hardware::boot::V1_1::MergeStatus;

namespace {

// clang-format off

#define BOOT_A_PATH     "/dev/block/by-name/boot_a"
#define BOOT_B_PATH     "/dev/block/by-name/boot_b"
#define DEVINFO_PATH    "/dev/block/by-name/devinfo"

// slot flags
#define AB_ATTR_PRIORITY_SHIFT      52
#define AB_ATTR_PRIORITY_MASK       (3UL << AB_ATTR_PRIORITY_SHIFT)
#define AB_ATTR_ACTIVE_SHIFT        54
#define AB_ATTR_ACTIVE              (1UL << AB_ATTR_ACTIVE_SHIFT)
#define AB_ATTR_RETRY_COUNT_SHIFT   (55)
#define AB_ATTR_RETRY_COUNT_MASK    (7UL << AB_ATTR_RETRY_COUNT_SHIFT)
#define AB_ATTR_SUCCESSFUL          (1UL << 58)
#define AB_ATTR_UNBOOTABLE          (1UL << 59)

#define AB_ATTR_MAX_PRIORITY        3UL
#define AB_ATTR_MAX_RETRY_COUNT     3UL

// clang-format on

static std::string getDevPath(uint32_t slot) {
    char real_path[PATH_MAX];

    const char *path = slot == 0 ? BOOT_A_PATH : BOOT_B_PATH;

    int ret = readlink(path, real_path, sizeof real_path);
    if (ret < 0) {
        ALOGE("readlink failed for boot device %s\n", strerror(errno));
        return std::string();
    }

    std::string dp(real_path);
    // extract /dev/sda.. part
    return dp.substr(0, sizeof "/dev/block/sdX" - 1);
}

static bool isSlotFlagSet(uint32_t slot, uint64_t flag) {
    std::string dev_path = getDevPath(slot);
    if (dev_path.empty()) {
        ALOGI("Could not get device path for slot %d\n", slot);
        return false;
    }

    GptUtils gpt(dev_path);
    if (gpt.Load()) {
        ALOGI("failed to load gpt data\n");
        return false;
    }

    gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a");
    if (e == nullptr) {
        ALOGI("failed to get gpt entry\n");
        return false;
    }

    return !!(e->attr & flag);
}

static bool setSlotFlag(uint32_t slot, uint64_t flag) {
    std::string dev_path = getDevPath(slot);
    if (dev_path.empty()) {
        ALOGI("Could not get device path for slot %d\n", slot);
        return false;
    }

    GptUtils gpt(dev_path);
    if (gpt.Load()) {
        ALOGI("failed to load gpt data\n");
        return false;
    }

    gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a");
    if (e == nullptr) {
        ALOGI("failed to get gpt entry\n");
        return false;
    }

    e->attr |= flag;
    gpt.Sync();

    return true;
}

static bool is_devinfo_valid;
static bool is_devinfo_initialized;
static std::mutex devinfo_lock;
static devinfo_t devinfo;

static bool isDevInfoValid() {
    const std::lock_guard<std::mutex> lock(devinfo_lock);

    if (is_devinfo_initialized) {
        return is_devinfo_valid;
    }

    is_devinfo_initialized = true;

    android::base::unique_fd fd(open(DEVINFO_PATH, O_RDONLY));
    android::base::ReadFully(fd, &devinfo, sizeof devinfo);

    if (devinfo.magic != DEVINFO_MAGIC) {
        return is_devinfo_valid;
    }

    uint32_t version = ((uint32_t)devinfo.ver_major << 16) | devinfo.ver_minor;
    // only version 3.3+ supports A/B data
    if (version >= 0x0003'0003) {
        is_devinfo_valid = true;
    }

    return is_devinfo_valid;
}

static bool DevInfoSync() {
    if (!isDevInfoValid()) {
        return false;
    }

    android::base::unique_fd fd(open(DEVINFO_PATH, O_WRONLY | O_DSYNC));
    return android::base::WriteFully(fd, &devinfo, sizeof devinfo);
}

static void DevInfoInitSlot(devinfo_ab_slot_data_t &slot_data) {
    slot_data.retry_count = AB_ATTR_MAX_RETRY_COUNT;
    slot_data.unbootable = 0;
    slot_data.successful = 0;
    slot_data.active = 1;
    slot_data.fastboot_ok = 0;
}

static int blow_otp_AR(bool secure) {
    static const char *dev_name = "/dev/trusty-ipc-dev0";
    static const char *otp_name = "com.android.trusty.otp_manager.tidl";
    int fd = 1, ret = 0;
    uint32_t cmd = secure? OTP_CMD_write_antirbk_secure_ap : OTP_CMD_write_antirbk_non_secure_ap;
    fd = tipc_connect(dev_name, otp_name);
    if (fd < 0) {
        ALOGI("Failed to connect to OTP_MGR ns TA - is it missing?\n");
        ret = -1;
        return ret;
    }

    struct otp_mgr_req_base req = {
        .command = cmd,
        .resp_payload_size = 0,
    };
    struct iovec iov[] = {
        {
            .iov_base = &req,
            .iov_len = sizeof(req),
        },
    };

    int rc = tipc_send(fd, iov, 1, NULL, 0);
    if (rc != sizeof(req)) {
        ALOGI("Send fail! %x\n", rc);
        return rc;
    }

    struct otp_mgr_rsp_base resp;
    rc = read(fd, &resp, sizeof(resp));
    if (rc < 0) {
        ALOGI("Read fail! %x\n", rc);
        return rc;
    }

    if (rc < sizeof(resp)) {
        ALOGI("Not enough data! %x\n", rc);
        return -EIO;
    }

    if (resp.command != (cmd | OTP_RESP_BIT)) {
        ALOGI("Wrong command! %x\n", resp.command);
        return -EINVAL;
    }

    if (resp.result != 0) {
        fprintf(stderr, "AR writing error! %x\n", resp.result);
        return -EINVAL;
    }

    tipc_close(fd);
    return 0;
}

static bool blowAR() {
    int ret = blow_otp_AR(true);
    if (ret) {
        ALOGI("Blow secure anti-rollback OTP failed");
        return false;
    }

    ret = blow_otp_AR(false);
    if (ret) {
        ALOGI("Blow non-secure anti-rollback OTP failed");
        return false;
    }

    return true;
}
}  // namespace

// Methods from ::android::hardware::boot::V1_0::IBootControl follow.
Return<uint32_t> BootControl::getNumberSlots() {
    uint32_t slots = 0;

    if (access(BOOT_A_PATH, F_OK) == 0)
        slots++;

    if (access(BOOT_B_PATH, F_OK) == 0)
        slots++;

    return slots;
}

Return<uint32_t> BootControl::getCurrentSlot() {
    char suffix[PROPERTY_VALUE_MAX];
    property_get("ro.boot.slot_suffix", suffix, "_a");
    return std::string(suffix) == "_b" ? 1 : 0;
}

Return<void> BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) {
    if (getNumberSlots() == 0) {
        // no slots, just return true otherwise Android keeps trying
        _hidl_cb({true, ""});
        return Void();
    }

    bool ret;
    if (isDevInfoValid()) {
        auto const slot = getCurrentSlot();
        devinfo.ab_data.slots[slot].successful = 1;
        ret = DevInfoSync();
    } else {
        ret = setSlotFlag(getCurrentSlot(), AB_ATTR_SUCCESSFUL);
    }

    if (!ret) {
        _hidl_cb({false, "Failed to set successful flag"});
        return Void();
    }

    if (!blowAR()) {
        ALOGE("Failed to blow anti-rollback counter");
        // Ignore the error, since ABL will re-trigger it on reboot
    }

    _hidl_cb({true, ""});
    return Void();
}

Return<void> BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) {
    if (slot >= 2) {
        _hidl_cb({false, "Invalid slot"});
        return Void();
    }

    if (isDevInfoValid()) {
        auto &active_slot_data = devinfo.ab_data.slots[slot];
        auto &inactive_slot_data = devinfo.ab_data.slots[!slot];

        inactive_slot_data.active = 0;
        DevInfoInitSlot(active_slot_data);

        if (!DevInfoSync()) {
            _hidl_cb({false, "Could not update DevInfo data"});
            return Void();
        }
    } else {
        std::string dev_path = getDevPath(slot);
        if (dev_path.empty()) {
            _hidl_cb({false, "Could not get device path for slot"});
            return Void();
        }

        GptUtils gpt(dev_path);
        if (gpt.Load()) {
            _hidl_cb({false, "failed to load gpt data"});
            return Void();
        }

        gpt_entry *active_entry = gpt.GetPartitionEntry(slot == 0 ? "boot_a" : "boot_b");
        gpt_entry *inactive_entry = gpt.GetPartitionEntry(slot == 0 ? "boot_b" : "boot_a");
        if (active_entry == nullptr || inactive_entry == nullptr) {
            _hidl_cb({false, "failed to get entries for boot partitions"});
            return Void();
        }

        ALOGV("slot active attributes %lx\n", active_entry->attr);
        ALOGV("slot inactive attributes %lx\n", inactive_entry->attr);

        // update attributes for active and inactive
        inactive_entry->attr &= ~AB_ATTR_ACTIVE;
        active_entry->attr = AB_ATTR_ACTIVE | (AB_ATTR_MAX_PRIORITY << AB_ATTR_PRIORITY_SHIFT) |
                             (AB_ATTR_MAX_RETRY_COUNT << AB_ATTR_RETRY_COUNT_SHIFT);
    }

    char boot_dev[PROPERTY_VALUE_MAX];
    property_get("ro.boot.bootdevice", boot_dev, "");
    if (boot_dev[0] == '\0') {
        _hidl_cb({false, "invalid ro.boot.bootdevice prop"});
        return Void();
    }

    std::string boot_lun_path =
            std::string("/sys/devices/platform/") + boot_dev + "/pixel/boot_lun_enabled";
    int fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC);
    if (fd < 0) {
        // Try old path for kernels < 5.4
        // TODO: remove once kernel 4.19 support is deprecated
        std::string boot_lun_path =
                std::string("/sys/devices/platform/") + boot_dev + "/attributes/boot_lun_enabled";
        fd = open(boot_lun_path.c_str(), O_RDWR | O_DSYNC);
        if (fd < 0) {
            _hidl_cb({false, "failed to open ufs attr boot_lun_enabled"});
            return Void();
        }
    }

    //
    // bBootLunEn
    // 0x1  => Boot LU A = enabled, Boot LU B = disable
    // 0x2  => Boot LU A = disable, Boot LU B = enabled
    //
    int ret = android::base::WriteStringToFd(slot == 0 ? "1" : "2", fd);
    close(fd);
    if (ret < 0) {
        _hidl_cb({false, "faied to write boot_lun_enabled attribute"});
        return Void();
    }

    _hidl_cb({true, ""});
    return Void();
}

Return<void> BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) {
    if (slot >= 2) {
        _hidl_cb({false, "Invalid slot"});
        return Void();
    }

    if (isDevInfoValid()) {
        auto &slot_data = devinfo.ab_data.slots[slot];
        slot_data.unbootable = 1;
        if (!DevInfoSync()) {
            _hidl_cb({false, "Could not update DevInfo data"});
            return Void();
        }
    } else {
        std::string dev_path = getDevPath(slot);
        if (dev_path.empty()) {
            _hidl_cb({false, "Could not get device path for slot"});
            return Void();
        }

        GptUtils gpt(dev_path);
        gpt.Load();

        gpt_entry *e = gpt.GetPartitionEntry(slot ? "boot_b" : "boot_a");
        e->attr |= AB_ATTR_UNBOOTABLE;

        gpt.Sync();
    }

    _hidl_cb({true, ""});
    return Void();
}

Return<::android::hardware::boot::V1_0::BoolResult> BootControl::isSlotBootable(uint32_t slot) {
    if (getNumberSlots() == 0)
        return BoolResult::FALSE;
    if (slot >= getNumberSlots())
        return BoolResult::INVALID_SLOT;

    bool unbootable;
    if (isDevInfoValid()) {
        auto &slot_data = devinfo.ab_data.slots[slot];
        unbootable = !!slot_data.unbootable;
    } else {
        unbootable = isSlotFlagSet(slot, AB_ATTR_UNBOOTABLE);
    }

    return unbootable ? BoolResult::FALSE : BoolResult::TRUE;
}

Return<::android::hardware::boot::V1_0::BoolResult> BootControl::isSlotMarkedSuccessful(
        uint32_t slot) {
    if (getNumberSlots() == 0) {
        // just return true so that we don't we another call trying to mark it as successful
        // when there is no slots
        return BoolResult::TRUE;
    }
    if (slot >= getNumberSlots())
        return BoolResult::INVALID_SLOT;

    bool successful;
    if (isDevInfoValid()) {
        auto &slot_data = devinfo.ab_data.slots[slot];
        successful = !!slot_data.successful;
    } else {
        successful = isSlotFlagSet(slot, AB_ATTR_SUCCESSFUL);
    }

    return successful ? BoolResult::TRUE : BoolResult::FALSE;
}

Return<void> BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) {
    _hidl_cb(slot == 0 ? "_a" : slot == 1 ? "_b" : "");
    return Void();
}

// Methods from ::android::hardware::boot::V1_1::IBootControl follow.
bool BootControl::Init() {
    return InitMiscVirtualAbMessageIfNeeded();
}

Return<bool> BootControl::setSnapshotMergeStatus(
        ::android::hardware::boot::V1_1::MergeStatus status) {
    return SetMiscVirtualAbMergeStatus(getCurrentSlot(), status);
}

Return<::android::hardware::boot::V1_1::MergeStatus> BootControl::getSnapshotMergeStatus() {
    MergeStatus status;
    if (!GetMiscVirtualAbMergeStatus(getCurrentSlot(), &status)) {
        return MergeStatus::UNKNOWN;
    }
    return status;
}

// Methods from ::android::hardware::boot::V1_2::IBootControl follow.
Return<uint32_t> BootControl::getActiveBootSlot() {
    if (getNumberSlots() == 0)
        return 0;

    if (isDevInfoValid())
        return devinfo.ab_data.slots[1].active ? 1 : 0;
    return isSlotFlagSet(1, AB_ATTR_ACTIVE) ? 1 : 0;
}

// Methods from ::android::hidl::base::V1_0::IBase follow.

IBootControl *HIDL_FETCH_IBootControl(const char * /* name */) {
    auto module = new BootControl();

    module->Init();

    return module;
}

}  // namespace implementation
}  // namespace V1_2
}  // namespace boot
}  // namespace hardware
}  // namespace android
