Skip to content

Commit 8faef82

Browse files
author
Donatien Garnier
authored
Merge pull request ARMmbed#111 from pan-/gatt-client-example
Add example exercising the GattClient API.
2 parents e2ea1ea + f916946 commit 8faef82

File tree

7 files changed

+864
-0
lines changed

7 files changed

+864
-0
lines changed

BLE_GattClient/.mbed

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ROOT=.
2+
TARGET=NRF52_DK

BLE_GattClient/BLEProcess.h

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2015 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef GATT_EXAMPLE_BLE_PROCESS_H_
18+
#define GATT_EXAMPLE_BLE_PROCESS_H_
19+
20+
#include <stdint.h>
21+
#include <stdio.h>
22+
23+
#include "events/Eventqueue.h"
24+
#include "platform/Callback.h"
25+
#include "platform/NonCopyable.h"
26+
27+
#include "ble/BLE.h"
28+
#include "ble/Gap.h"
29+
#include "ble/GapAdvertisingParams.h"
30+
#include "ble/GapAdvertisingData.h"
31+
#include "ble/FunctionPointerWithContext.h"
32+
33+
/**
34+
* Handle initialization and shutdown of the BLE Instance.
35+
*
36+
* Setup advertising payload and manage advertising state.
37+
* Delegate to GattClientProcess once the connection is established.
38+
*/
39+
class BLEProcess : private mbed::NonCopyable<BLEProcess> {
40+
public:
41+
/**
42+
* Construct a BLEProcess from an event queue and a ble interface.
43+
*
44+
* Call start() to initiate ble processing.
45+
*/
46+
BLEProcess(events::EventQueue &event_queue, BLE &ble_interface) :
47+
_event_queue(event_queue),
48+
_ble_interface(ble_interface),
49+
_post_init_cb() {
50+
}
51+
52+
~BLEProcess()
53+
{
54+
stop();
55+
}
56+
57+
/**
58+
* Initialize the ble interface, configure it and start advertising.
59+
*/
60+
bool start()
61+
{
62+
printf("Ble process started.\r\n");
63+
64+
if (_ble_interface.hasInitialized()) {
65+
printf("Error: the ble instance has already been initialized.\r\n");
66+
return false;
67+
}
68+
69+
_ble_interface.onEventsToProcess(
70+
makeFunctionPointer(this, &BLEProcess::schedule_ble_events)
71+
);
72+
73+
ble_error_t error = _ble_interface.init(
74+
this, &BLEProcess::when_init_complete
75+
);
76+
77+
if (error) {
78+
printf("Error: %u returned by BLE::init.\r\n", error);
79+
return false;
80+
}
81+
82+
return true;
83+
}
84+
85+
/**
86+
* Close existing connections and stop the process.
87+
*/
88+
void stop()
89+
{
90+
if (_ble_interface.hasInitialized()) {
91+
_ble_interface.shutdown();
92+
printf("Ble process stopped.");
93+
}
94+
}
95+
96+
/**
97+
* Subscription to the ble interface initialization event.
98+
*
99+
* @param[in] cb The callback object that will be called when the ble
100+
* interface is initialized.
101+
*/
102+
void on_init(mbed::Callback<void(BLE&, events::EventQueue&)> cb)
103+
{
104+
_post_init_cb = cb;
105+
}
106+
107+
private:
108+
/**
109+
* Sets up adverting payload and start advertising.
110+
*
111+
* This function is invoked when the ble interface is initialized.
112+
*/
113+
void when_init_complete(BLE::InitializationCompleteCallbackContext *event)
114+
{
115+
if (event->error) {
116+
printf("Error %u during the initialization\r\n", event->error);
117+
return;
118+
}
119+
printf("Ble instance initialized\r\n");
120+
121+
Gap &gap = _ble_interface.gap();
122+
ble_error_t error = gap.setAdvertisingPayload(make_advertising_data());
123+
if (error) {
124+
printf("Error %u during gap.setAdvertisingPayload\r\n", error);
125+
return;
126+
}
127+
128+
gap.setAdvertisingParams(make_advertising_params());
129+
130+
gap.onConnection(this, &BLEProcess::when_connection);
131+
gap.onDisconnection(this, &BLEProcess::when_disconnection);
132+
133+
start_advertising();
134+
135+
if (_post_init_cb) {
136+
_post_init_cb(_ble_interface, _event_queue);
137+
}
138+
}
139+
140+
/**
141+
* Start the gatt client process when a connection event is received.
142+
*/
143+
void when_connection(const Gap::ConnectionCallbackParams_t *connection_event)
144+
{
145+
printf("Connected.\r\n");
146+
}
147+
148+
/**
149+
* Stop the gatt client process when the device is disconnected then restart
150+
* advertising.
151+
*/
152+
void when_disconnection(const Gap::DisconnectionCallbackParams_t *event)
153+
{
154+
printf("Disconnected.\r\n");
155+
start_advertising();
156+
}
157+
158+
/**
159+
* Setup the advertising parameters.
160+
*/
161+
void setup_advertising()
162+
{
163+
Gap &gap = _ble_interface.gap();
164+
gap.setAdvertisingPayload(make_advertising_data());
165+
gap.setAdvertisingParams(make_advertising_params());
166+
}
167+
168+
/**
169+
* Start the advertising process; it ends when a device connects.
170+
*/
171+
void start_advertising()
172+
{
173+
ble_error_t error = _ble_interface.gap().startAdvertising();
174+
if (error) {
175+
printf("Error %u during gap.startAdvertising.\r\n", error);
176+
} else {
177+
printf("Advertising started.\r\n");
178+
}
179+
}
180+
181+
/**
182+
* Schedule processing of events from the BLE middleware in the event queue.
183+
*/
184+
void schedule_ble_events(BLE::OnEventsToProcessCallbackContext *event)
185+
{
186+
_event_queue.call(mbed::callback(&event->ble, &BLE::processEvents));
187+
}
188+
189+
/**
190+
* Build data advertised by the BLE interface.
191+
*/
192+
static GapAdvertisingData make_advertising_data(void)
193+
{
194+
static const uint8_t device_name[] = "GattClient";
195+
GapAdvertisingData advertising_data;
196+
197+
// add advertising flags
198+
advertising_data.addFlags(
199+
GapAdvertisingData::LE_GENERAL_DISCOVERABLE |
200+
GapAdvertisingData::BREDR_NOT_SUPPORTED
201+
);
202+
203+
// add device name
204+
advertising_data.addData(
205+
GapAdvertisingData::COMPLETE_LOCAL_NAME,
206+
device_name,
207+
sizeof(device_name)
208+
);
209+
210+
return advertising_data;
211+
}
212+
213+
/**
214+
* Build advertising parameters used by the BLE interface.
215+
*/
216+
static GapAdvertisingParams make_advertising_params(void)
217+
{
218+
return GapAdvertisingParams(
219+
/* type */ GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,
220+
/* interval */ GapAdvertisingParams::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(500),
221+
/* timeout */ 0
222+
);
223+
}
224+
225+
events::EventQueue &_event_queue;
226+
BLE &_ble_interface;
227+
mbed::Callback<void(BLE&, events::EventQueue&)> _post_init_cb;
228+
};
229+
230+
231+
#endif /* GATT_EXAMPLE_BLE_PROCESS_H_ */

BLE_GattClient/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# BLE Gatt Client example
2+
3+
This application demonstrates detailed uses of the GattClient APIs.
4+
5+
When the application is started it advertises itself to its environment with the
6+
device name `GattClient`. Once you have connected to the device with your mobile
7+
phone, the application starts a discovery of the GATT server exposed by your
8+
mobile phone.
9+
10+
After the discovery, this application reads the value of the characteristics
11+
discovered and subscribes to the characteristics emitting notifications or
12+
indications.
13+
14+
The device prints the value of any indication or notification received from the
15+
mobile phone.
16+
17+
# Running the application
18+
19+
## Requirements
20+
21+
You may use a generic BLE scanners:
22+
23+
- [nRF Master Control Panel](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp) for Android.
24+
25+
- [LightBlue](https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) for iPhone.
26+
27+
Hardware requirements are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md).
28+
29+
## Building instructions
30+
31+
Building instructions for all samples are in the [main readme](https://github.com/ARMmbed/mbed-os-example-ble/blob/master/README.md).
32+
33+

0 commit comments

Comments
 (0)