mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 09:35:42 +00:00
draft of LE Central example
This commit is contained in:
parent
35697e8afc
commit
69308c9e60
@ -0,0 +1,5 @@
|
||||
# Examples
|
||||
|
||||
In this section, we will describe a number of examples that are available
|
||||
from inside the Arduino IDE via File->Examples->BTstack.
|
||||
|
@ -1,11 +1,33 @@
|
||||
|
||||
#include <BTstack.h>
|
||||
#include <SPI.h>
|
||||
|
||||
/*
|
||||
* EXAMPLE_START(LECentral): LE Central
|
||||
*
|
||||
* @text Compared with the other examples, the LE Central is
|
||||
* a bit more complex. This is because it performs multiple
|
||||
* steps in sequence as it is common with GATT Client APIs.
|
||||
*
|
||||
* It shows how to first scan for other
|
||||
* devices and then connect to one. When connected, a series of
|
||||
* GATT Client operations are performed: first the list of
|
||||
* GATT Services is queried. If a particular service is found,
|
||||
* the list of its GATT Characteristics is retrieved and a set
|
||||
* of known Characteristics are cached for later access.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @section Characteristic Summary
|
||||
* @text As multiple Characteristics need to be found, a custom
|
||||
* struct is used to collect all information about it. This allows
|
||||
* to defined the list of neccessary characteristics in the
|
||||
* characteristics[] array
|
||||
*/
|
||||
/* LISTING_START(LECentralSummary): Characteristic Summary */
|
||||
|
||||
// BLE Shield Service V2 incl. used Characteristics
|
||||
UUID bleShieldServiceV2UUID("B8E06067-62AD-41BA-9231-206AE80AB550");
|
||||
|
||||
typedef struct characteristic_summary {
|
||||
UUID uuid;
|
||||
const char * name;
|
||||
@ -28,8 +50,7 @@ characteristic_summary characteristics[] = {
|
||||
{ UUID("65c228da-bad1-4f41-b55f-3d177f4e2196"), "BD ADDR" }
|
||||
};
|
||||
|
||||
// BLE Shield Service V2 incl. used Characteristics
|
||||
UUID bleShieldServiceV2UUID("B8E06067-62AD-41BA-9231-206AE80AB550");
|
||||
/* LISTING_END(LECentralSummary): Characteristic Summary */
|
||||
|
||||
// Application state
|
||||
BLEDevice myBLEDevice;
|
||||
@ -42,10 +63,14 @@ char counterString[20];
|
||||
|
||||
static timer_source_t heartbeat;
|
||||
|
||||
void setup(void){
|
||||
|
||||
/*
|
||||
* @section Setup
|
||||
* @text In the setup, various callbacks are registered. After that
|
||||
* we start scanning for other devices
|
||||
*/
|
||||
/* LISTING_START(LECentralSetup): LE Central Setup */
|
||||
void setup(void){
|
||||
Serial.begin(9600);
|
||||
|
||||
BTstack.setBLEAdvertisementCallback(advertisementCallback);
|
||||
BTstack.setBLEDeviceConnectedCallback(deviceConnectedCallback);
|
||||
BTstack.setBLEDeviceDisconnectedCallback(deviceDisconnectedCallback);
|
||||
@ -55,13 +80,21 @@ void setup(void){
|
||||
BTstack.setGATTCharacteristicReadCallback(gattReadCallback);
|
||||
BTstack.setGATTCharacteristicWrittenCallback(gattWrittenCallback);
|
||||
BTstack.setGATTCharacteristicSubscribedCallback(gattSubscribedCallback);
|
||||
|
||||
BTstack.setup();
|
||||
|
||||
BTstack.bleStartScanning();
|
||||
}
|
||||
/* LISTING_END(LECentralSetup): LE Central Setup */
|
||||
|
||||
|
||||
/*
|
||||
* @section Loop
|
||||
*
|
||||
* @text In the standard Arduino loop() function, BTstack's loop() is called first
|
||||
* If we're connected, we send the string "BTstack" plus a counter as fast as possible.
|
||||
* As the Bluetooth module might be busy, it's important to check the result of the
|
||||
* writeCharacteristicWithoutResponse() call. If it's not ok, we just try again in the
|
||||
* next loop iteration.
|
||||
*/
|
||||
/* LISTING_START(LECentralLoop): Loop */
|
||||
void loop(void){
|
||||
BTstack.loop();
|
||||
|
||||
@ -76,7 +109,20 @@ void loop(void){
|
||||
}
|
||||
}
|
||||
}
|
||||
/* LISTING_END(LECentralLoop): Loop */
|
||||
|
||||
/*
|
||||
* @section Advertisement Callback
|
||||
*
|
||||
* @text When an Advertisement is received, we check if it contains
|
||||
* the UUID of the service we're interested in. Only a single service
|
||||
* with a 128-bit UUID can be contained in and Advertisement and not
|
||||
* all BLE devices provides this. Other options are to match on the
|
||||
* reported device name or the BD ADDR prefix.
|
||||
*
|
||||
* If we found an interesting device, we try to connect to it.
|
||||
*/
|
||||
/* LISTING_START(LECentralAdvertisementCallback): Advertisement Callback */
|
||||
void advertisementCallback(BLEAdvertisement *bleAdvertisement) {
|
||||
Serial.print("Device discovered: ");
|
||||
Serial.print(bleAdvertisement->getBdAddr()->getAddressString());
|
||||
@ -88,7 +134,18 @@ void advertisementCallback(BLEAdvertisement *bleAdvertisement) {
|
||||
BTstack.bleConnect(bleAdvertisement, 10000); // 10 s
|
||||
}
|
||||
}
|
||||
/* LISTING_END(LECentralAdvertisementCallback): Advertisement Callback */
|
||||
|
||||
/*
|
||||
* @section Device Connected Callback
|
||||
*
|
||||
* @text At the end of bleConnect(), the device connected callback is callec.
|
||||
* The status argument tells if the connection timed out, or if the connection
|
||||
* was established successfully.
|
||||
*
|
||||
* On a successful connection, a GATT Service Discovery is started.
|
||||
*/
|
||||
/* LISTING_START(LECentralDeviceConnectedCallback): Device Connected Callback */
|
||||
void deviceConnectedCallback(BLEStatus status, BLEDevice *device) {
|
||||
switch (status){
|
||||
case BLE_STATUS_OK:
|
||||
@ -105,13 +162,34 @@ void deviceConnectedCallback(BLEStatus status, BLEDevice *device) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* LISTING_END(LECentralDeviceConnectedCallback): Device Connected Callback */
|
||||
|
||||
/*
|
||||
* @section Device Disconnected Callback
|
||||
*
|
||||
* @text If the connection to a device breaks, the device disconnected callback
|
||||
* is called. Here, we start scanning for new devices again.
|
||||
*/
|
||||
/* LISTING_START(LECentralDeviceDisconnectedCallback): Device Disconnected Callback */
|
||||
void deviceDisconnectedCallback(BLEDevice * device){
|
||||
Serial.println("Disconnected, starting over..");
|
||||
sendCounter = false;
|
||||
BTstack.bleStartScanning();
|
||||
}
|
||||
/* LISTING_END(LECentralDeviceDisconnectedCallback): Device Disconnected Callback */
|
||||
|
||||
/*
|
||||
* @section Service Discovered Callback
|
||||
*
|
||||
* @text The service discovered callback is called for each service and after the
|
||||
* service discovery is complete. The status argument is provided for this.
|
||||
*
|
||||
* The main information about a discovered Service is its UUID.
|
||||
* If we find our service, we store the reference to this service.
|
||||
* This allows to discover the Characteristics for our service after
|
||||
* the service discovery is complete.
|
||||
*/
|
||||
/* LISTING_START(LECentralServiceDiscoveredCallback): Service Discovered Callback */
|
||||
void gattServiceDiscovered(BLEStatus status, BLEDevice *device, BLEService *bleService) {
|
||||
switch(status){
|
||||
case BLE_STATUS_OK:
|
||||
@ -134,7 +212,21 @@ void gattServiceDiscovered(BLEStatus status, BLEDevice *device, BLEService *bleS
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* LISTING_END(LECentralServiceDiscoveredCallback): Service Discovered Callback */
|
||||
|
||||
/*
|
||||
* @section Characteristic Discovered Callback
|
||||
*
|
||||
* @text Similar to the Service Discovered callback, the Characteristic Discovered
|
||||
* callback is called for each Characteristic found and after the discovery is complete.
|
||||
*
|
||||
* The main information is again its UUID. If we find a Characteristic that we're
|
||||
* interested in, it's name is printed and a reference stored for later.
|
||||
*
|
||||
* On discovery complete, we subscribe to a particular Characteristic to receive
|
||||
* Characteristic Value updates in the Notificaation Callback.
|
||||
*/
|
||||
/* LISTING_START(LECentralCharacteristicDiscoveredCallback): Characteristic Discovered Callback */
|
||||
void gattCharacteristicDiscovered(BLEStatus status, BLEDevice *device, BLECharacteristic *characteristic) {
|
||||
switch(status){
|
||||
case BLE_STATUS_OK:
|
||||
@ -165,22 +257,63 @@ void gattCharacteristicDiscovered(BLEStatus status, BLEDevice *device, BLECharac
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* LISTING_END(LECentralCharacteristicDiscoveredCallback): Characteristic Discovered Callback */
|
||||
|
||||
/*
|
||||
* @section Subscribed Callback
|
||||
*
|
||||
* @text After the subcribe operation is complete, we get notified if it was
|
||||
* successful. In this example, we read the Characteristic that contains the
|
||||
* BD ADDR of the other device. This isn't strictly neccessary as we already
|
||||
* know the device address from the Advertisement, but it's a common pattern
|
||||
* with iOS as the device address is hidden from applications.
|
||||
*/
|
||||
/* LISTING_START(LECentralSubscribedCallback): Subscribed Callback */
|
||||
void gattSubscribedCallback(BLEStatus status, BLEDevice * device){
|
||||
device->readCharacteristic(&characteristics[charBdAddr].characteristic);
|
||||
}
|
||||
/* LISTING_END(LECentralSubscribedCallback): Subscribed Callback */
|
||||
|
||||
/*
|
||||
* @section Read Callback
|
||||
*
|
||||
* @text The Read callback is called with the result from a read operation.
|
||||
* Here, we write to the TX Characteristic next.
|
||||
*/
|
||||
/* LISTING_START(LECentralReadCallback): Read Callback */
|
||||
void gattReadCallback(BLEStatus status, BLEDevice *device, uint8_t *value, uint16_t length) {
|
||||
Serial.print("Read callback: ");
|
||||
Serial.println((const char *)value);
|
||||
device->writeCharacteristic(&characteristics[charTX].characteristic, (uint8_t*) "Hello!", 6);
|
||||
}
|
||||
/* LISTING_END(LECentralReadCallback): Read Callback */
|
||||
|
||||
/*
|
||||
* @section Written Callback
|
||||
*
|
||||
* @text After the write operation is complete, the Written Callback is callbed with
|
||||
* the result in the status argument. As we're done with the initial setup of the remote
|
||||
* device, we set the flag to write the test string as fast as possible.
|
||||
*/
|
||||
/* LISTING_START(LECentralWrittenCallback): Written Callback */
|
||||
void gattWrittenCallback(BLEStatus status, BLEDevice *device){
|
||||
sendCounter = true;
|
||||
}
|
||||
/* LISTING_END(LECentralWrittenCallback): Written Callback */
|
||||
|
||||
/*
|
||||
* @section Notification Callback
|
||||
*
|
||||
* @text Notifictions for Characteristic Value Updates are delivered via the
|
||||
* Notification Callback. When more than one Characteristic is subscribed,
|
||||
* the value handle can be used to distinguish between them. The
|
||||
* BLECharacteristic.isValueHandle(int handle) allows to test if a value handle
|
||||
* belongs to a particular Characteristic.
|
||||
*/
|
||||
/* LISTING_START(LECentralNotificationCallback): Notification Callback */
|
||||
void gattCharacteristicNotification(BLEDevice *device, uint16_t value_handle, uint8_t *value, uint16_t length) {
|
||||
Serial.print("Notification: ");
|
||||
Serial.println((const char *)value);
|
||||
}
|
||||
/* LISTING_END(LECentralNotificationCallback): Notification Callback */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user