.. _sec-conn-monitor-application-cc23xx:

************************************
Connection Monitoring - The Feature
************************************
The Connection Monitoring feature is a proprietary feature of the BLE-stack
provided through TI's Simplelink :sup:`®` SDK. The purpose of this feature is to
enable a |DEVICE| to monitor an active Bluetooth LE connection between any two 
devices , provided the connection parameters are provided to the |DEVICE|. This
feature can be used in applications like locationing, tracking connection status
and more. This section will cover the what, why, when and who for the connection
monitor. In other words, the following will be covered in this section:

* When can the connection monitor be enabled?
* Who can the connection monitor track in active connections?
* What data is needed for enabling the connection monitor on an ongoing connection,
  and what is the output from the Connection Monitor.
* How does the connection monitor work, and how to debug the connection monitor?


Enabling the Connection Monitoring Feature
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This section talks about when the Connection Monitor feature can be enabled. The
process for enabling the Connection Monitor feature starts much before writing code
for it in the application layer. In order to enable the connection monitoring
feature in your application, you will need to start by enabling the Connection
Monitor feature in SysConfig. 

.. figure:: resources/Enable_CMR.png
    :align: center

    Enabling the Connection Monitor feature of the TI BLE stack.

This is very important, as the aforementioned compiler macro is used by the
compiler to include/exclude code from the SDK.

.. warning:: If the Connection Monitor check-box is not checked, it will cause
             the compiler macro to not be defined in turn leading to the
             compilation errors, incurring hard-faults in the system, or getting
             incorrect size of memory blocks allocated for various purposes!

For a connection monitor device, referred to as candidate node in this document,
to start monitoring a connection, the candidate node needs to receive the
connection parameters for that connection. This can be provided directly by one
of the devices involved in the connection, i.e. the peripheral or the central.
The device that provides the connection information will hence be called the
serving side, and the APIs that have the prefix **CMS** will pertain to the
serving side. It is worthwhile noting that since the connection monitor does not
actively participate in a connection, not all of the connection information is
relevant for the connection monitor. In effect this means that when the serving
side, is preparing to send the connection information to the candidate node, only
a sub-set of the connection information needs to be provided. 

The API ``cmErrorCodes_e CMS_GetConnData(uint16_t connHandle, cmsConnDataParams_t *pData)``
can be called from the application layer on the serving side, where
the connHandle is the connection handle of the connection you want to get
connection parameters for, and pData is a pointer to a data structure of type
**cmsConnDataParams_t** to store information required by the connection monitor.
This struct contains two elements, one that tracks the length of the connection
information data it has been populated with, and the other is a pointer to a
memory block which shall contain the information needed by the candidate node.
It is the application's responsibility to make sure that a memory block has been
allocated to be used for storing connection parameters. The application should
also ensure that the memory block allocated for storing connection parameters is
word aligned (4-byte aligned). If the memory block is not properly aligned, it
could lead to a hard fault occurring due to unaligned access. 

The aforementioned API ``CMS_GetConnData()``, will uniquely identify the connection using the
provided connection handle, it will then find the pointer to the connection
information for that connection. From the connection parameters, it will then
populate the memory block, the pointer to which is provided as a parameter to
``CMS_GetConnData()``, with the relevant information needed by the candidate
node. This information then needs to be sent to the candidate node, which
will then setup for monitoring the connection on it's side.

There is no limitation around when, during the lifetime of a connection, can a
connection monitoring session be started. This means that the serving side can
choose to trigger the monitoring of a connection right after it's establishment.
It can, alternatively, also choose to start monitoring the connection at any other
point in time. The important thing to note here is that the connection information
which will be provided to the candidate node must always be "fresh". This means
that the connection parameters must be what are valid at that instant in time, and
not what was previously valid. This is especially true if the connection that the
candidate node needs to monitor has recently gotten a parameter update to change
the connection interval, the PHY, or the channel map. If the aforementioned data
is incorrect, the candidate node will not be able to track the connection. It is
as such recommended to call ``CMS_GetConnData()`` on the connHandle of interest
to ensure that the connection parameters that the application layer has access
to have not become stale since last use.


Tracking a connection
^^^^^^^^^^^^^^^^^^^^^

When the candidate node has received connection information from a serving node,
and a command to start monitoring a connection, the candidate node will try to
establish a monitoring session. Without getting into the details of how this is
done just yet, upon successful establishment of the connection monitoring session,
the candidate node can now sniff packets sent between the central and the
peripheral every connection event. The connection monitor is designed such that
it expects to sniff two connection event packets from every connection event. The
first being from the central to the peripheral, and the second being the
peripheral's response to the central. For each packet that is successfully sniffed
by the candidate node, a **connection monitor report** message is sent up to the
application layer. 

The application layer receives information like the RSSI value
of the last packet that was received, the origin of the packet (if it was from
the central or the peripheral), the channel number that the packet was received
on, and more. The connection monitor report cannot be filtered by role, and all RSSI reports
will be forwarded to the application. It is possible to configure each connection monitoring session
uniquely, and independently, to allow for using session specific connection role 
masks. This allows the application to only receive the connection monitor report
from a certain role. For instance, if a connection monitoring session is set up
to only report successfully sniffed packets from the peripheral to the central,
the application layer will receive a message every time the candidate node has
successfully received that packet, but no message for successfully sniffing the
central to peripheral packet. Implementing connection role masks may also help
with minimizing the amount of message traffic from the stack to the application
layer.

For as long as the connection parameters do not change, the candidate node can
manage to continuously monitor a connection. When the connection parameters/channel
map changes on the serving node's side, the candidate node must also immediately
receive the parameter update so that the monitoring session can be updated. If
this does not happen, then the candidate node may no longer be able to track the
connection, resulting in the failure of that monitoring session. The serving node
will then need to restart the process for starting a connection monitoring session.


Inner Workings of the Connection Monitor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The connection monitor feature presents itself to the application designer as a
black-box, since the connection monitoring feature is not standardized by the BLE
specification. This can make it harder to understand how the connection monitor
works, what kind of timing requirements are necessary from a system level, and how
the application designer can go about debugging the feature, should that ever
become relevant. Through this section, using a logic trace for the PA (Radio TX),
and LNA (Radio RX) pins from the candidate node, the central and the peripheral,
the application designer will become more familiar with what to look for to ensure
that everything works as expected, and if it doesn't, how to go about fixing it.

When running the connection monitor from the Simplelink :sup:`®` SDK, the user
has access to three forms of outputs from the demo:

* UART print to the terminal (Powershell, Command Prompt, etc): **Enabled out-of-Box**
* Log statements saved to a .txt file: **Enabled out-of-Box**
* RF Observables (visualize the activity of the radio, and timing):
  **Not** enabled out-of-Box, sysconfig changes required to enable this. Refer to
  the `Loading FW Images` section in the Connection Monitor Overview document on how to do this.

The UART prints to the terminal capture live state of the demo, printing RSSI
reports in realtime, and showing the different BLE events occuring. The .txt logs
are more technical and contain raw UART data that is transferred between the
candidate and serving nodes. The log file output can come in handy when trying to
examine the exchanged data, and extracting and understanding the flow of
information between the host PC, candidate and serving nodes.


.. figure:: resources/example_output_CMR_demo_connRoleMask.png
    :align: center

    Example output when running the out-of-box Connection Monitor Demo

In the example output presented above, the prints showcase that the com-ports to
the candidate node, and the serving node have been opened. It shows the serving
node, referred to as the Car Node, scanning for advertisement from the Key Node
(peripheral device). Upon discovering the advertising report from Key Node, the
serving node initiates a connection, and a pairing request. When these succeed,
the connection parameters, and information is forwarded to the candidate node to
start monitoring the connection. Upon successfully starting a connection monitor
session, the reports are printed containing RSSI, and more information.

.. note:: In the image above, the connection role Mask is set to central. This is
        why the reports from the candidate node only show the central in the
        connection role field of the report.

When the connection role mask is set to both central + peripheral, the report
from the candidate node, look like this:

.. figure:: resources/example_output_CMR_demo.png
    :align: center

    Example output with connection role mask set to central plus peripheral


RF observables and the Connection Monitor Demo
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In this sub-section, a logic trace of the RF Observables is shown which will help
demonstrate the manner in which the connection monitor works. Important terminology
for this section:

* Key Node: Advertising peripheral, with advertising interval set to 1s

* Car Node: The serving node. Scanning for advertising from a device called "Key
  Node". When it finds this device, it will initiate a connection, and sub-sequently
  initiate a pairing request.

    * This is a multi-role device. It means that it is possible to connect to the
      car node device with the phone acting as a central. The connection parameters
      for the connection between the phone and the car node will then be sent to The
      candidate node for monitoring.

* CMR Node: The candidate node. This node will wait to receive connection
  parameters, and connection monitor start/stop commands from the serving node. In
  addition to monitoring the connection that has been forwarded from the serving
  node, the CMR node can also maintain a connection in parallel as a peripheral.

* PA: Power Amplifier RF Observable, active-high when the radio is transmitting.

* LNA: Low-Noise Amplifier RF Observable, active-high when the radio is scanning.

The following figure visualizes advertising from the key node:

.. figure:: resources/Key_Node_advInterval_1s.png
    :align: center

    Key Node advertising with a 1s adv. interval

When the out-of-box demo is started, the Car Node will start scanning to find
advertising from the Key Node. The scan window, which is equal to the scan
interval here is set to be 10ms. This means that every 10ms the Car Node will
switch to a different BLE advertising channel, always starting on channel 37,
then moving to 38, then 39 and so on. This is depicted in the following image:

.. figure:: resources/CarNode_infinite_scan_start.png
    :align: center

    Car Node scanning with scan interval = scan window = 10ms

When the Car Node manages to successfully receive an advertising packet on the
channel it is scanning on, it will initiate a connection establishment. This is
showcased in the following figure:

.. figure:: resources/link_establishment_CN_KN.png
    :align: center

    Car Node initiating a connection with the Key Node.

The image above showcases an overlap between the PA of the Key Node, and the LNA
of the Car Node (marker 0). Since the Key Node advertises with connectable
advertising, right after emitting the advertising packet, it opens a receive
window which is when the Car Node sends the Connection Indication Packet. This
marks the creation of a link. At the next connection interval, the Car Node sends
a packet first, followed by the Key Node sending a packet. This marks the
establishment of the connection. The connection event for the connection between
the Car Node and the Key Node is set to 30ms. This is shown in the following image.

.. figure:: resources/connEvents.png
    :align: center

    Connection Events spaced 30ms apart.

The out-of-Box demo gets the connection information, and sends it to the CMR node
when the link established event is received by the application layer. Following
this, the Car Node then sends the information to the CMR Node. From the received
connection information, and the information about the transmission delay between
the Car Node, and the CMR node, the CMR node will calculate which channel to
listen on for the next connection event between the Car Node and the Key Node
device. It will then open scan windows hoping to catch this event, for a maximum
number of attempts, as defined in the ``CM_StartMonitor()`` API. Initially the
CMR node will open the first scan window slightly before the start of the
connection event. It does this to ensure that the connection event is not missed,
and that packets between the central and the peripheral are both received correctly.
The wide scan windows are opened for a fixed number of windows as defined in
software by the adjustment tries. After these adjustment tries, the CMR will fine
tune the opening of the scan windows such that it exactly, only covers the
connection event. The connection monitor now enters the adjustment mode again
if there are multiple missing packets (which can be caused by bad RSSI values for example).
The start of the monitoring session is captured in the image below.

.. figure:: resources/CMR_start_monitoring.png
    :align: center

    CMR starts monitoring the connection between the Car and Key Node.

The scan window fine tuning by the CMR is captured in the following image. In the
out-of-Box demo, the maximum number of adjustment tries is set to 5, which means
that after the first 5 scan windows, the CMR node will fine tune the timing of
the scan windows. Notice the sharper timing from marker 5 in the image below.

.. figure:: resources/scan_window_timing_improvement_CMR.png
    :align: center

    CMR fine tunes the timing of the scan window.

This concludes the section describing the expected behavior for the RF observables
from the out-of-box demo.

.. note:: When the connection monitor role is in adjustment mode, the connection monitor will report an UNDETERMINED status, 
          since the CMR is unable to determine the identity of the packet.
