/* Copyright 2018 Intel
 *
 * 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.
 */

#include "ipmbbridged.hpp"
#include "ipmbdefines.hpp"

#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/**
 * @brief Ipmb utils for checksum
 */
bool ipmbChecksumValidate(uint8_t* data, uint8_t length)
{
    uint8_t checksum = 0;

    // compute checksum.
    for (uint8_t idx = 0; idx < length; idx++)
    {
        checksum += data[idx];
    }

    // check if checksum is valid.
    if (0 == checksum)
    {
        // checksum valid.
        return true;
    }
    else
    {
        // checksum invalid.
        return false;
    }
}

uint8_t ipmbChecksumCompute(uint8_t* data, uint8_t length)
{
    uint8_t checksum = 0;

    // compute checksum.
    for (uint8_t idx = 0; idx < length; idx++)
    {
        checksum += data[idx];
    }

    checksum = (~checksum) + 1;

    // return computed checksum value.
    return checksum;
}

inline bool ipmbConnectionHeaderChecksumValidate(IPMB_HEADER* ipmbHeader)
{
    return ipmbChecksumValidate(reinterpret_cast<uint8_t*>(ipmbHeader),
                                ipmbConnectionHeaderLength);
}

inline bool ipmbDataChecksumValidate(IPMB_HEADER* ipmbHeader, uint8_t length)
{
    return ipmbChecksumValidate(
        (reinterpret_cast<uint8_t*>(ipmbHeader) + ipmbConnectionHeaderLength),
        (length - ipmbConnectionHeaderLength));
}

bool isFrameValid(IPMB_HEADER* frame, uint8_t length)
{
    bool frameValid = ipmbConnectionHeaderChecksumValidate(frame);
    if (false == frameValid)
    {
        // invalid connection header checksum.
        return false;
    }

    // data checksum validation.
    return ipmbDataChecksumValidate(frame, length);
}
