/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2014-2017 Nest Labs, Inc.
 *
 *    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.
 */

/**
 *    @file
 *      This file defines types and an object for the chip over
 *      Bluetooth Low Energy (CHIPoBLE) byte-stream, connection-oriented
 *      adaptation of chip for point-to-point Bluetooth Low Energy
 *      (BLE) links.
 *
 */

#ifndef CHIPOBLE_H_
#define CHIPOBLE_H_

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif

#include <stdint.h>
#include <string.h>

#include <ble/BleConfig.h>

#include <ble/BleError.h>
#include <system/SystemPacketBuffer.h>
#include <support/FlagUtils.hpp>

namespace chip {
namespace Ble {

using ::chip::System::PacketBuffer;

typedef uint8_t SequenceNumber_t; // If type changed from uint8_t, adjust assumptions in CHIPoBle::IsValidAck and
                                  // BLEEndPoint::AdjustReceiveWindow.

#if CHIP_ENABLE_CHIPOBLE_TEST
class BLEEndPoint;
#endif

// Public data members:
typedef enum
{
    kType_Data    = 0, // Default 0 for data
    kType_Control = 1,
} PacketType_t; // CHIPoBle packet types

class CHIPoBle
{
#if CHIP_ENABLE_CHIPOBLE_TEST
    friend class BLEEndPoint;
#endif

public:
    // Public data members:
    typedef enum
    {
        kState_Idle       = 0,
        kState_InProgress = 1,
        kState_Complete   = 2,
        kState_Error      = 3
    } State_t; // [READ-ONLY] Current state

    enum
    {
        kHeaderFlag_StartMessage    = 0x01,
        kHeaderFlag_ContinueMessage = 0x02,
        kHeaderFlag_EndMessage      = 0x04,
        kHeaderFlag_FragmentAck     = 0x08,
#if CHIP_ENABLE_CHIPOBLE_TEST
        kHeaderFlag_CommandMessage = 0x10,
#endif
    }; // Masks for BTP fragment header flag bits.

    static const uint16_t sDefaultFragmentSize;
    static const uint16_t sMaxFragmentSize;

public:
    // Public functions:
    CHIPoBle(void){};
    ~CHIPoBle(void){};

    BLE_ERROR Init(void * an_app_state, bool expect_first_ack);

    inline void SetTxFragmentSize(uint8_t size) { mTxFragmentSize = size; };
    inline void SetRxFragmentSize(uint8_t size) { mRxFragmentSize = size; };

    uint16_t GetRxFragmentSize(void) { return mRxFragmentSize; };
    uint16_t GetTxFragmentSize(void) { return mTxFragmentSize; };

    SequenceNumber_t GetAndIncrementNextTxSeqNum(void);
    SequenceNumber_t GetAndRecordRxAckSeqNum(void);

    inline SequenceNumber_t GetLastReceivedSequenceNumber(void) { return mRxNewestUnackedSeqNum; };
    inline SequenceNumber_t GetNewestUnackedSentSequenceNumber(void) { return mTxNewestUnackedSeqNum; };

    inline bool ExpectingAck(void) const { return mExpectingAck; };

    inline State_t RxState(void) { return mRxState; }
    inline State_t TxState(void) { return mTxState; }
#if CHIP_ENABLE_CHIPOBLE_TEST
    inline PacketType_t SetTxPacketType(PacketType_t type) { return (mTxPacketType = type); };
    inline PacketType_t SetRxPacketType(PacketType_t type) { return (mRxPacketType = type); };
    inline PacketType_t TxPacketType() { return mTxPacketType; };
    inline PacketType_t RxPacketType() { return mRxPacketType; };
    inline SequenceNumber_t SetTxPacketSeq(SequenceNumber_t seq) { return (mTxPacketSeq = seq); };
    inline SequenceNumber_t SetRxPacketSeq(SequenceNumber_t seq) { return (mRxPacketSeq = seq); };
    inline SequenceNumber_t TxPacketSeq() { return mTxPacketSeq; };
    inline SequenceNumber_t RxPacketSeq() { return mRxPacketSeq; };
    inline bool IsCommandPacket(PacketBuffer * p) { return GetFlag(*(p->Start()), kHeaderFlag_CommandMessage); }
    inline void PushPacketTag(PacketBuffer * p, PacketType_t type)
    {
        p->SetStart(p->Start() - sizeof(type));
        memcpy(p->Start(), &type, sizeof(type));
    };
    inline PacketType_t PopPacketTag(PacketBuffer * p)
    {
        PacketType_t type;
        memcpy(&type, p->Start(), sizeof(type));
        p->SetStart(p->Start() + sizeof(type));
        return type;
    };
#endif // CHIP_ENABLE_CHIPOBLE_TEST

    bool HasUnackedData(void) const;

    BLE_ERROR HandleCharacteristicReceived(PacketBuffer * data, SequenceNumber_t & receivedAck, bool & didReceiveAck);
    bool HandleCharacteristicSend(PacketBuffer * data, bool send_ack);
    BLE_ERROR EncodeStandAloneAck(PacketBuffer * data);

    PacketBuffer * RxPacket(void);
    PacketBuffer * TxPacket(void);

    bool ClearRxPacket(void);
    bool ClearTxPacket(void);

    void LogState(void) const;
    void LogStateDebug(void) const;

private:
    // Private data members:
#if CHIP_ENABLE_CHIPOBLE_TEST
    PacketType_t mTxPacketType;
    PacketType_t mRxPacketType;
    SequenceNumber_t mTxPacketSeq;
    SequenceNumber_t mRxPacketSeq;
#endif
    State_t mRxState;
    uint16_t mRxLength;
    void * mAppState;
    PacketBuffer * mRxBuf;
    SequenceNumber_t mRxNextSeqNum;
    SequenceNumber_t mRxNewestUnackedSeqNum;
    SequenceNumber_t mRxOldestUnackedSeqNum;
    uint16_t mRxFragmentSize;

    State_t mTxState;
    uint16_t mTxLength;
    PacketBuffer * mTxBuf;
    SequenceNumber_t mTxNextSeqNum;
    SequenceNumber_t mTxNewestUnackedSeqNum;
    SequenceNumber_t mTxOldestUnackedSeqNum;
    bool mExpectingAck;
    uint16_t mTxFragmentSize;

    uint16_t mRxCharCount;
    uint16_t mRxPacketCount;
    uint16_t mTxCharCount;
    uint16_t mTxPacketCount;

private:
    // Private functions:
    bool IsValidAck(SequenceNumber_t ack_num) const;
    BLE_ERROR HandleAckReceived(SequenceNumber_t ack_num);
};

} /* namespace Ble */
} /* namespace chip */

#endif /* CHIPOBLE_H_ */
