Connection Monitor (CM) Examples Guide

Table of Contents

Introduction

The Connection Monitor (CM) project utilizes the monitor role from the TI Micro BLE Stack (uBLE-Stack) to collect connection data from external BLE connections without having to formally participate in a BLE connection. The monitor role is not an official BLE Specification defined role. It is designed to follow an active BLE connection given the following parameters:

  1. Access address
  2. Connection Interval
  3. Hop Increment Value
  4. Channel Map
  5. Master Sleep Clock Accuracy (mSCA)

The connection monitor performs an initial scan and listens on a data channel to capture a packet and establish an anchor point for the specified connection. Once established, it will continue to monitor the connection by capturing the master and slave packets involved in the connection. It is able to return information such as the respective packet’s RSSI value and timestamp.

For more information on the TI Micro BLE Stack see BLE-Stack User’s Guide for Bluetooth 4.2.

There are two projects/configurations:

App Build Configuration Description
CM_FlashOnly_MultiMode Base application showing how to use Micro BLE Stack in the Connection Monitor Role
uNPI_CM_FlashOnly_MultiMode Same as the CM_FlashOnly_MultiMode project, with unified NPI built in to receive data from a host

The CM_FlashOnly_MultiMode (embedded) configuration requires the Connection Information parameters to be hard-coded into the Connection Monitor project, while the uNPI_CM_FlashOnly_MultiMode configuration uses uNPI (unified NPI) to receive the Connection Information parameters from the host.

Due to having a large delay from establishing the connection to inputting the connection information parameters, the CM_FlashOnly_MultiMode configuration’s initial scan is on a set data channel. This is currently on data channel 0. The uNPI_CM_FlashOnly_MultiMode configuration has the benefit of having the Connection Information parameters provided near instantly on connection establishment. This means it uses the current data channel that the connection was established on to quickly establish an anchor point.

Limitations

The current implementation of the Connection Monitor is designed only for the LAUNCHXL-CC2640R2 with the following limitations:

Hardware Prerequisites

Both CM_FlashOnly_MultiMode and uNPI_CM_FlashOnly_MultiMode is designed to use LAUNCHXL-CC2640R2.

2 additional LAUNCHXL-CC2640R2 will be required to create a connection to monitor. One of these launchpads will be running host_test or simple_central to act as a central. Another LaunchPad will be flashed with simple_peripheral to act as a peripheral for host_test to connect to. This can be replaced with another peripheral, such as a phone.

Software Prerequisites

For information on what versions of Code Composer Studio and IAR Embedded Workbench to use, see the Release Notes located in the docs/blestack folder. For information on how to import this project into your IDE workspace and build/run, please refer to The CC2640R2F Platform section in the BLE-Stack User’s Guide for Bluetooth 4.2.

In order to utilize ‘npi_cm_host.py’ for the uNPI_CM_FlashOnly_MultiMode configuration you will need a valid installation of

Required Python Modules

The ‘npi_cm_host.py’ script utilizes modules that need to be installed

The ‘requirements.txt’ contains a list of the modules required; can be used with

pip install -r requirements.txt

‘requirements.txt’ and ‘npi_cm_host.py’ are located in

/tools/blestack/connection_monitor/

Usage

Setup and User Guide For uNPI_CM_FlashOnly_MultiMode

Set Up

The uNPI_CM_FlashOnly_MultiMode project utilizes the UART peripheral through unified NPI. This requires the computer to be connected to the LaunchPad through USB. Flash uNPI_CM_FlashOnly_MultiMode project onto a LaunchPad and connect it the computer.

Flash another LaunchPad with the host_test project, connect this LaunchPad to the computer.

Each LaunchPad connected to the computer will enumerate as 2 COM ports. Always use the port labeled as “XDS110 Class Application/User UART”, this interfaces Application UART.

Take note of which COM port belongs to the LaunchPad running uNPI_CM_FlashOnly_MultiMode and which COM port belongs to the LaunchPad running host_test.

Optionally, if using a third LaunchPad as a peripheral - flash the final LaunchPad with simple_peripheral. After flashing is completed, record the Bluetooth Device Address. This can be found in the UART terminal. Once the Bluetooth Device Address is noted the LaunchPad is only required to be powered, no need to connect to the computer through the debugger.

Running the Script Manually with No Arguments

Some modifications to ‘npi_cm_host.py’ are required prior to running the project. These modifications are to configure the script to control the correct devices and connect host_test to the right peripheral.

  1. Update ‘host_port’ with the COM Port of the LaunchPad running host_test.
  2. Update ‘cm_port’ with the COM Port of the LaunchPad running uNPI_CM_FlashOnly_MultiMode.
  3. Update ‘strPeerAddress’ with the Bluetooth Device Address of the peripheral to be connected to.
  4. Run the script using Python. This requires calling the python executable with the path to ‘npi_cm_host.py’ passed in as an argument.
if __name__ == '__main__':
    global peerAddrs
    version_control()
    rtn_args = parse_args()

if(len(sys.argv) < 4):
    print '\nUsing Default Hardcoded Values: '
    print 'or enter 3 default(cm_port host_port peerAddress) arguments.'
    print 'See -h help.\n'
    #set your own hard coded com ports
    host_port = 'COM104'
    cm_port     = 'COM105'
    strPeerAddress = '0xB0912265CBE2'
C:\Python27\python.exe [sdk]\tools\blestack\connection_monitor\npi_cm_host.py

Note ‘sdk’ refers to the Software Development Kit installation directory.

The script will send commands to the LaunchPad running host_test to act as a central device and connect to the peripheral. Then it will query the central for the current connection parameters. Finally it will launch the connection monitor with the retrieved connection parameters. A continuous stream of RSSI data and timestamps from the connection monitor of master and slave devices at each connection event will appear in the terminal after a short delay. The default connection interval of connection events is 100ms.

Running the Python Script or Executable with Command Line arguments

To run the script without editing the python code, the configuration information can be passed into the script as arguments. An executable is also provided, allow the user to utilize uNPI_CM_FlashOnly_MultiMode project without having Python installed. Similar to the python script, arguments need to passed in when being invoked.

The arguments are expected to be in the following order:

Argument 1 Argument 2 Argument 3
CM COM PORT host_test COM PORT Peripheral Bluetooth Address
[sdk]\tools\blestack\connection_monitor\npi_cm_host.exe COM4 COM5 0xB0912265CBE2

Or alternatively the same command line will also work with a direct call to the python script.

C:\Python27\python.exe [sdk]\tools\blestack\connection_monitor\npi_cm_host.py COM4 COM5 0xB0912265CBE2

Note ‘sdk’ refers to the Software Development Kit installation directory.

The script will send commands to the LaunchPad running host_test to act as a central device and connect to the peripheral. Then it will query the central for the current connection parameters. Finally it will launch the connection monitor with the retrieved connection parameters. A continuous stream of RSSI data and timestamps from the connection monitor of master and slave devices at each connection event will appear in the terminal after a short delay. The default connection interval of connection events is 100ms.

Additional Information

The script ‘npi_cm_host.py’ contains in-line comments - these comments describe script behavior.

Setup and User Guide For CM_FlashOnly_MultiMode

Set Up

CM_FlashOnly_MultiMode does not utilize unified NPI, thus has no transport layer interface to the UART Module. In order to configure the connection monitor, connection parameters must be manually placed into application code and compiled. Connect a LaunchPad which will be flashed with CM_FlashOnly_MultiMode to the computer. This will be the Connection Monitor LaunchPad.

Another LaunchPad will be acting as a central device. Flash this LaunchPad with simple_central and connect to it’s COM Port using a serial terminal emulator such as Putty. See Simple Central Guide for instructions on how to utilize and get the project working.

Optionally, if using a third LaunchPad as a peripheral - flash this final LaunchPad with simple_peripheral. After flashing is completed, record the Bluetooth Device Address. This can be found in the UART terminal. Once the Bluetooth Device Address is noted, the LaunchPad is only required to be powered, no need to connect to the computer through the debugger.

Form a connection between the simple_central and simple_peripheral through the simple_central’s two button interface. In other words, scan for devices, and connect to the advertising simple_peripheral by verifying the Bluetooth Device Address noted earlier.

Once a connection is formed, use the ‘Connection Info’ menu option to extract the Connection Information required by the Connection Monitor. Ensure that the connection is maintained.

Open the CM_FlashOnly_MultiMode project; in the ‘micro_cm_demo.c’ source file, the ‘MicroCmDemo_init’ function, input the Connection Information retrieved, such as the Access Address, Connection Interval, and Hop Value.

/* Initialize Connection Monitor */
if (ubCm_init() == true)
{
    /*
     * The ubCM_Start() is called here to kick off CM sessions as a demo.
     * This API should be called from host uNPI once the uNPI host
     * if available. The currentStartTime, access address, and scan duration
     * are hard-coded. They should be provided by the host. In this demo, the
     * very first ubCM_start() call will cover UB_MAX_MONITOR_DURATION.
     */
    ubCMConnInfo.ArrayOfConnInfo[0].accessAddr = 0x87318ba3;
    ubCMConnInfo.ArrayOfConnInfo[0].currentStartTime = 0;
    ubCMConnInfo.ArrayOfConnInfo[0].nextStartTime = RF_getCurrentTime() + 100 * BLE_TO_RAT;
    ubCMConnInfo.ArrayOfConnInfo[0].scanDuration = UB_MAX_MONITOR_DURATION; // 40.96s
    ubCMConnInfo.ArrayOfConnInfo[0].connInterval = 1600;
    ubCMConnInfo.ArrayOfConnInfo[0].hopValue = 15;
    ubCMConnInfo.ArrayOfConnInfo[0].combSCA = 90; // Master+Slave = 50+40
    ubCMConnInfo.ArrayOfConnInfo[0].chanMap[0] = 0xFF;
    ubCMConnInfo.ArrayOfConnInfo[0].chanMap[1] = 0xFF;
    ubCMConnInfo.ArrayOfConnInfo[0].chanMap[2] = 0xFF;
    ubCMConnInfo.ArrayOfConnInfo[0].chanMap[3] = 0xFF;
    ubCMConnInfo.ArrayOfConnInfo[0].chanMap[4] = 0x1F;

Build the project and flash the Connection Monitor LaunchPad with the updated CM_FlashOnly_MultiMode project.

Observing the Monitored Information

Open Putty on the computer, and connect to the “XDS110 Class Application/User UART” COM Port that corresponds to the Connection Monitor LaunchPad. After about 40 seconds RSSI and timestamp information should appear as the Connection Monitor LaunchPad following the connection between the central and the peripheral.

Keeping Track of the Connection

ubCM_ConnInfo_t struct

The following is the main struct that keeps track of the values required to monitor a connection and also stores the information gathered from a scanned packet:

typedef struct
{
  uint8_t   sessionId;                           //! Number 1-255 assigned as they are created identifying each connection monitor session
  uint8_t   timesScanned;                        //! track count of recent events monitored to determine next priority CM session to avoid starvation
  uint8_t   timesMissed;                         //! missed count of recent events monitored
  uint32_t  accessAddr;                          //! return error code if failed to get conn info
  uint16_t  connInterval;                        //! connection interval time, range 12 to 6400 in  625us increments (7.5ms to 4s)
  uint16_t  scanDuration;                        //! Required scan window to capture minimum of 1 packet from Master and Slave up to max possible packet size
  uint8_t   hopValue;                            //! Hop value for conn alg 1, integer range (5,16)
  uint16_t  combSCA;                             //! mSCA + cmSCA
  uint8_t   prevChan;                            //! previous channel
  uint8_t   currentChan;                         //! current data channel
  uint8_t   nextChan;                            //! next data channel
  uint8_t   chanMap[CM_NUM_BYTES_FOR_CHAN_MAP];  //! bitmap of used channels, use to reconstruct chanTableMap
  uint8_t   masterAddress[CM_DEVICE_ADDR_LEN];   //! BLE address of connection master
  uint8_t   slaveAddress[CM_DEVICE_ADDR_LEN];    //! BLE address of connection slave
  uint8_t   rssiMaster;                          //! last Rssi value master
  uint8_t   rssiSlave;                           //! last Rssi value slave
  uint32_t  timeStampMaster;                     //! last timeStamp master
  uint32_t  timeStampSlave;                      //! last timeStamp slave
  uint32_t  currentStartTime;                    //! Current anchor point
  uint32_t  nextStartTime;                       //! Record next planned scan anchor point to compare with competing CM sessions
  uint32_t  timerDrift;                          //! Clock timer drift
} ubCM_ConnInfo_t;

Generally, these members should not be modified as they are already being self-maintained by the connection monitor.

However, in the case that fine tuning is needed for the scan window the following should be understood:

For the scans after the initial scan, ubCM_setupNextCMEvent() of micro_ble_cm.c updates the scanDuration, currentStartTime, nextStartTime, and the currentChan.

These members are in the units of RAT (Radio Timer) ticks. The conversion from milliseconds to RAT ticks is as follows: x ms/ 0.625 ms = RAT ticks where x is the desired time in ms.

The scanDuration takes account for timing factors such as the timerDrift, the Radio RX Settle Time, and other processing delays. If an increase or decrease to the scan length is needed, adjust scanDuration accordingly.

The currentStartTime determines where the scan will begin. It is determined by the anchor point from the last Master packet’s timestamp and shifts that timestamp forward based on the connInterval multiplied by how many connection events have passed. To guarantee a captured packet, the currentStartTime will shift slightly to open earlier than the expected time. If the head of the scan needs to shift left or right, adjust currentStartTime appropriately.

The nextStartTime records the next planned scan anchor point to compare with competing CM sessions. The RF driver uses this value to decide if the scan will be scheduled or not. If a scan is absent, this can be the cause.

The currentChan will simply update to the next channel.