/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#ifndef BT_CUSTOM_CLIENT_H_
#define BT_CUSTOM_CLIENT_H_

/**
 * @file
 * @defgroup bt_custom_client Bluetooth LE GATT CUSTOM Client API
 * @{
 * @brief API for the Bluetooth LE GATT Nordic UART Service (CUSTOM) Client.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/conn.h>
#include <bluetooth/gatt_dm.h>

#define DISCOVERY

/** @brief UUID of the CUSTOM_SRV Service. **/
#define BT_UUID_CUSTOM_SRV_VAL \
	BT_UUID_128_ENCODE(0x2a1f963c, 0x143a, 0x4f7d, 0x9107, 0x6315196a02a6)

/** @brief UUID of the TX Characteristic. **/
#define BT_UUID_CUSTOM_SRV_TX_VAL \
	BT_UUID_128_ENCODE(0x651135b0, 0xdfe9, 0x45a2, 0x95c1, 0x46552a8a77e2)

/** @brief UUID of the RX Characteristic. **/
#define BT_UUID_CUSTOM_SRV_RX_VAL \
	BT_UUID_128_ENCODE(0xe7d6274e, 0xb765, 0x11e9, 0xa2a3, 0x2a2ae2dbcce4)

#define BT_UUID_CUSTOM_SRV_DISCOVER_VAL  \
	BT_UUID_128_ENCODE(0x6baee5f6, 0xf2fc, 0x4df6, 0x9266, 0x0d65a5908fac)

#define BT_UUID_CUSTOM_SERVICE   BT_UUID_DECLARE_128(BT_UUID_CUSTOM_SRV_VAL)
#define BT_UUID_CUSTOM_RX        BT_UUID_DECLARE_128(BT_UUID_CUSTOM_SRV_RX_VAL)
#define BT_UUID_CUSTOM_TX        BT_UUID_DECLARE_128(BT_UUID_CUSTOM_SRV_TX_VAL)
#define BT_UUID_CUSTOM_DISC      BT_UUID_DECLARE_128(BT_UUID_CUSTOM_SRV_DISCOVER_VAL)

#define  NO_ERROR 0

#define SCAN_BY_NAME

/** @brief Handles on the connected peer device that are needed to interact with
 * the device.
 */
struct bt_custom_client_handles 
{
	uint16_t rx; // Handle of the CUSTOM RX characteristic, provided by a discovery.	
	uint16_t rx_ccc; // CCC descriptor of the RX chcracteristic??
	uint16_t tx; // And for the TX characteristic
	uint16_t tx_ccc; // CCC descriptor of the TX chcracteristic	
#ifdef DISCOVERY	
	uint16_t association;
	uint16_t association_ccc;
#endif	
};

struct association_params_struct {
	/** Value handle. */
	uint16_t handle;

	/** Read parameters. */
	struct bt_gatt_read_params read_params;

};

struct bt_custom_client;

/** @brief CUSTOM Client callback structure. 
 * * @brief Data received callback.
	 *
	 * The data has been received as a notification of the CUSTOM TX
	 * Characteristic.
	 *
	 * @param[in] custom  CUSTOM Client instance.
	 * @param[in] data Received data.
	 * @param[in] len Length of received data.
	 *
	 * @retval BT_GATT_ITER_CONTINUE To keep notifications enabled.
	 * @retval BT_GATT_ITER_STOP To disable notifications.
	 
	 @brief Data sent callback.
	 *
	 * The data has been sent and written to the CUSTOM RX Characteristic.
	 *
	 * @param[in] custom  CUSTOM Client instance.
	 * @param[in] err ATT error code.
	 * @param[in] data Transmitted data.
	 * @param[in] len Length of transmitted data.

	* @brief TX notifications disabled callback.
	 *
	 * TX notifications have been disabled.
	 *
	 * @param[in] custom  CUSTOM Client instance.	 

*/
#ifdef CALLBACK_METHOD
struct bt_custom_client_cb 
{	
	uint8_t (*received_tx)(struct bt_custom_client *custom, const uint8_t *data, uint16_t len);
	uint8_t (*received_rx)(struct bt_custom_client *custom, const uint8_t *data, uint16_t len);	
	void (*sent)(struct bt_custom_client *custom, uint8_t err, const uint8_t *data, uint16_t len);
	void (*unsubscribed)(struct bt_custom_client *custom);
};
#endif

/** @brief CUSTOM Client structure. */
struct bt_custom_client 
{
       
	struct bt_conn *conn;  // Connection object.        
	atomic_t state; // Internal state.
        /** Handles on the connected peer device that are needed
         * to interact with the device.
         */
	struct bt_custom_client_handles handles;

        /** GATT subscribe parameters for CUSTOM TX Characteristic. */
	struct bt_gatt_subscribe_params tx_notif_params;

        /** GATT write parameters for CUSTOM RX Characteristic. */
	struct bt_gatt_subscribe_params rx_notif_params;
	struct bt_gatt_write_params tx_write_params;
	struct association_params_struct association_parameters;

	// GATT discovery
	

};



/** @brief Send data to the server.
 *
 * This function writes to the RX Characteristic of the server.
 *
 * @note This procedure is asynchronous. Therefore, the data to be sent must
 * remain valid while the function is active.
 *
 * @param[in,out] custom CUSTOM Client instance.
 * @param[in] data Data to be transmitted.
 * @param[in] len Length of data.
 *
 * @retval 0 If the operation was successful.
 *           Otherwise, a negative error code is returned.
 */
int bt_custom_client_send(struct bt_custom_client *custom, const uint8_t *data,
		       uint16_t len);

/** @brief Assign handles to the CUSTOM Client instance.
 *
 * This function should be called when a link with a peer has been established
 * to associate the link to this instance of the module. This makes it
 * possible to handle several links and associate each link to a particular
 * instance of this module. The GATT attribute handles are provided by the
 * GATT DB discovery module.
 *
 * @param[in] dm Discovery object.
 * @param[in,out] custom CUSTOM Client instance.
 *
 * @retval 0 If the operation was successful.
 * @retval (-ENOTSUP) Special error code used when UUID
 *         of the service does not match the expected UUID.
 * @retval Otherwise, a negative error code is returned.
 */
int bt_custom_handles_assign(struct bt_gatt_dm *dm,
			  struct bt_custom_client *custom);

/** @brief Request the peer to start sending notifications for the TX
 *	   Characteristic.
 *
 * This function enables notifications for the CUSTOM TX Characteristic at the peer
 * by writing to the CCC descriptor of the CUSTOM TX Characteristic.
 *
 * @param[in,out] custom CUSTOM Client instance.
 *
 * @retval 0 If the operation was successful.
 *           Otherwise, a negative error code is returned.
 */
int bt_custom_subscribe_tx_receive(struct bt_custom_client *custom);
int bt_custom_subscribe_rx_receive(struct bt_custom_client *custom);


int init_association_discovery(struct bt_custom_client *xlrt_connection_ptr);

#ifdef __cplusplus
}
#endif

/**
 * @}
 */

#endif /* BT_CUSTOM_CLIENT_H_ */
