/*
 *
 *    Copyright (c) 2020-2021 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 objects that provide an abstraction layer between a
 *      platform's Bluetooth Low Energy (BLE) implementation and the CHIP
 *      stack.
 *
 *      The BleLayer obect accepts BLE data and control input from the
 *      application via a functional interface. It performs the fragmentation
 *      and reassembly required to transmit CHIP message via a BLE GATT
 *      characteristic interface, and drives incoming messages up the CHIP
 *      stack.
 *
 *      During initialization, the BleLayer object requires a pointer to the
 *      platform's implementation of the BleAdapter object. This object is
 *      defined but not implemented by the CHIP stack, and provides the
 *      BleLayer with a functional interface to drive outgoing GATT
 *      characteristic writes and indications. It also provides a mechanism
 *      for CHIP to inform the application when it has finished using a given
 *      BLE connection, i.e., when the chipConnection object wrapping this
 *      connection has closed.
 *
 *      To enable CHIP over BLE for a new platform, the application developer
 *      must implement the BleAdapter class for their platform, pass it to the
 *      BleLayer on startup, pass a pointer to this BleLayer to their instance
 *      of chipMessageLayer, and ensure that the application calls the
 *      necessary BleLayer functions to drive BLE data and control input up the
 *      stack.
 */

#pragma once

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>

#include <ble/BleConfig.h>

#include <lib/support/SetupDiscriminator.h>
#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>

#include <ble/BleApplicationDelegate.h>
#include <ble/BleConnectionDelegate.h>
#include <ble/BleError.h>
#include <ble/BleLayerDelegate.h>
#include <ble/BlePlatformDelegate.h>
#include <ble/BleRole.h>
#include <ble/BleUUID.h>

namespace chip {
namespace Ble {

/**
 *  @def NUM_SUPPORTED_PROTOCOL_VERSIONS
 *
 *  Number of unsigned 4-bit representations of supported transport protocol
 *  versions encapsulated in a BleTransportCapabilitiesRequest. Defined by CHIP
 *  over BLE protocol specification.
 */
#define NUM_SUPPORTED_PROTOCOL_VERSIONS 8
/// Version(s) of the CHIP BLE Transport Protocol that this stack supports.
#define CHIP_BLE_TRANSPORT_PROTOCOL_MIN_SUPPORTED_VERSION kBleTransportProtocolVersion_V4
#define CHIP_BLE_TRANSPORT_PROTOCOL_MAX_SUPPORTED_VERSION kBleTransportProtocolVersion_V4

/// Forward declarations.
class BleLayer;
class BLEEndPoint;

/// Enum defining versions of CHIP over BLE transport protocol.
typedef enum
{
    kBleTransportProtocolVersion_None = 0,
    kBleTransportProtocolVersion_V4   = 4 // BTP as defined by CHIP v1.0
} BleTransportProtocolVersion;

constexpr size_t kCapabilitiesRequestMagicnumLength          = 2;
constexpr size_t kCapabilitiesRequestL2capMtuLength          = 2;
constexpr size_t kCapabilitiesRequestSupportedVersionsLength = 4;
constexpr size_t kCapabilitiesRequestWindowSizeLength        = 1;
constexpr size_t kCapabilitiesRequestLength = (kCapabilitiesRequestMagicnumLength + kCapabilitiesRequestL2capMtuLength +
                                               kCapabilitiesRequestSupportedVersionsLength + kCapabilitiesRequestWindowSizeLength);

constexpr size_t kCapabilitiesResponseMagicnumLength                = 2;
constexpr size_t kCapabilitiesResponseL2capMtuLength                = 2;
constexpr size_t kCapabilitiesResponseSelectedProtocolVersionLength = 1;
constexpr size_t kCapabilitiesResponseWindowSizeLength              = 1;
constexpr size_t kCapabilitiesResponseLength(kCapabilitiesResponseMagicnumLength + kCapabilitiesResponseL2capMtuLength +
                                             kCapabilitiesResponseSelectedProtocolVersionLength +
                                             kCapabilitiesResponseWindowSizeLength);

class BleTransportCapabilitiesRequestMessage
{
public:
    /**
     * An array of size NUM_SUPPORTED_PROTOCOL_VERSIONS listing versions of the
     * BLE transport protocol that this node supports. Each protocol version is
     * specified as a 4-bit unsigned integer. A zero-value represents unused
     * array elements. Counting up from the zero-index, the first zero-value
     * specifies the end of the list of supported protocol versions.
     */
    uint8_t mSupportedProtocolVersions[(NUM_SUPPORTED_PROTOCOL_VERSIONS / 2) + (NUM_SUPPORTED_PROTOCOL_VERSIONS % 2)];

    /**
     *  The MTU that has been negotiated for this BLE connection. Specified in
     *  the BleTransportCapabilitiesRequestMessage because the remote node may
     *  be unable to glean this info from its own BLE hardware/software stack,
     *  such as on older Android platforms.
     *
     *  A value of 0 means that the central could not determine the negotiated
     *  BLE connection MTU.
     */
    uint16_t mMtu;

    /**
     *  The initial and maximum receive window size offered by the central,
     *  defined in terms of GATT indication payloads.
     */
    uint8_t mWindowSize;

    /**
     *  Set supported version value at given index in
     *  SupportedProtocolVersions. uint8_t version argument is truncated to 4
     *  least-significant bits. Index shall be 0 through number of
     *  SupportedProtocolVersions elements - 1.
     */
    void SetSupportedProtocolVersion(uint8_t index, uint8_t version);

    /// Must be able to reserve 20 byte data length in msgBuf.
    CHIP_ERROR Encode(const System::PacketBufferHandle & msgBuf) const;

    static CHIP_ERROR Decode(const System::PacketBufferHandle & msgBuf, BleTransportCapabilitiesRequestMessage & msg);
};

class BleTransportCapabilitiesResponseMessage
{
public:
    /**
     *  The lower 4 bits specify the BLE transport protocol version that the BLE
     *  peripheral has selected for this connection.
     *
     *  A value of kBleTransportProtocolVersion_None means that no supported
     *  protocol version was found in the central's capabilities request. The
     *  central should unsubscribe after such a response has been sent to free
     *  up the peripheral for connections from devices with supported protocol
     *  versions.
     */
    uint8_t mSelectedProtocolVersion;

    /**
     *  BLE transport fragment size selected by peripheral in response to MTU
     *  value in BleTransportCapabilitiesRequestMessage and its local
     *  observation of the BLE connection MTU.
     */
    uint16_t mFragmentSize;

    /**
     *  The initial and maximum receive window size offered by the peripheral,
     *  defined in terms of GATT write payloads.
     */
    uint8_t mWindowSize;

    /// Must be able to reserve 20 byte data length in msgBuf.
    CHIP_ERROR Encode(const System::PacketBufferHandle & msgBuf) const;

    static CHIP_ERROR Decode(const System::PacketBufferHandle & msgBuf, BleTransportCapabilitiesResponseMessage & msg);
};

/**
 *  @class BleLayer
 *
 *  @brief
 *    This class provides an interface for a single thread to drive data
 *    either up the stack via the BleLayer platform interface functions,
 *    or down the stack via a chipConnection object associated with a
 *    BLEEndPoint.
 *
 *    There are two ways to associate a chipConnection (defined by the
 *    chipMessageLayer) with a BLE connection:
 *
 *    First, the application can passively receive an incoming BLE connection
 *    and hand the platform-specific BLE_CONNECTION_OBJECT that this receipt
 *    generates to BleLayer via the corresponding platform interface function.
 *    This causes BleLayer to wrap the BLE_CONNECTION_OBJECT in a BLEEndPoint,
 *    and notify chipMessageLayer that a new BLE conneciotn has been received.
 *    The message layer then wraps the new BLEEndPoint object in a
 *    chipConnection, and hands this object to the application via the message
 *    layer's OnConnectionReceived callback.
 *
 *    Second, the application can actively form an outgoing BLE connection, e.g.,
 *    by connecting to a BLE peripheral. It then creates a new chipConnection
 *    via the chipMessageLayer, assigns an authentication type to this
 *    connection, and binds it to the BLE_CONNECTION_OBJECT for the new BLE
 *    connection via chipConnection::ConnectBle. This function then
 *    establishes the secure session type specified by the chipConnection's
 *    authentication type member variable.
 *
 */
class DLL_EXPORT BleLayer
{
    friend class BLEEndPoint;
#if CHIP_ENABLE_CHIPOBLE_TEST
    friend class BtpEngineTest;
#endif

public:
    // Public data members:
    enum
    {
        kState_NotInitialized = 0,
        kState_Initialized    = 1
    } mState; ///< [READ-ONLY] Current state

    // This app state is not used by ble transport etc, it will be used by external ble implementation like Android
    void * mAppState                 = nullptr;
    BleLayerDelegate * mBleTransport = nullptr;

    typedef void (*BleConnectionReceivedFunct)(BLEEndPoint * newEndPoint);
    BleConnectionReceivedFunct OnChipBleConnectReceived;

    // Public functions:
    BleLayer();

    CHIP_ERROR Init(BlePlatformDelegate * platformDelegate, BleApplicationDelegate * appDelegate,
                    chip::System::Layer * systemLayer);
    CHIP_ERROR Init(BlePlatformDelegate * platformDelegate, BleConnectionDelegate * connDelegate,
                    BleApplicationDelegate * appDelegate, chip::System::Layer * systemLayer);
    void Shutdown();

    CHIP_ERROR CancelBleIncompleteConnection();
    CHIP_ERROR NewBleConnectionByDiscriminator(const SetupDiscriminator & connDiscriminator, void * appState = nullptr,
                                               BleConnectionDelegate::OnConnectionCompleteFunct onSuccess = OnConnectionComplete,
                                               BleConnectionDelegate::OnConnectionErrorFunct onError      = OnConnectionError);
    CHIP_ERROR NewBleConnectionByObject(BLE_CONNECTION_OBJECT connObj);
    CHIP_ERROR NewBleEndPoint(BLEEndPoint ** retEndPoint, BLE_CONNECTION_OBJECT connObj, BleRole role, bool autoClose);

    void CloseAllBleConnections();
    void CloseBleConnection(BLE_CONNECTION_OBJECT connObj);

    /**< Platform interface functions:

     *   Calling conventions:
     *     CHIP takes ownership of PacketBuffers received through these functions,
     *     and will free them or pass ownership up the stack.
     *
     *     Beyond each call, no guarantees are provided as to the lifetime of UUID arguments.
     *
     *     A 'true' return value means the CHIP stack successfully handled the corresponding message
     *     or state indication. 'false' means the CHIP stack either failed or chose not to handle this.
     *     This contract allows the platform to pass BLE events to CHIP without needing to know which
     *     characteristics CHIP cares about.

     *     Platform must call this function when a GATT subscription has been established to any CHIP service
     *     charateristic.
     *
     *     If this function returns true, CHIP has accepted the BLE connection and wrapped it
     *     in a chipConnection object. If CHIP accepts a BLE connection, the platform MUST
     *     notify CHIP if the subscription is canceled or the underlying BLE connection is
     *     closed, or the associated chipConnection will never be closed or freed. */
    bool HandleSubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /// Call when a GATT subscribe request succeeds.
    bool HandleSubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /**< Platform must call this function when a GATT unsubscribe is requested on any CHIP
     *   service charateristic, that is, when an existing GATT subscription on a CHIP service
     *   characteristic is canceled. */
    bool HandleUnsubscribeReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /// Call when a GATT unsubscribe request succeeds.
    bool HandleUnsubscribeComplete(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /// Call when a GATT write request is received.
    bool HandleWriteReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                             System::PacketBufferHandle && pBuf);

    /// Call when a GATT indication is received.
    bool HandleIndicationReceived(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId,
                                  System::PacketBufferHandle && pBuf);

    /// Call when an outstanding GATT write request receives a positive receipt confirmation.
    bool HandleWriteConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /// Call when an outstanding GATT indication receives a positive receipt confirmation.
    bool HandleIndicationConfirmation(BLE_CONNECTION_OBJECT connObj, const ChipBleUUID * svcId, const ChipBleUUID * charId);

    /// Call when a GATT read request is received.
    bool HandleReadReceived(BLE_CONNECTION_OBJECT connObj, BLE_READ_REQUEST_CONTEXT requestContext, const ChipBleUUID * svcId,
                            const ChipBleUUID * charId);

    /**< Platform must call this function when any previous operation undertaken by the BleLayer via BleAdapter
     *   fails, such as a characteristic write request or subscribe attempt, or when a BLE connection is closed.
     *
     *   In most cases, this will prompt CHIP to close the associated chipConnection and notify that platform that
     *   it has abandoned the underlying BLE connection.
     *
     *   NOTE: if the application explicitly closes a BLE connection with an associated chipConnection such that
     *   the BLE connection close will not generate an upcall to CHIP, HandleConnectionError must be called with
     *   err = BLE_ERROR_APP_CLOSED_CONNECTION to prevent the leak of this chipConnection and its end point object. */
    void HandleConnectionError(BLE_CONNECTION_OBJECT connObj, CHIP_ERROR err);

#if CHIP_ENABLE_CHIPOBLE_TEST
    BLEEndPoint * mTestBleEndPoint;
#endif

private:
    // Private data members:

    // UUID of CHIP service characteristic used for central writes.
    static const ChipBleUUID CHIP_BLE_CHAR_1_ID;
    // UUID of CHIP service characteristic used for peripheral indications.
    static const ChipBleUUID CHIP_BLE_CHAR_2_ID;
    // UUID of CHIP service characteristic used for additional data
    static const ChipBleUUID CHIP_BLE_CHAR_3_ID;

    BleConnectionDelegate * mConnectionDelegate;
    BlePlatformDelegate * mPlatformDelegate;
    BleApplicationDelegate * mApplicationDelegate;
    chip::System::Layer * mSystemLayer;

    // Private functions:
    void HandleAckReceived(BLE_CONNECTION_OBJECT connObj);
    void DriveSending();
    CHIP_ERROR HandleBleTransportConnectionInitiated(BLE_CONNECTION_OBJECT connObj, System::PacketBufferHandle && pBuf);

    static BleTransportProtocolVersion GetHighestSupportedProtocolVersion(const BleTransportCapabilitiesRequestMessage & reqMsg);

    static void OnConnectionComplete(void * appState, BLE_CONNECTION_OBJECT connObj);
    static void OnConnectionError(void * appState, CHIP_ERROR err);
};

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

#include "BLEEndPoint.h"
