Transferring Data
Other versions of this page are also available for the following:
8/28/2008
To avoid data copying, the protocol stack uses two static buffers: one for reading and the other for writing. These buffers are given to the HCI_ReadPacket and HCI_WritePacket functions, respectively.
The data transfer structure is organized in such a way that headers can be easily pre-allocated on the way down or stripped on the way up. The HCI then goes into a read loop on one thread calling the HCI_ReadPacket function.
The buffers are exchanged using the following form.
struct BD_BUFFER {
int cSize;
int cStart;
int cEnd;
BD_BUFFER_FREE pFree;
int fMustCopy;
unsigned char *pBuffer;
};
Of interest to HCI transport here are only three members:
- cSize,whichdefines the size of pBuffer
- cStart, which is the offset of valid information in pBuffer
- cEnd, which is the end of valid information in pBuffer
HCI_ReadPacket is given a buffer in which cSize is not smaller than the one requested in the HCI_ReadHciParameters response. cStart is set to 0 and cEnd is set to be equal to cSize. Before HCI_ReadPacket returns, it is allowed to use this buffer however it pleases. On return, the data between cStart and cEnd MUST contain a valid Bluetooth HCI packet.
The HCI_WritePacket function is given a buffer where cStart is set to the beginning of the HCI packet. The spaces between 0 and cStart and between cEnd and cSize will be big enough to accommodate the transport header and trailer as requested by HCI_ReadHciParameters. HCI_WritePacket can use these spaces to put its own information in it.
The packet type is returned in *peType and can be DATA_PACKET_ACL, DATA_PACKET_SCO or EVENT_PACKET.
If communication with the Bluetooth controller fails because of hardware failure or the controller has been ejected from the device, HCI_ReadPacket must fail with a 0 return code. The HCI layer will then shut itself down until indicated by the transport layer that the hardware is available using the callback.
// HCI_ReadPacket MUST return 4-bytes aligned cStart in its buffer
// HCI_ReadPacket and HCI_WritePacket WILL change cStart and cEnd of the
// buffer, but WILL NOT change any other data.
enum HCI_TYPE {
COMMAND_PACKET = 1,
DATA_PACKET_ACL = 2,
DATA_PACKET_SCO = 3,
EVENT_PACKET = 4,
ETYPE_FINISH = 5
};
int HCI_ReadPacket (HCI_TYPE *peType, BD_BUFFER *pInBuffer);
int HCI_WritePacket (HCI_TYPE eType, BD_BUFFER *pOutBuffer);