#ifndef _BT_L2CAP_H
#define _BT_L2CAP_H


#define L2CAP_CID_SIGNALING                 0x0001
#define L2CAP_CID_CONNECTIONLESS_CHANNEL    0x0002
#define L2CAP_CID_ATTRIBUTE_PROTOCOL        0x0004
#define L2CAP_CID_SIGNALING_LE              0x0005
#define L2CAP_CID_SECURITY_MANAGER_PROTOCOL 0x0006

typedef enum {
	COMMAND_REJECT = 1,
	CONNECTION_REQUEST,
	CONNECTION_RESPONSE,
	CONFIGURE_REQUEST,
	CONFIGURE_RESPONSE,
	DISCONNECTION_REQUEST,
	DISCONNECTION_RESPONSE,
	ECHO_REQUEST,
	ECHO_RESPONSE,
	INFORMATION_REQUEST,
	INFORMATION_RESPONSE
} L2CAP_SIGNALING_COMMANDS;

typedef enum {
	PB_FIRST_NON_FLUSH = 0,
	PB_CONTINUE_FRAGMENT,
	PB_FIRST_FLUSHABLE,
	PB_COMPLETE_PDU
} L2CAP_PB_FLAG;

typedef enum {
	BC_NO_BROADCAST = 0,
	BC_ACTIVE_SLAVE,
	BC_PARKED_SLAVE,
	BC_RESERVED
} L2CAP_BC_FLAG;

// Connection result values
#define BT_L2CAP_CON_RES_SUCCESS		0x0000
#define BT_L2CAP_CON_RES_PENDING		0x0001
#define BT_L2CAP_CON_RES_REFUSED_PSM		0x0002
#define BT_L2CAP_CON_RES_REFUSED_SECURITY	0x0003
#define BT_L2CAP_CON_RES_REFUSED_RSRC		0x0004

#define BT_L2CAP_CON_STAT_NOINFO		0x0000
#define BT_L2CAP_CON_STAT_AUTHEN_PENDING	0x0001
#define BT_L2CAP_CON_STAT_AUTHOR_PENDING	0x0002

typedef enum {
	BT_L2CAP_CON_IDLE = 0,
	BT_L2CAP_CON_CONNECTED
} bt_l2cap_con_state_t;

// describes the L2CAP connection
typedef struct {
	bt_l2cap_con_state_t cstate;

	uint16_t hci_handle;
	uint16_t PSM;		// PSM of this connection

	uint16_t locCID;	// our local CID
	uint16_t remCID;	// remote host CID

	uint16_t locMTU;
	uint16_t remMTU;
} bt_l2cap_con_t;

void init_l2cap(void);
void bt_l2cap_proc_dyn_channel(const uint16_t channel, const uint16_t handle, const void *mdat, uint16_t mlen);
uint8_t bt_l2cap_get_connected(const uint16_t channel);
void bt_l2cap_send_channel(const uint16_t channel, const void *mdat, uint16_t mlen);
void bt_l2cap_proc_signalling(const uint16_t handle, unsigned char *mdat, uint16_t mlen);
void bt_l2cap_handle_connection_request(const uint16_t handle, const uint8_t ident, const uint16_t PSM, const uint16_t src_CID);

#endif