Skip to content

Commit 009cf48

Browse files
authored
Advertisement Publisher and filters (#78)
1 parent 99d1dcc commit 009cf48

27 files changed

+1489
-224
lines changed

README.md

Lines changed: 110 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ Bluetooth is currently only supported on ESP32 devices with following firmware.
2727

2828
- ESP32_BLE_REV0
2929
- ESP32_BLE_REV3
30+
- ESP32_PSRAM_BLE_GenericGraphic_REV3
31+
- ESP32_S3_BLE
3032
- M5Core2
3133
- LilygoTWatch2021
3234
- ESP32_ETHERNET_KIT_1.2
3335

34-
This restriction is due to IRAM memory space in the firmware image.
35-
With revision 1 of ESP32 devices, the PSRAM implementation requires a large number of PSRAM library fixes which greatly reduces the
36+
The Bluetooth is not in every firmware due to a restriction in the IRAM memory space in the firmware image.
37+
For earlier revision 1 ESP32 devices, the PSRAM implementation required a large number of PSRAM library fixes which greatly reduces the
3638
available space in the IRAM area, so PSRAM is currently disabled for ESP32_BLE_REV0. With the revision 3 devices the Bluetooth and
3739
PSRAM are both available.
3840

@@ -52,17 +54,15 @@ A number of Bluetooth LE samples are available in the [nanoFramework samples rep
5254

5355
### Overview
5456

55-
This implementation supports a cut down version of the Gatt Server and Gatt Client implementation.
57+
This implementation supports a cut down version of the Gatt Server and Gatt Client implementations.
5658

5759
The device can either run as a Server or Client, but not at the same time.
58-
For example if you start a Watcher to look for advertisements from Server devices you will not
59-
be able to connect to those devices until the Watcher has been stopped. But you can receive data from connected
60-
devices while Watcher is scanning.
6160

6261
For more information see relevant sections: -
6362

6463
- [Gatt Server](#gatt-server)
6564
- [Gatt Client / Central](#gatt-client-central)
65+
- [Advertisement Publishing](#advertisement-publishing)
6666

6767
Also as part of this assembly is the NordicSPP class which implements a Serial Protocol Profile based on
6868
the Nordic specification. This allows clients to easily connect via Bluetooth LE to send and receive messages via a
@@ -75,7 +75,7 @@ called GUID in .Net and UUID in the Bluetooth specifications.
7575

7676
If the attribute is standard UUID defined by the Bluetooth SIG, it will also have a corresponding 16-bit short ID (for example,
7777
the characteristic **Battery Level** has a UUID of 00002A19-0000-1000-8000-00805F9B34FB and the short ID is 0x2A19).
78-
The common standard UUIDs can be seen in GattServiceUuids and GattCharacteristicUuids.
78+
The common standard UUIDs can be seen in the classes GattServiceUuids and GattCharacteristicUuids.
7979

8080
If the short ID is not present in GattServiceUuids or GattCharacteristicUuids then create your own short GUID by
8181
calling the utility function CreateUuidFromShortCode.
@@ -332,8 +332,22 @@ private static void _notifyCharacteristic_SubscribedClientsChanged(GattLocalChar
332332
## Advertising your service
333333

334334
Once all the Characteristics have been created you need to advertise the Service so other devices can see it
335-
and/or connect to it. We also provide the device name seen on the discovery.
335+
and/or connect to it.
336336

337+
As part of the ServiceProvider we add the following data sections to the advertisement
338+
payload automatically.
339+
340+
* Flags
341+
* Complete Local Name
342+
* UUID of service defined on provider.
343+
* ServiceData ( Optional )
344+
345+
An extension for nanoFramework allows the advertisement to be added to by adding data sections to
346+
the Advertisement property of the GattServiceProviderAdvertisingParameters object.
347+
Also by setting the GattServiceProviderAdvertisingParameters.CustomAdvertisement flag all data sections can
348+
be set up by the user.
349+
350+
### Starting the advertisement.
337351
```csharp
338352
serviceProvider.StartAdvertising(new GattServiceProviderAdvertisingParameters()
339353
{
@@ -366,18 +380,57 @@ When a advertisement is received an event will be raised calling the Watcher_Rec
366380
In the event handler you will be able to select a device using the information supplied on the event.
367381
This could be device LocalName or other data supplied in the advertisement data.
368382

383+
If you start a Watcher to look for advertisements from Server devices you will not
384+
be able to connect to those devices until the Watcher has been stopped, but you can receive data from connected
385+
devices while Watcher is scanning. So the Watcher needs to be stopped while connections are being made to servers.
386+
369387
See samples for more information.
370388

371389
Filters can be added to the BluetoothLEAdvertisementWatcher.
372-
Currently this is just an RSSI filter so Advertisements are only received from devices within a certain signal strength.
390+
THere are 2 filters available:-
391+
* RSSI filter - Advertisements are only received from devices within a certain signal strength.
392+
* Advertisement Filter - Advertisements are filtered by the contents of the advertisement.
373393

374-
RSSI filter
394+
### RSSI filter
375395
```csharp
376396
watcher.SignalStrengthFilter.InRangeThresholdInDBm = -70;
377397
watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -77;
378398
watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(10000);
379399
```
380400

401+
### Advertisements Filter
402+
403+
Advertisements are only received from devices which match the data sections or part of a data section contained in the filter.
404+
405+
Update the advertisement object with data sections for the filter to match against.
406+
There are some properties on object for common data sections. For other data sections load the "dataSections" arrayList property with the data sections required to match.
407+
408+
Using a property to match a local name of device.
409+
Only adverts from devices with a local name of "Sample" will be received.
410+
```csharp
411+
watcher.AdvertisementFilter.Advertisement.LocalName = "Sample";
412+
```
413+
414+
This filter uses a partial match of part of data section.
415+
Select all Advertisements with an "a" in 2nd position of Local name
416+
417+
If you want to filter on part of a data section then use the BytePatterns arrayList.
418+
```csharp
419+
BluetoothLEAdvertisementBytePattern pattern = new BluetoothLEAdvertisementBytePattern()
420+
{
421+
DataType = (byte)BluetoothLEAdvertisementDataSectionType.CompleteLocalName,
422+
Data = new Buffer(new Byte[] { (Byte)'a' }),
423+
Offset = 1
424+
};
425+
426+
watcher.AdvertisementFilter.BytePatterns.Add(pattern2;
427+
```
428+
429+
Any data thats contained in an advertisement can be filtered on.
430+
Advertisement and byte patterns can be used together.
431+
432+
For more examples of advertisement filters see the Watcher filter sample.
433+
381434
## Creating a device and connecting to device.
382435

383436
To communicate with a device a BluetoothLEDevice class needs to be created using the devices Bluetooth address and type.
@@ -738,6 +791,53 @@ private static void Pairing_PairingComplete(object sender, DevicePairingEventArg
738791
}
739792
```
740793

794+
# Advertisement Publishing
795+
796+
The BluetoothLEAdvertisementPublisher class allows the configuration and advertising of a Bluetooth LE advertisement packet.
797+
The payload of the advertisement is configured when the class is constructed via the BluetoothLEAdvertisement class.
798+
799+
The BluetoothLEAdvertisement class is used to control exactly what the advertisement packet contains and is mainly
800+
used to create beacons.
801+
802+
The advertisement is constructed by adding BluetoothLEAdvertisementDataSection to the BluetoothLEAdvertisement class.
803+
For some common Data Sections there are properties on the BluetoothLEAdvertisement class which automatically add the correct
804+
data section to advertisement. i.e. LocalName, Flags
805+
806+
Once the BluetoothLEAdvertisementPublisher class has been constructed the advertising can be started or stopped with
807+
the Start() and Stop() methods.
808+
809+
## Creating an advertisement packet
810+
For legacy advertisements the packet length is 31 bytes which includes all data sections.
811+
Each data section is 1 byte for length, 1 byte for section type and the data bytes. Any data section that
812+
doesn't fit in advertisement will be moved to the scan response or left off it no room.
813+
814+
Currently we don't support extended advertisement. This will be available in future release.
815+
816+
817+
```csharp
818+
BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();
819+
820+
// Add Flags using property
821+
publisher.Advertisement.Flags = BluetoothLEAdvertisementFlags.GeneralDiscoverableMode |
822+
BluetoothLEAdvertisementFlags.DualModeControllerCapable |
823+
BluetoothLEAdvertisementFlags.DualModeHostCapable;
824+
825+
// Adding flags using Data Sections
826+
publisher.Advertisement.
827+
828+
```
829+
830+
831+
## Starting and Stopping Publisher
832+
Advertise for 1 minute.
833+
```csharp
834+
publisher.Start();
835+
836+
Thread.Sleep(60000);
837+
838+
publisher.Stop();
839+
```
840+
741841

742842

743843

Tests/Client/Program.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,9 @@ public static void Main()
156156
EnvService.UpdateValue(iTempOutMin, t3);
157157
Thread.Sleep(5000);
158158
}
159-
160159
}
161160

162-
163161
Thread.Sleep(Timeout.Infinite);
164162
}
165-
166-
// Receive test commands
167-
private static void Test_CommandRX(TestService sender, string args)
168-
{
169-
170-
}
171163
}
172164
}

0 commit comments

Comments
 (0)