![]() |
|
|
| Bluetooth on Microcontroller Platforms |
As part of the Smart-Its project we have designed and built a minimal computing and communication platform based on a Bluetooth module and a microcontroller with embedded memory. While the Bluetooth module offeres the generic Host Controller Interface (HCI) to the lower layers of the Bluetooth protocol stack, the higher L2CAP layer is implemented on the microcontroller.
News: As of June 13th, 2001, the Bluetooth stack (currently only HCI and L2CAP, SDP to come) is up and running. However, it is far from beeing a masterpiece of engineering and it is certainly not production quality! There will be a world-readable CVS repository in the upcoming weeks.
| Micorcontroller-Based Bluetooth Hardware |

| System Software |
The system software consists of low level drivers (2 serial ports, ADC, random number generator, system clock), a scheduler, and the bluetooth stack. Applications need to be linked against the system software code and then uploaded to the device.
Smart-Its applications are event driven. The scheduler allows application to register callback functions to be called upon certain events. Events currently supported are: data received on uart, uart ready to write data, timeout expired, and user events. The granularity of the timeout is roughly 250ms. If higher precision is required, the additional timer needs to be programmed on interrupt level. User events can be triggered by application code. They are useful to trigger a function being called from within a hardware interrupt. The scheduler only calls the function when it is save to do so.
The interface provided to the serial ports is equivalent to
the UNIX read() and write()
functions. In the microcontroller implementation, there are
static values for the file descriptors.
Both bluetooth stack and scheduler are available for the Atmel AVR as well as LINUX. therefore applications typically run on both systems without modification.
int main( void ) {
SmartIts_init();
// ...
// register callbacks for uarts
Scheduler_add_fd_read( UART_FD, data_received_on_uart );
Scheduler_run();
return 0;
} // end main()
void data_received_on_uart( int fd ) {
unsigned char tmpbuf[128] = "";
int count = 0;
count = read( fd, tmpbuf, 128 );
write( fd, tmpbuf, count );
} // end data_received_on_uart()
This code writes the data received on the serial port back
to the serial port. Whenever there is data available for reading
on the serial port, the scheduler calls the function
data_received_on_uart().
| Bluetooth-Stack |
Axis Communications has developed a Bluetooth driver for Linux. Our microcontroller version of the stack is based on an earlier version of the stack. (At that time the source code was available under the Gnu Public License, GPL.)
I have pulled the stack apart, removed unwanted code and optimized the remaining layers (HCI, L2CAP, hopefully SDP soon) for memory consumption. As of June 13th, 2001 the stack is running, however it is far from beeing a masterpiece of engineering. There will be a world readable CVS repository in the upcoming weeks.
| L2CAP Layer |
The L2CAP layer provides connection-oriented and connectionless data services to upper layer protocols with protocol multiplexing capability, segmentation and reassembly operation, and group abstractions. The L2CAP layer is based around the concept of 'channels'. Each one of the end-points of an L2CAP channel is referred to by a channel identifier.

Channel identifiers (CIDs) are local names representing a logical channel end-point on the device. CID assignment is relative to a particular device and a device can assign CIDs independently from other devices (with the exception of certain reserved CIDs, such as the signalling channel).
| CID | Description |
|---|---|
| 0x0000 | null id |
| 0x0001 | signalling channel |
| 0x0002 | connectionless reception channel |
| 0x0003 - 0x003F | reserved |
| 0x0040 - 0xFFFF | dynamically allocated |
The connection-oriented data channels represent a connection between two devices, where a CID identifies each endpoint of the channel. The connectionless channels restrict data flow to a single direction. These channels are used to support a channel 'group' where the CID on the source represents one or more remote devices.
The signalling channel is one example of a reserved channel. This channel is used to create and establish connection-oriented data channels and to negotiate changes in the characteristics of these channels. Another CID is reserved for all incoming connectionless data traffic.
| Cannel Type | Local Id | Remote Id |
|---|---|---|
| connection oriented | dynamically allocated | dynamically allocated |
| connectionless data | dynamically allocated | 0x0002 |
| signalling | 0x0001 | 0x0001 |
This state machine is only pertinent to bi-directional CIDs and is not representative of the signalling channel or the uni-directional channel.

Naming conventions:
While Requests for an action always result in a corresponding Confirmation (for the successful or unsuccessful satisfaction of the action), Indications do not always result into corresponding Responses.

Connection request packets are sent to create a channel between two devices. The connection request has two relevant parameters: the source Channel ID (CID) and the Protocol/Service Multiplexer (PSM).
The source CID parameter in the connection request is used as the destination CID in the connection response by the recipient of the request. The PSM parameter is used for protocol multiplexing. Some PMS values are assigned by the Bluetooth SIG and indicate protocols. The second range of values are dynamically allocated and used in conjunction with the Service Discovery Protocol (SDP). PSM values must be odd (see BT spec V1.0B section 5.3 "Connection Response" and 4.2 "Connectionless Data Channel").
| PSM value | Description |
|---|---|
| 0x0001 | Service Discovery Protocol |
| 0x0003 | RFCOMM |
| 0x0005 | Telephony Control Protocol |
| < 0x1000 | reserved |
| [0x1001-0xFFFF] | dynamically assigned |
Note: Currently the Axis stack only supports psm values < 8. 7 is used for L2CAP testing.
Maximum Transmission Unit (MTU): all L2CAP implementations must support a minimum MTU size of 48 bytes (regular and signalling packets). The default MTU size is 672 bytes (see section 4.1 and 6.1).
|