Hello:

Disclaimers:
1) Long email follows.
2) This is a preliminary version of this code. There are hard-coded things and 
things I had to hack, mainly because of my ignorance of some areas in the code. 
I pushed it so some folks (if they want) can take a look and mess around before 
things get cleaned up.

For those interested, a branch was committed today named the “bsnbranch”. For 
lack of a better term, I called this the “body sensor network” branch. This 
could be quite the misnomer as there is no actual sensor code with this commit, 
but I had to come up with a name :-)

The basic idea behind this branch is the following:

* A central wants to connect to N known peripherals.
* Each peripheral wants to connect to a known central.
* Peripherals generate “application data” at some fixed size and rate (for the 
most part). This rate is expected to be pretty fast.
* Peripherals and centrals should do their best to maintain these connections 
and if a connection is dropped, to re-connect.
* The central should allocate fixed time slots to the peripherals and guarantee 
those fixed time slots are available.

As with some of the apps in the repo, the initial commit is fairly hard-coded 
in some ways. If you look at the source code in main.c in these apps there are 
arrays which currently hold some hard-coded addresses: the public address of 
the peripheral, the public address of the central, and the addresses that the 
central wants to connect to. The application example shows a central that wants 
to connect to 5 peripherals. If you want to use the app without mods in the 
repo, you need to change BLE_MAX_CONNECTIONS to 5 when you build your central 
(in net/nimble/syscfg.yml).

The central application adds the devices in the bsncent_peer_addrs array to the 
whitelist and constantly intiates if it is not connected to all of these 
devices. The peripheral application does high-duty cycle directed advertising 
(constantly!) until it connects to the central. If a connection is dropped the 
central and/or peripheral start initiating/advertising until the connection is 
re-established. NOTE: there is no delay between the high-duty cycle advertising 
attempts currently so beware of that if you are running your peripheral on a 
battery!

The central currently uses a hard-coded connection interval of 13 (16.25 
msecs). More on this later. The peripheral attempts to send approx an 80-byte 
packet at a rate close to this connection interval. That timing is based on os 
ticks so it is not perfect, so if folks want more accurate timing something 
else would need to be done.

The central also display some basic performance numbers on the console at a 
10-second interval: # of connections, total packets received, total bytes 
received, and the pkts/sec and bytes/sec over the last 10 second interval.

While I was testing this setup (5 peripherals, one central) I ran into some 
resource issues. I cannot claim to know the host code all that well, but here 
are the items that I modified to get this to work. Some of these may not be 
necessary since I did not test them in all their various combinations and some 
may have no impact at all.

NOTE: these changes are not in the branch btw. They need to be modified by 
either changing a syscfg value or hacking the code. I realize hacking the code 
is quite undesirable but it was not obvious how to do this with syscfg and my 
lack of understanding of the code prevented me from doing something more 
elegant. The items in CAPS are syscfg variables. Changing them in your target 
is a good way to change there.

1) Mbufss at the central. I modified the number of mbufs and their size. I used 
24 mbufs with a size of 128. Not sure how many you actually need, but did not 
run out of mbufs with this setting.
    MSYS_1_BLOCK_COUNT: 24
    MSYS_1_BLOCK_SIZE: 128
2) BLE_GATT_MAX_PROCS: I increased this to 8 for the central.
3) BLE_MAX_CONNECTIONS: I made this 5 for the central. NOTE: 32 is the maximum 
# of connections supported here. If you use more, the code does not complain 
and the behavior will be unpredicatable.
4) I hacked the code to add more the ble_att_svr_entry_pool. I multiplied the 
number by 2 (ble_hs_max_attrs * 2).
5) I believe I added 12 to the ble_gatts_clt_cfg_pool but not sure this is 
needed.
6) Enabled data length extension by setting BLE_LL_CONN_INIT_MAX_TX_BYTES to 
251. This number could be made less but for now I made it the full size. This 
is for both central and peripheral.
 
SCHEDULER CHANGES:
A large part of the changes to the controller involve how connections get 
scheduled. There are three configuration items that can be modified, and need 
to be modified, for this code to work. I realize I committed this with some 
default numbers that probably should be turned off when we merge this into 
develop, but for now realize these numbers are based on the connection interval 
that the central uses (16.25 msecs) and 5 connections

BLE_LL_STRICT_CONN_SCHEDULING: This is basically a flag that turns on/off this 
form of scheduling for the central (boolean value 0 or 1).
BLE_LL_ADD_STRICT_SCHED_PERIODS: Adds additional periods to the epoch (see more 
below). Default 0
BLE_LL_USECS_PER_PERIOD: The number of usecs per period (see more below). 
Default 3250

The terminology used above is pretty simple. The central divides time into 
epochs. Each epoch is composed of N periods. The number of periods is the 
number of connections plus the number of BLE_LL_ADD_STRICT_SCHED_PERIODS. The 
connection interval should then be made to equal the epoch length. I realize 
that some of this could have been calculated a bit more easily and with less 
configuration; those changes will be added soon. Hopefully you see the basic 
idea: you want to use a connection interval such that each period repeats in 
each epoch. Connections gets assigned to a period and they keep that period in 
each epoch. As long as the connection interval is a multiple of the epoch 
length, you should be fine. For example, if you want 6 connections and want a 
30 msec connection interval, you can make each period 5 msecs. Realize that 
once you fill up all the periods you will not be able to do anything else. 
Currently, we really do not support advertising on the central. Well, you can 
do it, but the scheduler has not been modified to deal with advertising and 
your mileage will certainly vary! The BLE_LL_ADD_STRICT_SCHED_PERIODS is some 
attempt at reserving some time in the epoch to do other things. Certainly, you 
can scan/initiate, but the scan window/interval is currently not forced to 
occur on any particular period boundary, so generally it is expected that your 
scan window will equal your scan interval (and thus scanning will occur 
whenever the device is not inside a connection event).

I realize that this email glosses over some items and really requires folks to 
dive into things a bit to fully understand. I would be happy to answer 
questions about the code. I am not quite sure it is truly “ready for prime 
time” as there are some items that still need to be dealt with but it should 
work reasonably well for now.

Thanks!

Reply via email to