.. _sec-conn-monitor-overview-cc23xx:

******************
Connection Monitor
******************
This section introduces the functionality of the Connection
Monitoring feature provided through TI's BLE Stack. This section is set up into
the following parts:

#. `Connection Monitor Introduction`_.
#. `Connection Monitor Feature`_.
#. `Connection Monitor Demo`_.
#. `Setting up Host PC`_.
#. `Loading FW Images`_.
#. `Running the Connection Monitor Demo`_.


.. _Connection Monitor Introduction:

Connection Monitor Introduction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The Connection Monitoring feature allows the |DEVICE| to follow, and monitor,
active BLE connections. When the |DEVICE| is actively monitoring a connection,
it is said to be in the Connection Monitoring Role (CMR). The CMR is not the same
as the Peripheral, Central, Broadcaster or Observer roles, which the
BLE device can be configured through SysConfig. **Any** |DEVICE| **which has the
Connection Monitoring feature enabled can enter the CMR at any point of it's
liftime.**  The CMR can co-exist with any BLE role that the |DEVICE| is configured
to be in. In other words, if the |DEVICE| is configured to be a Peripheral upon
startup, the CMR will work without compromising the functionality of the Peripheral
role, given that there is no conflict of radio time.

.. _Connection Monitor Feature:

Connection Monitor Feature
^^^^^^^^^^^^^^^^^^^^^^^^^^

The Connection Monitor (CM), refers to any device that can monitor an ongoing
connection between two external devices. This is enabled by the connection
monitoring device receiving the connection information from one of the two external devices,
in order to start tracking the connection. This connection information may be sent to the
CM over UART, SPI, I2C, CAN, or any other protocol. Here is **an example block
diagram** for the Connection Monitor feature, where the CM receives connection
information over the UART protocol:

.. note:: The choice of UART is arbitrary, and only to demonstrate the block diagram.
    The user is free to choose any protocol of choice.

.. ditaa::
    :--no-shadows:
    :--no-separation:
    :align: center

    /-----------------------------\      +-----------------------------\
    |                             |      |                             |
    |                             |  BLE |                             |
    |  cRED   BLE Device 1        |  ->  |  cRED   BLE Device 2        |
    |                             |  <-  |                             |
    |                             |      |                             |
    \--------------+--------------/      \-----------------------------/
                ^
                :
                |
                |          /-----------------------------\
                :          |                             |
                :  UART    |            c33F             |
                +--------->|     Connection Monitor      |
                           |                             |
                           |                             |
                           \-----------------------------/


Since the CM is only "monitoring" an ongoing connection, it does not participate
in the connection's data exchange. The CM, in practicality, is a sniffer that is
setup to scan for connection event packets between two devices that
are in an active connection. If the CM is, successfully, able to receive the first two
connection event packets from every connection event (One from the peripheral to the
central, and the other from the central to the peripheral), the CM considers that
connection event to be successfully monitored. This happens because every connection
event starts with the central device sending a packet to the peripheral. If the
peripheral receives this packet successfully, the peripheral replies to the
central with its packet in response. There may be more packets that are sent
in that connection event, but after the CM receives the initial two packets, it closes
the monitoring session. It then waits until the next connection event to start
monitoring again for the packets from that connection event, and this continues
for as long as the connection information doesn't change. The packets that are
received per connection event are not parsed/decrypted by the CM. This means that
the CM is, purely, **observing** an active connection, with no information about
the data being exchanged between the two devices. The connection information
that is needed by the CM to monitor a connection must therefore be explicitly
provided to the CM via a communication medium, as shown above. Every time the CM
scans, and successfully receives a packet, an event is raised to the application
layer to report the following things in the form of a
**connection monitor report**, and more:

#. RSSI of the received packet.
#. The origin of the packet (whether the sender was the central or the peripheral).
#. The channel that the packet was received on.

When the CM starts monitoring a connection it assigns a connection handle
to the connection monitoring session that has just started. This handle is used
to uniquely identify the connection monitoring session. The assigned handle is
stored in the same array that also tracks active connections. This implicitly
means that the CM treats every connection monitoring session as a connection.
This has no practical impact on the connection monitoring session itself. The only
effect of this is that the total number of connections (active + connection monitoring)
need to be less than or equal to the maximum number of connections as defined in
the project's SysConfig file.

.. note:: The size of the CM data is now reduced to 56 bytes. 

.. warning:: - ``CMS_GetConnDataSize(void)`` returns ``uint8_t`` instead of ``uint16_t``.
                - ``cmErrorCodes_e CMS_GetConnData(uint16_t connHandle, cmsConnDataParams_t *pData)`` adds ``uint32_t accessAddr`` to the ``CMS_GetConnData struct``.
                - ``dataSize`` is changed from ``uint16_t`` to ``uint8_t``.
                - ``cmErrorCodes_e CM_StartMonitor(cmStartMonitorParams_t *pParams)`` adds to the paramters structure. 
                  ``cmStartMonitorParams_t``, ``adjustementEvtTries`` and ``cmConnectionMaskRole_e connRole`` were removed from the struct. 
                - ``cmDataSize`` was changed from ``uint16_t`` to ``uint8_t``.
                - ``cmReportEvt_t`` now contains 2 packets with status of ``CM_PKT_STATUS_NOT_RECEIVED``, ``CM_PKT_VALID_CENTRAL``, ``CM_PKT_VALID_PERIPHERAL`` and ``CM_PKT_STATUS_UNDETERMINED``. 


.. _Connection Monitor Demo:

Connection Monitor Demo
^^^^^^^^^^^^^^^^^^^^^^^

The |SDK| :sup:`®` ships with a demo that enables the
user to run the Connection Monitoring functionality. This demo helps orient the user
with the Connection Monitor feature, and with visualizing the output from the
Connection Monitor.

In order to run the demo, the following pre-requisites must be fulfilled:

* HW required to run the demo can be either of the combinations
  listed under:

  * 2 |DEVICE| launchpads + 1 phone

  * 3 |DEVICE| launchpads
* The latest |SDK| :sup:`®`, using 9.11.xx.xx and
  above.
* Installation of Python, version 3.10.xx, on your computer. Python version 3.10.11
  can be downloaded `from here <https://www.python.org/downloads/release/python-31011/>`_

The following sections will list the necessary steps to prepare the host PC, and
the |DEVICE| launchpads to successfully run the Connection Monitor Demo. Before
getting into that, it is worthwhile to look at the block diagram for the Connection
Monitor Demo, and understand the role of each block.

.. ditaa::
 :--no-shadows:
 :--no-separation:
 :align: center

 /----------\       /-----------\     /----------\
 |          |       |           |     |          |
 |          |  BLE  |           |     |          |
 | Car Node |  ->   |  Key Node |     |    CM    |
 |          |  <-   |           |     |   Node   |
 |          |       |           |     |          |
 \-------+--/       \--------+--/     \-------+--/
     ^                                  ^
     :                                  :
     |                                  |
     |           /-----------\          |
     :           |           |          :
     :   UART    |           |   UART   :
     +---------->|  Host PC  |<---------+
                 |           |
                 |           |
                 \--------+--/


Notice that this block diagram looks different than the one shown earlier in this
document where the Connection Monitor Node was directly connected to one of the
BLE devices. Both ways are **correct**. What is important is that
the Connection Monitor receives the connection information to start tracking the
connection.

The Car Node behaves as a multi-role device (Central + Peripheral), while the Key
Node, and the CM nodes are peripheral devices. Note that there are **no limitations**
when it comes to which role the CMR device needs to be in. This demo is setup to
use the Host PC as this can help emulate the presence of an external MCU which may
act as the controller in applications like Car Access.

In the Out-of-Box Connection Monitor Demo, the **Car Node**, and the **Connection
Monitor (CM)** node devices are controlled entirely by the Host PC, over UART.
This means that these node devices wait to get UART commands from the Host PC,
which controls the BLE behavior of these nodes. This includes controlling when
the Car Node starts scanning, advertising, initiating a connection etc. Additionally,
the Host PC provides the CM node with the connection information of the connection that
needs to be monitored. The Host PC is also responsible for configuring the
duration for which the connection needs to be monitored. Lastly, it is the Host
PC that triggers the start of a connection monitoring session on the CM node. The
Host PC, gets the connection information from the Car Node, which is then forwarded
to the CM Node.

.. ditaa::
    :--no-shadows:
    :--no-separation:
    :align: center

    /------------\             /------------\               /------------\                   /--------------\
    |            |      BLE    |            |      UART     |            |      UART         |              |
    | Conn Peer2 |     <-      | Conn Peer1 :<------------->:   Host PC  |<----------------->| Conn Monitor |
    |            |     ->      |            |               |            |                   |              |
    \-------+----/             \-------+----/               \-------+----/                   \-------+------/
            :<------------------------>:                            :                                :
            |       Conn               |                            |                                |
            |   Established            |                            |                                |
            |                          :<-------------------------->:                                |
            |                          |            Conn            |                                |
            |                          |     Established Event      :<------------------------------>:
            |                          |                            |             CM                 |
            |                          |                            |        Register CBs            |
            |                          :<---------------------------:                                |
            |                          | CM_InitGetConnDataParams() |                                |
            |                          :<---------------------------:                                |
            |                          |    CM_GetConnDataSize()    |                                |
            |                          :<---------------------------:                                |
            |                          :      CM_GetConnData()      :                                |
            |                          :--------------------------->:                                |
            |                          |        Return Data         |                                |
            |                          |                            :------------------------------->:
            |                          |                            | CM_InitStartMonitorParams(data)|
            |                          |                            :------------------------------->:
            |                          |                            |        CM_StartMonitor()       |
            |                          |                            |                                |
            |                          |                            |                                |Process Data
            |                          |                            |                                :-----------+
            |                          |                            |                                |           |
            |                          |                            |                                :<----------+
            |                          |                            :<-------------------------------:
            |                          |                            :       Monitoring Status        :
            |                          |                            |                                |
            :                          :                            :                                :
    /------------\              /------------\               /------------\              /--------------\
    |            |      BLE     |            |      UART     |            |              |              |
    | Conn Peer2 |      <-      | Conn Peer1 |       <-      |   Host PC  |              | Conn Monitor |
    |            |      ->      |            |       ->      |            |              |              |
    \-------+----/              \-------+----/               \-------+----/              \-------+------/


Car Node, and the Connection Monitor nodes send event notifications to
the Host PC over UART, which includes events like advertising reports, connection
establishment events, connection monitor reports, and more. An example of what the
information flow looks like is showcased in the figure above.

Setting up to run the Connection Monitor Demo
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. _Setting up Host PC:

Setting up Host PC
^^^^^^^^^^^^^^^^^^

Follow the steps mentioned below to prepare your host PC for running the Connection
Monitor Demo:

* With the SDK, and Python installed, using either Powershell or
  CMD Prompt, open the SDK installation folder. The SDK should normally be
  placed under **C:/ti/**.

    * With the terminal open, check to see that the correct version of Python is
      installed, and ready to use. You should see something similar to the image
      below:

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

    Powershell session with the SDK opened.

* Navigate then to the ``tools\ble\ble_agent`` folder to setup the necessary python
  environment for running the demo by doig the following:

    * Run ``python -m pip install virtualenv`` to install the virtual environment
      module for Python. Using a virtual environment ensures that the Python modules
      installed inside of a virtual environment **do not affect the global Python
      setup** on your computer.

.. note:: The exact alias for running python through powershell command prompt may
    vary, for instance python3, py, python etc. Please check whichever one works
    for your system, and use the same

    * If your network is behind a proxy, then add the proxy flag
      like so: ``--proxy YOUR_PROXY_HERE`` to all the python commands. For
      instance: ``python -m pip install virtualenv --proxy YOUR_PROXY_HERE``

* Once the installation of the **venv** module is complete, initialize a virtual
  environment (venv) by running the following command in the shell terminal
  ``python -m venv .venv``. This creates a venv in the ``YOUR_SDK\tools\ble\ble_agent``
  folder.
* Once the venv has been created, activate it by typing the following: ``.venv\Scripts\activate``
  These steps are captured in the screenshot below:

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

    Powershell session with the **venv** module installed and venv activated.


* Once the venv is **installed and activated**, install the required python modules
  to run the demo by doing the following: ``pip install -r requirements.txt``

.. warning:: If the previous step is not run, and the necessary requirements are
             not installed, **it will cause the demo to fail**, due to a lack of the
             required modules needed by the python code!

That wraps up the necessary steps required to setup your host PC for running the
CM demo. Now, the launchpads need to be loaded with the correct FW to be enable
them to run the Connection Monitor Demo.


.. _Loading FW Images:

Loading FW Images Onto launchpads
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

With the Host PC prepared with python installation, and the virtual environments,
the next step is to prepare the |DEVICE| launchpads. In order to do so, follow
these steps:

* Start with opening Device Manger, and note down the Com Port for each of the 3
  launchpads. **This step is very essential for running the demo**. It is essential
  that you **note down the Com Port for the UART, and not the XDS**. When using
  the Windows Device Manager to figure out the Com Ports for the launchpads,
  beware that each launchpad shows up as 2 Com Ports, where the
  **XDS110 Class Application/UART** Com Port is the one we need to use, not the
  **XDS110 Class Auxiliary**. Refer to the image below for an example:

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

    Choosing the correct Com Port

* Start with importing the **key_node** example into CCS. Open SysConfig for this
  project, navigate to RCL under TI Drivers, and find the RF Observables setting.
  Here, enable the PA/LNA Pins (See highlighted rectangle in image below). It is
  recommended to enable these as this makes it easy to visualize what the radio
  is doing. This, in turn makes it easy to understand the CM's behavior.

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

    Enabling PA and LNA

* Save the sysconfig changes, and build your project. Once the build succeeds,
  flash **one** of the launchpads with the **key_node** .out file. Make sure you
  have noted the Com port of this device.
* Now import the **car_node** example from the SDK. As with the **key_node**
  example above, enables the PA/LNA pins for the car node example too. Save your
  changes, build and flash this project to the **second and third** launchpad.
  Note the com Ports for the two launchpads, and pick one to use as your car
  node. The com port will be used in the python script mentioned in the next
  section to run the connection monitoring demo. Make sure to note the Com port
  of the CM Node, as this will be used later.

This now concludes loading of the correct FW images onto the launchpad. The next
step, is running the Connection Monitor Demo!

.. _Running the Connection Monitor Demo:

Running the Connection Monitor Demo
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

With the python environment prepped, and the necessary firmware loaded onto the
launchpads, the Connection Monitor Demo can now be run. In order to do so, follow
the steps listed hereunder:

* Open the ble_device_car_node.py file which is available inside the SDK at the
  following location: ``YOUR_SDK\tools\ble\ble_agent\examples``
* In the ble_device_car_node.py script, find the line that says
  ``car_node = BleDevice(`` and here, for the device_comport, replace the com port
  with the actual com port of the **car node** device, for instance **"COM13"** if the
  car node device you chose uses the Com Port 13. For the car_node device, we
  want the Com Port of the device that was flashed with Connection Monitor feature
  disabled via SysConfig.
* Do the same for the **cmr_node**, which will be the Connection Monitor node,
  in the ble_device_car_node.py file. Then, save the python file.
* Make sure that all the launchpads are powered, have been flashed with correct
  FW, and that the correct Com Ports are being used in the Python script.
* To run the demo, in the shell terminal window, with the python venv activated,
  navigate to the ``YOUR_SDK\tools\ble\ble_agent\examples`` folder, and run the
  following command: ``python .\examples\ble_device_car_node.py``. This will
  kickoff the process shown in the information flow for the connection monitor.