30.11.2015 Views

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!