/**
******************************************************************************************************************************************************************************************
*@file                       buff.h
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#ifndef BUFF_H
#define BUFF_H

struct buff_stru {
	WORD len; /* length of whole buffer, including data before off */
	WORD off;
	UCHAR data[1];
};

struct buff_stru *_buff_new(UINT16 size, UINT16 off);

#ifdef CONFIG_MEMORY_LEAK_DETECT
	#define BuffNew(size_, off_)	DBG_Memory_LeakNew(_buff_new((size_), (off_)), 0, (size_) + (off_) + sizeof(struct buff_stru) + sizeof(UINT32), MEMORY_LEAK_POSINFO)
#else
	#define BuffNew(size_, off_)	_buff_new((size_), (off_))
#endif

#define PriBufNew(size_, off_, buf_, pri_) buf_ = BuffNew(size_, off_); HCI_BUFPRI(buf_) = (pri_)

struct buff_stru *buff_copy(struct buff_stru *in);
UINT8 buff_res(struct buff_stru *buf, INT16 delta);
#define BuffFree FREE

enum {/* HCI_BUFPRI */
	PRI_RELIABLE = 	1,/* Lowest priority, but reliable, donot flush, etc, FTP */
	PRI_REALTIME = 	2,/* etc, A2DP, could be flush */
	PRI_SIGNAL = 	3,/* Signal, harry to send out */
	PRI_PARTOUT = 	0xFF/* Partial send out, do not interlace */
};

#define HDLPTR(buf)				((UINT32 *)(&(((struct buff_stru *)buf)->data[0])))
#define HCICTRL(buf)			(&(((struct buff_stru *)buf)->data[4]))/* for HCI_RESERVE, Bufdata Priority(1), HCI AMPID(1), L2CAP Payload or S_Frame Flag(1) */
#define HCI_BUFPRI(buf)			(*HCICTRL(buf))/* Bufdata Priority, 1 octet, etc, PRI_RELIABLE */
#define HCI_BUFAMPID(buf)		(*(HCICTRL(buf) + 1))/* HCI AMPID, 1 octet */
#define HCI_BUFL2PAYLOAD(buf)	(*(HCICTRL(buf) + 2))/* L2CAP Payload or S_Frame Flag, 1 octet */
#define HCI_HEADER				5/* data Type (1), Handle (2), HCI Payload len (2) */
#define HCI_RESERVE				(3 + HCI_HEADER)/* 3 for HCICTRL as above; 5 is for hci_acl_data_send2TL, HCI headers */
#define L2CAP_RESERVE			(4 + HCI_RESERVE)/* L2CAP CID(2), Length(2), as Basic Header */

#define BUFLEN(buf)  			(((struct buff_stru *)buf)->len)
#define BUFDATA(buf)			((UINT8 *)(((struct buff_stru *)buf)->data + ((struct buff_stru *)buf)->off))
#define BUFEND(buf)				((UINT8 *)(((struct buff_stru *)buf)->data + ((struct buff_stru *)buf)->len))/* BUFDATA+DATASIZE, 1st invalid octet */
#define DATASIZE(buf) 			(BUFLEN((struct buff_stru *)buf) - ((struct buff_stru *)buf)->off)

#endif

