/**

 */
#ifndef BLE_RCBR_H__
#define BLE_RCBR_H__

#include <stdint.h>
#include <stdbool.h>
#include "sdk_config.h"
#include "ble.h"
#include "ble_srv_common.h"
#include "nrf_sdh_ble.h"
#include "ble_link_ctx_manager.h"

#ifdef __cplusplus
extern "C" {
#endif

#define BLE_RCBR_BLE_OBSERVER_PRIO 2

/**@brief   Macro for defining a ble_rcbr instance.
 *
 * @param     _name            Name of the instance.
 * @param[in] _rcbr_max_clients Maximum number of RCBR clients connected at a time.
 * @hideinitializer
 */
#define BLE_RCBR_DEF(_name, _rcbr_max_clients)                      \
    BLE_LINK_CTX_MANAGER_DEF(CONCAT_2(_name, _link_ctx_storage),  \
                             (_rcbr_max_clients),                  \
                             sizeof(ble_rcbr_client_context_t));   \
    static ble_rcbr_t _name =                                      \
    {                                                             \
        .p_link_ctx_storage = &CONCAT_2(_name, _link_ctx_storage) \
    };                                                            \
    NRF_SDH_BLE_OBSERVER(_name ## _obs,                           \
                         BLE_RCBR_BLE_OBSERVER_PRIO,               \
                         ble_rcbr_on_ble_evt,                      \
                         &_name)

#define BLE_UUID_RCBR_SERVICE 0xD6E2 //0xD6E2 /**< The UUID of the R3charge Borrower Service. */

#define RCBR_SERVICE_UUID_TYPE   BLE_UUID_TYPE_VENDOR_BEGIN              /**< UUID type for the RCBR Service (vendor specific). */


#define BLE_UUID_RCBR_NOTIF_CHARACTERISTIC   0xD7E3 //0xD7E2               /**< The UUID of the Notification Characteristic. */
#define BLE_UUID_RCBR_SETTING_CHARACTERISTIC 0xD7E5 //0xD7E4               /**< The UUID of the Setting Characteristic. */

#define BLE_RCBR_MAX_NOTIF_CHAR_LEN        BLE_RCBR_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */
#define BLE_RCBR_MAX_SETTING_CHAR_LEN      BLE_RCBR_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */

#define RCBR_BASE_UUID                  {{0x77, 0x9a, 0x0c, 0x20, 0x00, 0x08, 0x6e, 0xaa, 0xe3, 0x11, 0x76, 0x34, 0xe2, 0xd6, 0x48, 0x75}} /**< Used vendor specific UUID. */


#define OPCODE_LENGTH        1
#define HANDLE_LENGTH        2

/**@brief   Maximum length of data (in bytes) that can be transmitted to the peer by the R3charge Borrower service module. */
#if defined(NRF_SDH_BLE_GATT_MAX_MTU_SIZE) && (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 0)
#define BLE_RCBR_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH)
#else
#define BLE_RCBR_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH)
#warning NRF_SDH_BLE_GATT_MAX_MTU_SIZE is not defined.
#endif


/**@brief   R3charge Borrower Service event types. */
typedef enum {
    BLE_RCBR_EVT_RX_DATA,      /**< Data received. */
    BLE_RCBR_EVT_TX_RDY,       /**< Service is ready to accept new data to be transmitted. */
    BLE_RCBR_EVT_NOTIF_ENABLED, /**< Notification has been enabled. */
    BLE_RCBR_EVT_NOTIF_DISABLED, /**< Notification has been disabled. */
} ble_rcbr_evt_type_t;


/* Forward declaration of the ble_rcbr_t type. */
typedef struct ble_rcbr_s ble_rcbr_t;


/**@brief   R3charge Borrower Service @ref BLE_RCBR_EVT_RX_DATA event data.
 *
 * @details This structure is passed to an event when @ref BLE_RCBR_EVT_RX_DATA occurs.
 */
typedef struct {
    uint8_t const * p_data; /**< A pointer to the buffer with received data. */
    uint16_t        length; /**< Length of received data. */
} ble_rcbr_evt_rx_data_t;


/**@brief R3charge Borrower Service client context structure.
 *
 * @details This structure contains state context related to hosts.
 */
typedef struct {
    bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
} ble_rcbr_client_context_t;


/**@brief   R3charge Borrower Service event structure.
 *
 * @details This structure is passed to an event coming from service.
 */
typedef struct {
    ble_rcbr_evt_type_t         type;        /**< Event type. */
    ble_rcbr_t                * p_rcbr;       /**< A pointer to the instance. */
    uint16_t                   conn_handle; /**< Connection handle. */
    ble_rcbr_client_context_t * p_link_ctx;  /**< A pointer to the link context. */
    union {
        ble_rcbr_evt_rx_data_t rx_data; /**< @ref BLE_RCBR_EVT_RX_DATA event data. */
    } params;
} ble_rcbr_evt_t;


/**@brief R3charge Borrower Service event handler type. */
typedef void (* ble_rcbr_data_handler_t) (ble_rcbr_evt_t * p_evt);


/**@brief   R3charge Borrower Service initialization structure.
 *
 * @details This structure contains the initialization information for the service. The application
 * must fill this structure and pass it to the service using the @ref ble_rcbr_init
 *          function.
 */
typedef struct {
    ble_rcbr_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
} ble_rcbr_init_t;


/**@brief   R3charge Borrower Service structure.
 *
 * @details This structure contains status information related to the service.
 */
struct ble_rcbr_s {
    uint8_t                         uuid_type;          /**< UUID type for R3charge Borrower Service Base UUID. */
    uint16_t                        service_handle;     /**< Handle of R3charge Borrower Service (as provided by the SoftDevice). */
    ble_gatts_char_handles_t        tx_handles;         /**< Handles related to the TX characteristic (as provided by the SoftDevice). */
    ble_gatts_char_handles_t        rx_handles;         /**< Handles related to the RX characteristic (as provided by the SoftDevice). */
    blcm_link_ctx_storage_t * const p_link_ctx_storage; /**< Pointer to link context storage with handles of all current connections and its context. */
    ble_rcbr_data_handler_t          data_handler;       /**< Event handler to be called for handling received data. */
};


/**@brief   Function for initializing the R3charge Borrower Service.
 *
 * @param[out] p_rcbr      R3charge Borrower Service structure. This structure must be supplied
 *                        by the application. It is initialized by this function and will
 *                        later be used to identify this particular service instance.
 * @param[in] p_rcbr_init  Information needed to initialize the service.
 *
 * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
 * @retval NRF_ERROR_NULL If either of the pointers p_rcbr or p_rcbr_init is NULL.
 */
uint32_t ble_rcbr_init(ble_rcbr_t * p_rcbr, ble_rcbr_init_t const * p_rcbr_init);


/**@brief   Function for handling the R3charge Borrower Service's BLE events.
 *
 * @details The R3charge Borrower Service expects the application to call this function each time an
 * event is received from the SoftDevice. This function processes the event if it
 * is relevant and calls the R3charge Borrower Service event handler of the
 * application if necessary.
 *
 * @param[in] p_ble_evt     Event received from the SoftDevice.
 * @param[in] p_context     R3charge Borrower Service structure.
 */
void ble_rcbr_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);


/**@brief   Function for sending a data to the peer.
 *
 * @details This function sends the input string as an RX characteristic notification to the
 *          peer.
 *
 * @param[in]     p_rcbr       Pointer to the R3charge Borrower Service structure.
 * @param[in]     p_data      String to be sent.
 * @param[in,out] p_length    Pointer Length of the string. Amount of sent bytes.
 * @param[in]     conn_handle Connection Handle of the destination client.
 *
 * @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
 */
uint32_t ble_rcbr_data_send(ble_rcbr_t * p_rcbr,
                            uint8_t   * p_data,
                            uint16_t  * p_length,
                            uint16_t    conn_handle);


#ifdef __cplusplus
}
#endif

#endif // BLE_RCBR_H__

/** @} */
