How_To_Writing_BlueCore_Applications
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
_äìÉi~Ä qj<br />
<strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
User Guide<br />
December 2007<br />
CSR<br />
Cambridge Science Park<br />
Milton Road<br />
Cambridge CB4 0WH<br />
United Kingdom<br />
Registered in England 4187346<br />
Tel: +44 (0)1223 692000<br />
Fax: +44 (0)1223 692001<br />
www.csr.com<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.
Contents<br />
Contents<br />
1 General............................................................................................................................................................ 4<br />
1.1 Introduction.............................................................................................................................................. 4<br />
2 Tasks, Messages and Message Handlers .................................................................................................... 5<br />
2.1 Tasks ..................................................................................................................................................... 5<br />
2.2 Messages ................................................................................................................................................ 5<br />
2.2.1 Message ID Numbering ............................................................................................................... 6<br />
2.2.2 Sending Messages....................................................................................................................... 6<br />
2.3 Message Handling................................................................................................................................... 6<br />
2.3.1 MessageLoop function ................................................................................................................. 6<br />
3 Task and Messages, Working Examples ..................................................................................................... 7<br />
3.1 Example 1................................................................................................................................................ 7<br />
3.1.1 The Code ..................................................................................................................................... 8<br />
3.1.2 Analysis of Code .......................................................................................................................... 8<br />
3.2 Example 2.............................................................................................................................................. 11<br />
3.2.1 The Code ................................................................................................................................... 11<br />
3.2.2 Analysis of Code ........................................................................................................................ 11<br />
3.3 Example 3.............................................................................................................................................. 12<br />
3.3.1 The Code ................................................................................................................................... 12<br />
4 Application Architecture ............................................................................................................................. 13<br />
4.1 The Application Task ............................................................................................................................. 13<br />
4.2 Profile and Support Tasks ..................................................................................................................... 14<br />
4.3 Firmware................................................................................................................................................ 14<br />
4.4 Message Scheduler............................................................................................................................... 15<br />
5 Planning and Coding an Application.......................................................................................................... 16<br />
5.1 Planning the Application ........................................................................................................................ 16<br />
5.2 Coding Overview ................................................................................................................................... 16<br />
5.2.1 Initialising Tasks......................................................................................................................... 16<br />
5.2.2 Dynamic (Lazy) Tasks................................................................................................................ 18<br />
5.2.3 Message Handling ..................................................................................................................... 21<br />
6 Using the Bluetooth Radio, Working Example .......................................................................................... 22<br />
6.1 Initialisation (common)........................................................................................................................... 23<br />
6.2 Enable Inquiry and Page Scan (hello_world_b)..................................................................................... 23<br />
6.3 Register the L2CAP PSM (common) ..................................................................................................... 23<br />
6.4 Initiate an L2CAP Connection (hello_world_a) ...................................................................................... 23<br />
6.5 Simple Pairing (common) ...................................................................................................................... 24<br />
6.6 Authorising the L2CAP connection (hello_world_b)............................................................................... 24<br />
6.7 Accept the L2CAP connection (hello_world_b)...................................................................................... 25<br />
6.8 L2CAP Connection Confirmation (common)..........................................................................................25<br />
7 Technical Support........................................................................................................................................ 26<br />
Document References ........................................................................................................................................ 27<br />
Terms and Definitions ........................................................................................................................................ 28<br />
Document History ............................................................................................................................................... 32<br />
Document Feedback ........................................................................................................................................... 32<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
List of Figures<br />
Figure 3.1: LED Flashing Application Example 1 .................................................................................................... 8<br />
Figure 3.2: LED Flashing Application Example 2 .................................................................................................. 11<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 2 of 32
Contents<br />
Figure 3.3: LED Flashing Application Example 3 .................................................................................................. 12<br />
Figure 4.1: Typical Application Architecture .......................................................................................................... 13<br />
Figure 4.2: Initialising a Task ................................................................................................................................ 14<br />
Figure 4.3: MessageLoop Function Call................................................................................................................ 15<br />
Figure 5.1: Defining a Task Data Structure ........................................................................................................... 17<br />
Figure 5.2: Declaring an Application Task............................................................................................................. 17<br />
Figure 5.3:Initialising an Application Task ............................................................................................................. 17<br />
Figure 5.4: Initialising a Profile Task ..................................................................................................................... 18<br />
Figure 5.5: Message Handling Code..................................................................................................................... 21<br />
Figure 6.1: L2CAP Connection Message Sequence Chart ................................................................................... 22<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 3 of 32
General<br />
1 General<br />
_äìÉi~Ä» SDKs provide developers with a series of libraries that support the implementation of Bluetooth<br />
applications that run on _äìÉ`çêÉ∆ chips.<br />
The use of the supplied libraries allows engineers to develop <strong>BlueCore</strong> applications that implement Bluetooth<br />
Profiles without becoming distracted by the complexity of the underlying Bluetooth Protocols.<br />
This approach has the additional benefit of allowing the underlying <strong>BlueCore</strong> firmware to be considered as a prequalified<br />
component of the final product.<br />
This document illustrates at a conceptual level how the source code and supplied libraries are used to build<br />
Bluetooth applications to run on <strong>BlueCore</strong> chips.<br />
This document should be read in conjunction with the Reference Guides provided as part of BlueLab’s on-line<br />
documentation that details the library-defined functions and the messages generated by the supplied libraries.<br />
1.1 Introduction<br />
This document introduces the fundamental concepts employed when developing applications designed to run on<br />
CSR’s <strong>BlueCore</strong> chips.<br />
The document covers:<br />
• The fundamentals of tasks, messages and message handling<br />
• <strong>How</strong> these are used by the libraries<br />
• <strong>How</strong> this defines the architectural of a typical <strong>BlueCore</strong> application<br />
The basic concepts and simple coding examples in this document are intended to illustrate good practice when<br />
writing code to run on <strong>BlueCore</strong>’s Virtual Machine and to help engineers gain a clearer understanding of using<br />
BlueLab SDKs to develop applications.<br />
In addition the reference applications supplied with BlueLab provide engineers with a valuable resource that can<br />
be used as a basis for their own application development or simply to help increase the understanding of how to<br />
implement <strong>BlueCore</strong> applications.<br />
The VM Memory Mapping and Memory Usage application note is also recommended reading for engineers<br />
embarking on the process of developing <strong>BlueCore</strong> applications.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 4 of 32
Tasks, Messages and Message Handlers<br />
2 Tasks, Messages and Message Handlers<br />
It is important to understand the concept of tasks, messages and message handling as they are integral to the<br />
way BlueLab applications are implemented.<br />
The sections 2.1 to 2.3 introduce these concepts:<br />
2.1 Tasks<br />
Tasks are the basic architectural building blocks used to construct an application and to provide an interface with<br />
the <strong>BlueCore</strong> firmware.<br />
Tasks provide functionality to the application i.e. an instance of the appropriate task must be initialised by the<br />
code in order for the functionality it supports to be available to the application.<br />
A task is basically a message handling function and a structure containing the task’s current state. All tasks are<br />
run as a single thread i.e. tasks do not execute concurrently.<br />
The tasks that make up the application include a top level task known as the application task. The application<br />
task responds to messages and controls the behaviour of the application.<br />
Note:<br />
More complex applications may define more than one application task.<br />
2.2 Messages<br />
Messages pass information between the tasks and are constructed in the form:<br />
Task t, MessageId id, Message payload<br />
The elements of a message are described below:<br />
• Task t: Identifies the destination of the message i.e. it is a pointer to the recipient task e.g.<br />
&AppTask.<br />
• MessageId id: is the message label that allows the task receiving the message to identify the<br />
appropriate function within the handler code.<br />
The MessageId id also implies the fields that can be expected in the payload. This allows the<br />
required information to be extracted by casting pointers to the payload fields.<br />
Note:<br />
By convention, a message’s structure is always enumerated as the Message Id with a suffix of _T.<br />
For example, the structure of the message CL_INIT_CFM is enumerated as Type<br />
CL_INIT_CFM_T.<br />
• Message payload: The payload should contain any state data required by the handler function to<br />
correctly react to the message. The payload is freed after the message has been delivered.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
<strong>To</strong> maximise the efficient use of memory the data passed in the payload should be kept to the minimum<br />
required by the message handling function to implement the appropriate response.<br />
In some cases, the message id alone may be sufficient. Therefore, the payload field is optional and can<br />
be Null.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 5 of 32
Tasks, Messages and Message Handlers<br />
2.2.1 Message ID Numbering<br />
The base number for Message IDs adhere to the following conventions:<br />
• Messages send by a task to itself start at 0x00.<br />
• System messages start at 0x8000.<br />
• Messages sent by specific profile libraries to tasks have been assigned base values e.g. the connection<br />
library messages start at base 0x7000 and the SPP library messages start at 0x6f00. See Appendix<br />
B.<br />
2.2.2 Sending Messages<br />
A number of functions are provided to facilitate the sending of messages, see message.h in the on-line help C<br />
Reference Guide.<br />
2.3 Message Handling<br />
The message handling facility for each task must be able to successfully handle all the message ids and states<br />
that can be passed to it.<br />
In practice the developer’s main responsibility is to provide the message handling code for the messages that will<br />
be received by the application task.<br />
Note:<br />
The message handlers for profile and support tasks initialised from BlueLab or SDK libraries need not<br />
concern developers. The handlers for these tasks are implemented by the libraries and are selected as a<br />
result of calling the appropriate Init function.<br />
The application must handle messages received from the libraries that it has initialised.<br />
2.3.1 MessageLoop function<br />
The MessageLoop function controls the main scheduler loop and handles the delivery of task messages.<br />
Messages are added to the queue in the order they are due to be delivered. The scheduler checks the first<br />
message in the queue and if due delivers the message to the appropriate task.<br />
Note:<br />
The MessageLoop function never returns and therefore is the last function called before the return<br />
statement in main.<br />
Tasks and messages allow the application developer to split the application up into cooperating modules (i.e.<br />
tasks) that handle messages from the firmware and each other.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 6 of 32
Task and Messages, Working Examples<br />
3 Task and Messages, Working Examples<br />
The previous chapter introduced the concepts of tasks, messages and message handling.<br />
This chapter looks at working examples to examine how these principals are applied in simple implementations of<br />
code and gives a brief explanation of the elements within the code.<br />
3.1 Example 1<br />
The first example looks at a single task application that flashes an LED on a PIO pin with a regular on/off period<br />
of 500 milliseconds.<br />
Note:<br />
The application has been chosen for simplicity, as it is one of the few examples that can be run on <strong>BlueCore</strong><br />
chips without using the connection library.<br />
<strong>To</strong> do this the code:<br />
• Defines a state for the single task required.<br />
• Defines a handling routine for messages (that will read the state of a PIO pin and switch it at regular<br />
intervals).<br />
• Sets the PIO as output.<br />
• Declares an instance of the task and initialises it.<br />
• Sends an initial message that will invoke the handler code.<br />
• Calls the MessageLoop function.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 7 of 32
Task and Messages, Working Examples<br />
3.1.1 The Code<br />
3.1.2 Analysis of Code<br />
Figure 3.1: LED Flashing Application Example 1<br />
1. The code employs functions declared in the message.h and pio.h header files so the first step is to<br />
#include these files:<br />
2. The next line of code defines a variable used to set a mask that identifies the PIO pin number that the<br />
LED is attached to (in this example PIO 6):<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
3. The next step is to define a structure for the task state. This is done using the typedef specifier:<br />
This defines a structure for the task and gives it the type <strong>To</strong>ggleTask.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 8 of 32
Task and Messages, Working Examples<br />
The first element of the structure, i.e. task, has the type TaskData defined as:<br />
{ void (*handler)(Task, MessageId, Message); }<br />
This consists of a pointer to a function that takes the three standard message fields as arguments i.e. a<br />
handler function.<br />
4. The next block of code defines the message handler function MyHandler:<br />
This code accepts a message as arguments then:<br />
• change is assigned the value in change by casting t (the task’s address) to a pointer of type<br />
<strong>To</strong>ggleTask pointing to the change field.<br />
• Calls the PioSet function, the arguments passed to it have the effect of flipping the LED state i.e.<br />
if the LED is on it is switched to off and vice versa.<br />
• The final statement sends a message after a delay of 500 milliseconds. The message scheduler<br />
delivers the message to MyHandler and the process is repeated, resulting in the LED flashing<br />
on/off every 500 milliseconds.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 9 of 32
Task and Messages, Working Examples<br />
5. The next line of code initialises the task:<br />
It defines a task, toggle with parameters that point to the handler function and set the bit mask for the<br />
PIO connected to the LED i.e. the handler will set PIO 6 (see #define statement).<br />
6. The final block of code is the main function:<br />
Looking at these statements individually:<br />
• The first statement sets the PIO pin to which the LED is connected to output.<br />
• The second sends a message to the handler, this kicks-off the LED sequence.<br />
• The third statement calls the MessageLoop() function for message delivery.<br />
• The final line complies with the ANSI C requirement to return a value.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 10 of 32
Task and Messages, Working Examples<br />
3.2 Example 2<br />
Example 2 expands on example 1 by adding a second flashing LED. This is achieved by adding a second task (in<br />
this example called flash).<br />
As no connection task is required, no AppTask as such is needed.<br />
3.2.1 The Code<br />
3.2.2 Analysis of Code<br />
Figure 3.2: LED Flashing Application Example 2<br />
This section considers how the code has been adjusted to add the second LED. Essentially this involves just 4<br />
lines of code:<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
1.<br />
Defines a label for the PIO pin to which the LED is connected (in this case PIO 7).<br />
2.<br />
Initialises a second task flash with parameters that point to the handler function and set the bit mask<br />
for the PIO connected to a second LED i.e. the handler will set PIO 7 (see #define statement).<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 11 of 32
Task and Messages, Working Examples<br />
3.<br />
Sets the PIOs connected to the LEDs direction to output.<br />
4.<br />
Finally, the second LED is started by the MessageSendLater function, the final parameter of which<br />
dictates the delay (in milliseconds) before the message is sent.<br />
3.3 Example 3<br />
Example 3 examines an alternative method of controlling the flashing LEDs. The salient point in this example is<br />
the addition of a field the Task structure used to control the timing of the LEDs flashing sequence.<br />
3.3.1 The Code<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
Figure 3.3: LED Flashing Application Example 3<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 12 of 32
Application Architecture<br />
4 Application Architecture<br />
This chapter describes how a typical BlueLab application uses tasks and messages to support Bluetooth profiles.<br />
The application architecture can be considered in three parts:<br />
• The application task.<br />
• The profile and support tasks (including the connection task).<br />
Note:<br />
• The firmware.<br />
These are library tasks provided by CSR to implement common functions, such as Bluetooth<br />
profiles.<br />
The architecture of the application is best illustrated graphically:<br />
Application<br />
Layer<br />
Key:<br />
Profile and<br />
Support Tasks<br />
Firmware Layer<br />
= Messages<br />
= Function Calls<br />
4.1 The Application Task<br />
Connection Task<br />
Application Task<br />
task1 task1 task1<br />
BlueStack<br />
Figure 4.1: Typical Application Architecture<br />
Support Task<br />
PIO<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
The application itself must be initialised as a task, and is generally known as the AppTask.<br />
Defining a structure for the AppTask and coding the message handler represents the minimum requirement<br />
when developing a <strong>BlueCore</strong> application.<br />
The data structure for the AppTask is determined by the specific application’s requirements and should include<br />
any data required to identify the state of the other tasks used by the application.<br />
See section 5.2 for a more in-depth description of the AppTask.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 13 of 32
Application Architecture<br />
4.2 Profile and Support Tasks<br />
BlueLab provides libraries that implement commonly used functionality, including Bluetooth profiles, to support<br />
the development of <strong>BlueCore</strong> applications.<br />
Note:<br />
The libraries support a wide range of Bluetooth Profiles. The addition of further libraries is a major objective<br />
in the ongoing development of BlueLab.<br />
<strong>To</strong> use a profile or support library in an application the developer must #include the appropriate library header<br />
file and calls the initialisation function to create an instance of the task. See Figure 4.2.<br />
The resultant task can then be regarded as a black box that handles any messages it receives and responds with<br />
a message to the application task where appropriate.<br />
Figure 4.2: Initialising a Task<br />
The code in Figure 4.2 initialises the connection library. The connection task created can support multiple<br />
connections and should only be called once.<br />
The application task receives an _INIT_CFM message when a task is created. The message-><br />
status indicates whether the task was created successfully or not.<br />
As long as the developer’s application message handler code correctly handles messages received from an<br />
instance of a task, the task will provide the expected functionality.<br />
Note:<br />
It is important to initialise the connection library before any other profile libraries because the connection<br />
library task is required during the creation of profile tasks.<br />
4.3 Firmware<br />
BlueLab and SDK applications interface with the BlueStack element of the <strong>BlueCore</strong> firmware through the<br />
connection task, i.e. the connection library gives access to Bluetooth features on <strong>BlueCore</strong>.<br />
When the connection task is initialised, the developer need not be concerned with how the connection task<br />
implements underlying functionality supported by the firmware.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
The developer can concentrate on handling the limited number of messages that the application task can<br />
potentially receive from the connection task.<br />
Note:<br />
Details of the messages generated by a connection task can be found in the xIDE on-line Reference Guide.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 14 of 32
Application Architecture<br />
4.4 Message Scheduler<br />
BlueLab and application SDKs provides a function to implement message scheduling. This function handles the<br />
delivery of task messages.<br />
Figure 4.3: MessageLoop Function Call<br />
The MessageLoop function acts on queued messages owned by the tasks. Messages are added to the queue<br />
in delivery due time order. The scheduler looks at the first message in the queue and if due, delivers it as<br />
arguments to the appropriate task handler.<br />
After a message has been passed to the task handler the MessageLoop function frees the original message<br />
payload before handling the next message in the queue or waiting until another message is added to the queue.<br />
Note:<br />
The message scheduler is not pre-emptive. It is therefore important that all handler functions run to<br />
completion and do not loop forever.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 15 of 32
Planning and Coding an Application<br />
5 Planning and Coding an Application<br />
This chapter considers the process of planning an application and gives a brief overview of the coding<br />
requirements.<br />
5.1 Planning the Application<br />
The first step when developing an application is to determine the tasks required to provide the desired<br />
functionality.<br />
In practical terms Bluetooth applications always require:<br />
• An application task<br />
• A connection task<br />
The other tasks depend on the type of device being developed and it is the developer’s responsibility to identify<br />
the Profile and Support tasks that are required by their application.<br />
When all the tasks that are required to build the application have been identified, the developer can begin to<br />
consider the code required to support them.<br />
5.2 Coding Overview<br />
This section gives a high-level overview of the elements that constitute an application.<br />
In simplistic terms the finished application code needs to:<br />
1. Set up and initialise the required tasks.<br />
2. Handle the messages received by the application task.<br />
These two basic requirements constitute the essential elements of all <strong>BlueCore</strong> application code. The actual way<br />
the code handles these requirements is largely at the discretion of the developer.<br />
The code required to implement an actual application can become complex. <strong>How</strong>ever, sections 5.2.1 and 5.2.3<br />
give brief description of the main elements.<br />
5.2.1 Initialising Tasks<br />
The code required to initialise a task depends on whether the task is developed by the software engineer e.g. the<br />
application task, or is a task supported by a BlueLab library e.g. a profile task.<br />
Initialising an Application Task<br />
Setting up and initialising an application task involves three distinct steps:<br />
• Typedef a data structure for the application task.<br />
• Declare a variable for the application task.<br />
• Initialise the application task states.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
When initialising an engineer defined task the developer is responsible for including code to handle each of the<br />
above steps.<br />
Defining Task State Structures<br />
The structure of the application task data type is at the discretion of the developer. It should allow for any data<br />
required to identify the state of other tasks and any other data the developer may want to use within the<br />
application.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 16 of 32
Planning and Coding an Application<br />
It is the developer’s responsibility to define a suitable structure for the application task.<br />
Figure 5.1 indicates a typical typedef for a simple Serial Port Profile (SPP) application task.<br />
Note:<br />
SPP has been selected as it is provides a simple example<br />
Figure 5.1: Defining a Task Data Structure<br />
When declaring a structure for a task the TaskData element is mandatory and must be the first element of the<br />
structure.<br />
Note:<br />
TaskData is defined as:<br />
Declaring the AppTask variable<br />
{ void (*handler)(Task, MessageId, Message); }<br />
When the structure for the application task has been defined, the application task can be declared e.g.:<br />
Figure 5.2: Declaring an Application Task<br />
This declaration defines the application task as a static variable called theSppApp with a data type as defined<br />
by sppTaskData.<br />
Initialising the Application Task<br />
The task is initialised by setting up the task’s message handler:<br />
Figure 5.3:Initialising an Application Task<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
In most cases it is also desirable to set up initial states for any variables associated with the task data.<br />
Initialising a ProfileTask<br />
When initialising a task supported by BlueLab or SDK libraries simply calling the appropriate Init function (with<br />
the argument pointing to the address of the application task handler) performs all the necessary steps for the task<br />
to be used by the application e.g:<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 17 of 32
Planning and Coding an Application<br />
Figure 5.4: Initialising a Profile Task<br />
Each time an Init function is called an instance of the respective task is created, memory allocated and a<br />
pointer to it is sent back to the application task.<br />
Note:<br />
ConnectInit is a special case in that it can only be called once. The connection task can maintain<br />
multiple connections in a single instance of the task.<br />
5.2.2 Dynamic (Lazy) Tasks<br />
From BlueLab v4.0 onwards dynamic (or lazy) tasks will be supported in VM applications.<br />
Note:<br />
In computer programming, lazy initialization delays the creation of an object, the calculation of a value, or<br />
some other expensive process until the first time it is needed. (from Wikipedia)<br />
Lazy tasks provide the following benefits:<br />
• A task instance is created and destroyed dynamically when needed. This provides better use of the<br />
limited memory resources available to a VM application.<br />
• More profiles can be supported in a single application since they do not need a task instance to be<br />
allocated on start up.<br />
• An application needs to call the initialisation function of a profile library only once. This simplifies the<br />
application initialisation state machine.<br />
Note:<br />
Without dynamic tasks the application needs to call the init function multiple times if it wants to<br />
support more than one instance of the profile<br />
• Without dynamic tasks a service record is registered for each profile instance. For example, if the<br />
application wishes to support two simultaneous HFP connections it calls HfpInit() twice. This<br />
registers two service records (with different RFCOMM server channels) with the SDP server in<br />
BlueStack. Although this is within specification it makes for a less elegant implementation as it requires<br />
the service record to be unregistered when that service has been connected to (and registered again<br />
when the connection is dropped).<br />
• Support can be provided for multiple profile instances for profile libraries using L2CAP.<br />
Note:<br />
Without dynamic tasks only a single profile library instance can be supported as only one task<br />
can be sent notifications of incoming connections. For example, this meant that before support<br />
for dynamic tasks only a single AV connection could be maintained.<br />
Registering the Client Task with the Connection Library<br />
For all instances of a dynamic task the first operation is to register it with the connection library, so that an<br />
RFCOMM channel or L2CAP PSM can be allocated. During this process the profile library also registers a<br />
profile_task_recipe. This is stored by the connection library and is used to dynamically create an<br />
instance of the specified profile library when required.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 18 of 32
Planning and Coding an Application<br />
The profile_task_recipe is defined as:<br />
typedef struct profile_task_recipe<br />
{<br />
uint16<br />
MessageId<br />
TaskData<br />
uint16<br />
const struct profile_task_recipe<br />
} profile task recipe;<br />
size_instance;<br />
msg_id;<br />
data;<br />
max_channels<br />
*parent_profile;<br />
Where:<br />
size_instance: This is the size of the profile task data for the profile registering with the<br />
connection library.<br />
msg_id: The message the connection library will send to the newly created task.<br />
Data: The task data for the profile task instance i.e. the profile handler function.<br />
max_channels: The maximum number of channels the profile instance will support<br />
parent_profile: The task recipe of the parent profile.<br />
Lazy tasks must be able to accommodate incoming and outgoing connections, each of which is handled<br />
differently:<br />
Incoming Connections<br />
On an incoming connection the task instance needs to be created dynamically by the connection library when<br />
it first receives the incoming connection indication. The connection library does this in two steps:<br />
1. The task instance is allocated and the profile handler set up. The size_instance field is used to<br />
allocate the memory for the task data and the data field is used to initialise the handler function of the<br />
newly created task.<br />
2. The initialisation message (msg_id) is sent to the newly created task.<br />
At this point the profile task instance has been created and partially initialised and the incoming connection<br />
indication can be sent to the new task. The task initialisation message is sent as soon as the task is created. This<br />
means that it will be delivered before any incoming connection indication message and by the time that message<br />
is delivered the profile task will be fully initialised. The incoming connection message is then handled as normal<br />
by the newly created task.<br />
Outgoing Connections<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
On an outgoing connection the profile library is responsible for creating the profile instance and using it in the<br />
connect request to the connection library. All libraries follow the same convention and the API function for<br />
initiating a connection creates an internal message to send to itself.<br />
The profile instance must be created and initialised before this internal message is sent so that, by the time the<br />
message is delivered, the task is ready to be used.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 19 of 32
Planning and Coding an Application<br />
Destroying a Dynamic Task<br />
Tasks that are allocated dynamically must be destroyed when they are no longer needed. In most cases this will<br />
be when the profile level connection is disconnected. On a disconnect indication, the profile library is responsible<br />
for notifying any clients of the disconnect and then cleaning up its state and destroying the profile task instance.<br />
When a client has received a disconnect indication it must not attempt to use the profile task instance (identified<br />
in the indication message) as that task has already been destroyed.<br />
Note:<br />
A disconnect is not the only case where a task will need to be destroyed. Other cases include a connect fail<br />
or the rejection of an incoming connection by the application.<br />
When the task needs to clean itself up, there may be outstanding messages for it in the queue.<br />
MessageTaskFlush must be called to ensure any such messages are removed. This is done by the profile<br />
instance as part of the clean up process.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 20 of 32
Planning and Coding an Application<br />
5.2.3 Message Handling<br />
The application task message handler must be able to successfully handle all the message states that can be<br />
passed to it by the other tasks that provide the application functionality.<br />
Typically, the handler consists of switch statements designed to take the appropriate action in response to the<br />
message id and the task state as indicated by a message passed to the handler function. Figure 5.5 shows a<br />
simplified example indicating typical message handler code.<br />
Example:<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
Figure 5.5: Message Handling Code<br />
It is the developer’s responsibility to ensure that the application task handles the messages it receives, to achieve<br />
the results expected/required by the application.<br />
Note:<br />
By convention, the message structure is always enumerated as the name of the message (i.e. the Message<br />
Id) with a suffix of _T. For example, if the message name is CL_INIT_CFM then the message type will be<br />
CL_INIT_CFM_T.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 21 of 32
Using the Bluetooth Radio, Working Example<br />
6 Using the Bluetooth Radio, Working Example<br />
This section describes how to set up a simple ACL connection between two Bluetooth devices. In this example,<br />
the connection is used for L2CAP and employs Bluetooth 2.1 Simple Pairing Just Works for authentication of the<br />
link.<br />
The example requires two separate communicating applications, a master A application on one device and a<br />
slave B application on the other device.<br />
Double-click on this<br />
xIDE.<br />
icon to open the master A example code which you can then paste into a New project in<br />
Double-click on this<br />
xIDE..<br />
icon to open the master B example code which you can then paste into a New project in<br />
Figure 6.1: L2CAP Connection Message Sequence Chart<br />
Figure 6.1 shows the basic message sequence chart for the applications on two Bluetooth devices,<br />
hello_world_a and hello_world_b. In the example, hello_world_a is the master and initiates the<br />
connection to hello_world_b. Hello_world_b which is inquiry and Page scanning. The BlueStack radio<br />
interactions are simplified, as that is not the focus of this example.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
The applications in this example share the majority of their functionality, therefore the description of the code<br />
samples indicates whether it is specific to the master A application, specific to the slave B application or common<br />
to both:<br />
• Common: common to both applications<br />
• hello_world_a: specific to the master A application<br />
• hello_world_b: specific to the slave B application<br />
The initialisation of the connection library, used to provide the functionality and API for creating the L2CAP<br />
connection, is covered in section 5.2.1.<br />
The master A application has been hard coded with the Bluetooth address of the slave B device so that no device<br />
inquiry and discovery phase is required.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 22 of 32
Using the Bluetooth Radio, Working Example<br />
6.1 Initialisation (common)<br />
When a connection has been established and bonded between two devices, the connection library stores the<br />
Bluetooth address of a bonded device and its link keys in PS Keys USR41 to USR49. The example<br />
demonstrates Simple Pairing when making a connection. In order to ensure this is carried out, all previously<br />
authenticated device information is deleted as part of the application initialisation.<br />
6.2 Enable Inquiry and Page Scan (hello_world_b)<br />
The slave B application is configured to enable scans for pages, although in the above example it has been<br />
configured to respond to inquiries as well.<br />
6.3 Register the L2CAP PSM (common)<br />
Both applications must register the L2CAP PSM value that is used to identify the connection, before attempting to<br />
establish the connection. The PSM must be an odd number and is a 16-bit value. In the example, a PSM of 257<br />
is used (see Bluetooth Core Specification for L2CAP).<br />
The BlueStack firmware responds to the PSM registration request with a CL_L2CAP_REGISTER_CFM<br />
message, indicating success or failure.<br />
6.4 Initiate an L2CAP Connection (hello_world_a)<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
Triggered by the successful registration of the PSM, the master A application initiations an L2CAP connection<br />
request. The Bluetooth address of the device to connect to (&theApp.dev_b) and the PSM of the L2CAP<br />
connection to connect from and to are passed as parameters. In this example, it is the same PSM value.<br />
Further L2CAP configuration parameters can be set but in this example, the default configuration is used by<br />
passing 0 or NULL for the configuration parameter block.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 23 of 32
Using the Bluetooth Radio, Working Example<br />
6.5 Simple Pairing (common)<br />
The example code above is taken from the master A application, although the code is common to both example<br />
applications. The slave B device requests the IO Capability of the Master A device first, and then after the master<br />
A device has responded, it requests the IO Capability of the Slave B device.<br />
The application must interact with BlueStack during the Simple Pairing scenario to indicate the hardware<br />
capability of the device which is being paired. In this example, both the master A device and slave B device<br />
indicate that they have no capability for input or output and also no Out Of Band data is used.<br />
Simple Pairing then proceeds using the Just Works model. Although more secure than the authentication<br />
previous to Bluetooth 2.1, it is still susceptible to a Man In The Middle (MITM) attack. (see Simple Pairing in the<br />
Core Specification).<br />
When the other device, receives the IO Capability Response, it indicates this to the application by a<br />
CL_SM_REMOTE_IO_CAPABILITY_IND message.<br />
6.6 Authorising the L2CAP Connection (hello_world_b)<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
After Simple Pairing is complete, the CL_SM_AUTHORISE_IND message indicates to the Slave B device that<br />
the Master A device is trying to establish a connection to it. The slave B application authorises the connection on<br />
the indicated L2CAP channel.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 24 of 32
Using the Bluetooth Radio, Working Example<br />
6.7 Accept the L2CAP Connection (hello_world_b)<br />
After the L2CAP channel connection has been authorised, the L2CAP Connection is indicated to the Slave B<br />
application. The application then send a response indicating that the L2CAP connection for the PSM is accepted.<br />
(see the xIDE online C reference Guide).<br />
6.8 L2CAP Connection Confirmation (common)<br />
Both applications receive a CL_L2CAP_CONNECT_CFM message to indicate that the L2CAP connection has<br />
been successfully set-up and is ready to use. The applications can start to transfer data across the radio using<br />
the L2CAP connection.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 25 of 32
Technical Support<br />
7 Technical Support<br />
Further information on all CSR products can be found on the technical support website<br />
(http://www.csrsupport.com).<br />
Developers are also recommended to view the public newsgroups hosted by CSR on the Internet news (NTTP)<br />
server news.csr.com. The newsgroups are a convenient forum for the Bluetooth community to exchange<br />
knowledge and are a valuable source of information.<br />
Set up instructions and guidelines for the use of newsgroups can be found by following the links on the CSR<br />
support website and in an introduction to BlueLab (CSR ref: blab-ug-001P).<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 26 of 32
Document References<br />
Document References<br />
Document<br />
an introduction to BlueLab<br />
BlueLab xIDE user guide<br />
a guide to the BlueLab Libraries<br />
Implementing Streams in BlueLab<br />
VM Memory Mapping and Memory Usage<br />
CSR Reference<br />
blab-ug-001P<br />
blab-ug-002P<br />
CS-101501-UG<br />
CS-110344-UG<br />
CS-110364-AN<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 27 of 32
Terms and Definitions<br />
Terms and Definitions<br />
API<br />
<strong>BlueCore</strong>®<br />
Bluetooth®<br />
CSR<br />
e.g.<br />
etc<br />
i.e.<br />
L2CAP<br />
MITM<br />
PSM<br />
SPP<br />
VM<br />
xIDE<br />
Application Programming Interface<br />
Group term for CSR’s range of Bluetooth wireless technology chips<br />
Set of technologies providing audio and data transfer over short-range radio connections<br />
Cambridge Silicon Radio<br />
exempli gratia, for example<br />
et cetera, and the rest, and so forth<br />
Id est, that is<br />
Logical Link Control and Adaptation Protocol<br />
Man-In-The-Middle<br />
Protocol Service Multiplexer<br />
Serial Port Profile<br />
Virtual Machine; environment in the <strong>BlueCore</strong> firmware for running application-specific code<br />
produced with BlueLab<br />
BlueLab’s Integrated Development Environment<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 28 of 32
System Messages<br />
Appendix A<br />
System Messages<br />
This section describes BlueLab’s system messages. They provide a means for a VM application to find out about asynchronous events. Effectively every possible asynchronous event is mapped onto a message from the system. A single task within the application<br />
can register an interest in particular messages. When a task has registered an interest any appropriate message types are routed to that task. If no task registers an interest in a particular message then that message is silently discarded.<br />
Note:<br />
Registering an interest in any BlueStack primitive registers all BlueStack primitives which will then be sent to the registering task<br />
Message Payload Type Task Granularity Description<br />
BLUESTACK_LC_PRIM<br />
BLUESTACK_LM_PRIM<br />
BLUESTACK_HCI_PRIM<br />
BLUESTACK_DM_PRIM<br />
BLUESTACK_L2CAP_PRIM<br />
BLUESTACK_RFCOMM_PRIM<br />
BLUESTACK_SDP_PRIM<br />
BLUESTACK_BCSP_LM_PRIM<br />
BLUESTACK_BCSP_HQ_PRIM<br />
uint16* MessageBlueStackTask System wide The corresponding BlueStack primitives<br />
BLUESTACK_BCSP_BCCMD_PRIM<br />
BLUESTACK_CALLBACK_PRIM<br />
BLUESTACK_TCS_PRIM<br />
BLUESTACK_BNEP_PRIM<br />
BLUESTACK_TCP_PRIM<br />
BLUESTACK_UDP_PRIM<br />
BLUESTACK_FB_PRIM<br />
FROM_HOST Bluestack primitive* MessageHostCommsTask System wide Word-oriented messages passed over BCSP#13<br />
MORE_DATA MessageMoreData* MessageSinkTask Per sink<br />
Data may have arrived on the source corresponding to<br />
the registered sink.<br />
MORE_SPACE MessageMoreSpace* MessageSinkTask Per sink Data may have left the registered sink.<br />
PIO_CHANGED MessagePioChanged* MessagePioTask System wide<br />
PioDebounce (or PioDebounce32) must have been<br />
called to enable the messages<br />
FROM_KALIMBA MessageFromKalimba* MessageKalimbaTask System wide DSP application must be running<br />
ADC_RESULT MessageAdcResult* AdcRequest Per request Task registered per-request using AdcRequest<br />
STREAM_DISCONNECT MessageStreamDisconnect* MessageSinkTask Per sink<br />
Message is sent to *both* tasks registered for source and<br />
sink of the connection.<br />
ENERGY_CHANGED MessageEnergyChanged* MessageSinkTask<br />
Per sink and<br />
request<br />
STATUS_CHANGED NONE MessageStatusTask Per request<br />
SOURCE_EMPTY MessageSourceEmpty* MessageSinkTask Per sink<br />
LONG_MESSAGE_FROM_KALIMBA LongMessageFromKalimba* MessageLongKalimbaTask System wide<br />
USB_ENUMERATED NONE MessageSystemTask System wide<br />
The message is sent to the task associated with the sink<br />
identifying the SCO stream. Estimation must be enabled<br />
(on a single-shot basis) using EnergyEstimationOn<br />
or EnergyEstimationSetBounds.<br />
The message is sent (an a one-shot basis) if any of the<br />
fields specified in the MessageStatusTask change.<br />
Details of the change can then be found using<br />
StatusQuery.<br />
Sent when the source corresponding to the sink becomes<br />
empty (and cannot possibly become full again.)<br />
A long message (longer than four words) is received from<br />
Kalimba.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGPc<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 29 of 32
System Messages<br />
Message Payload Type Task Granularity Description<br />
USB_SUSPENDED MessageUsbSuspended* MessageSystemTask System wide<br />
CHARGER_CHANGED MessageChargerChanged* MessageChargerTask System wide<br />
PSFL_FAULT NONE MessageSystemTask System wide<br />
USB_DECONFIGURED NONE MessageSystemTask System wide<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGPc<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 30 of 32
Library Message Bases<br />
Appendix B<br />
Library Message Bases<br />
This appendix shows the hex value bases for BlueLab library messages.<br />
Library Message Base Library Message Base<br />
Connection 0x7000 FTP Server 0x6500<br />
SPP 0x6f00 Codec 0x6400<br />
HFP 0x6e00 AGHFP 0x6300<br />
A2DP 0x6d00 PBAP Client 0x6200<br />
GAVDP (1) 0x6c00 PBAP Server 0x6100<br />
AVRCP 0x6b00 PIO Library 0x6000<br />
GOEP (OBEX) 0x6a00 DUN Library 0x5f00<br />
FTP Client 0x6900 audio 0x5d00<br />
Battery library 0x6800 GOEPC 0x5c00<br />
OPP Client 0x6700 GOEPS 0x5b00<br />
OPP Server 0x6600 HID 0x7100<br />
(1) The GAVDP library is deprecated from BlueLab v4.0 onwards.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 31 of 32
Document History<br />
Document History<br />
Revision Date Reason for Change<br />
ISSUE 1 14 DEC 07 Original publication of this document. (CSR reference: CS-110344-UGP1)<br />
Document Feedback<br />
If you have any comments about this document, send an email to comments@csr.com, giving the document<br />
number, title and section with your feedback.<br />
Unless otherwise stated, words and logos marked with or ® are trademarks registered or owned by Cambridge<br />
Silicon Radio Limited or its affiliates. Bluetooth ® and the Bluetooth logos are trademarks owned by Bluetooth SIG,<br />
Inc. and licensed to CSR. Other products, services and names used in this document may have been<br />
trademarked by their respective owners.<br />
_äìÉi~Ä qj <strong>Writing</strong> <strong>BlueCore</strong> <strong>Applications</strong><br />
The publication of this information does not imply that any license is granted under any patent or other rights<br />
owned by Cambridge Silicon Radio Limited.<br />
CSR reserves the right to make technical changes to its products as part of its development programme.<br />
While every care has been taken to ensure the accuracy of the contents of this document, CSR cannot accept<br />
responsibility for any errors.<br />
CSR’s products are not authorised for use in life-support or safety-critical applications.<br />
CS-110344-UGP1<br />
© CSR plc 2007<br />
This material is subject to CSR’s non-disclosure agreement.<br />
Page 32 of 32