Bluetooth HCI Transport Layer

The HCI Transport is designed to abstract and simplify physical communication between the Bluetooth stack and the controller. This set of modules implement UART, COM, or USB transports as defined by respective parts of the Bluetooth Core Specification.

A transport only implements a few functions; schematically, Open, Read, Write, Close and two for bookkeeping; Read and Write are blocking. The Bluetooth stack uses these functions to send Bluetooth commands and data packets, and receive data packets and events.

This interface is defined by Bt_hcip.h. Annotated excerpts from this file are included below.

When the Bluetooth stack initializes, it calls the HCI_SetCallback function of the HCI Transport interface. It passes a callback that is used by HCI transport layer to indicate insertion or removal of hardware.

The stack can also call the HCI_StartHardware and HCI_StopHardware functions to make the physical layer simulate an ejection or insertion of a controller, whether it is removable or not.

enum HCI_EVENT {
   DEVICE_UP,
   DEVICE_DOWN,
   DEVICE_ERROR
};
typedef int (*HCI_TransportCallback) (HCI_EVENT eEvent, void *pEvent);
int HCI_SetCallback (HCI_TransportCallback pfCallback);
int HCI_StartHardware (void);
int HCI_StopHardware (void);

When an insertion is signaled, the stack calls the HCI_OpenConnection function. If it returns TRUE, the transport is considered to be active.

When HCI_OpenConnection returns TRUE, the Bluetooth stack calls the HCI_ReadHciParameters function.

In the HCI_PARAMETERS structure passed as an argument, it fills out only the size and version field. The transport driver must ensure that the version of the stack matches the version of the transport driver exactly.

The HCI transport is responsible for filling the HCI_PARAMETERS structure completely. Important members of this structure indicate minimum buffers required for incoming packets, and maximum buffers allowed for outgoing packets, as well as the version of the Bluetooth hardware.

#define HCI_INTERFACE_VERSION_1_0       0x00010000
#define HCI_HARDWARE_VERSION_V_1_0_A    0
#define HCI_HARDWARE_VERSION_V_1_0_B    1
#define HCI_HARDWARE_VERSION_V_1_1      2
#define HCI_DEFAULT_WRITE_TIMEOUT       15000
#define HCI_FLAGS_NORESET               0x00000001
#define HCI_FLAGS_NOLOCALNAME           0x00000002
#define HCI_FLAGS_NOROLESWITCH          0x00000004
//
// Note:
//   iMaxSize parameters MUST fit the biggest HCI command
//     (HCI_RemoteNameRequest as of this writing is 257 bytes,
//      see also bt_ddi.h::HCI_MAX_COMMAND_LENGTH)
//   iReadBufferHeader and iWriteBufferHeader MUST be 4-bytes aligned
//
typedef struct __hci_parameters {
   unsigned int   uiSize;              // structure size
   unsigned int   fInterfaceVersion;   // interface version
   int   iMaxSizeRead;                 // Max size of read packet
                                       // (not including headers and 
                                       // trailers)
   int   iMaxSizeWrite;                // Max size of write packet
                                       // (not including headers and 
                                       // trailers)
   int   iReadBufferHeader;            // Hint : read may contain up to
                                       //as much transport header bytes
   int   iReadBufferTrailer;           // Hint : read may contain up to
                                       // as much transport trailer bytes
   int   iWriteBufferHeader;           // Number of bytes to preallocate
                                       // for transport header
   int   iWriteBufferTrailer;        // Number of bytes to preallocate
                                     // for transport trailer
   int   uiFlags;                    // Flags
   int   fHardwareVersion;           // Bluetooth specification version of      
                                     // hardware
   unsigned int   uiResetDelay;      // milliseconds : delay next command
                                     // after reset by this much
   unsigned int   uiWriteTimeout;    // milliseconds : abort if card
                                     // does not respond in this time
                                     // (use the default above)
} HCI_PARAMETERS;

int HCI_ReadHciParameters (HCI_PARAMETERS  *pParms);

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);

When the HCI wants to close communication to the Bluetooth controller, it issues an HCI_CloseConnection command. The HCI must then unblock and fail the pending HCI_ReadPacket call and shut down communications with the Bluetooth controller.

The HCI transport is not allowed to issue any commands that affect the state of the Bluetooth controller on its own, such as Reset, except in the context of the HCI_OpenConnection function.

HCI Transports are currently provided only for BSCP, UART, NOKIA and USB protocols. Other hardware support is supplied by the OEM. Sample device drivers for the provided protocols, mentioned above, can be found in %_WINCEROOT%\Public\Common\Oak\Drivers\Bluetooth\Transports.

A universal driver is also provided. This driver acts as an intermediary between a real protocol driver and the Bluetooth stack. It detects insertion of PCMCIA and USB cards and thunks HCI transport interface calls to the right driver. This driver is described in detail in %_WINCEROOT%\Public\Common\Oak\Drivers\Bluetooth\Transports\UNIV.

The following topics discuss the HCI transport layer in more detail:

A reference is also provided to help you take advantage of all the functionality offered by the HCI transport layer. For more information about the Bluetooth enumerations, functions, and structures, see the topics in the Bluetooth HCI Transport Layer Reference node.

See Also

Bluetooth HCI Transport Driver

 Last updated on Tuesday, May 18, 2004

© 1992-2003 Microsoft Corporation. All rights reserved.