%% Energy Profiling of Bluetooth Mesh Nodes in Wireless Sensor Networks
%
% This example shows energy profiling in a Bluetooth mesh network using the
% Communications Toolbox(TM) Library for the Bluetooth(R) Protocol. One of
% the fundamental features of a Bluetooth mesh is its suitability for the
% low power and energy-constrained nodes. This example models the energy
% profiling of Low Power, battery operated Bluetooth mesh nodes that
% implement an energy saving feature called Friendship. Energy is
% computed based on the time profiled at various states (transmission,
% listen, sleep and idle) of each node in the mesh network. The derived
% results show that the Low Power nodes always consume less energy by
% spending more time in sleep state, thus resulting in energy conservation
% and increased lifetime.

% Copyright 2019 The MathWorks, Inc.

%% Bluetooth Mesh Stack
%
% The Bluetooth Core Specification [ <#17 1> ] includes a low energy
% version for low-rate wireless personal area networks, referred to as
% Bluetooth Low Energy (BLE) or Bluetooth Smart. The BLE stack consists of
% the: Generic Attribute Profile (GATT), Attribute Protocol (ATT), Security
% Manager Protocol (SMP), Logical Link Control and Adaptation Protocol
% (L2CAP), Link layer (LL) and Physical layer. BLE was added to the
% standard for low energy devices generating small amounts of data, such as
% the notification alerts used in applications like home automation,
% health-care, fitness, and Internet of Things (IoT).
%
% The Bluetooth mesh profile [ <#17 2> ] defines the fundamental
% requirements to implement mesh networking solutions for BLE. The mesh
% stack is located on top of the BLE core specification and consists of
% the: Model Layer, Foundation Model Layer, Access Layer, Upper Transport
% Layer, Lower Transport Layer, Network Layer and Bearer Layer. Bluetooth
% mesh networking enables end-to-end communication in large-scale device
% networks to support applications like smart lighting, industrial
% automation, sensor networking, asset tracking, and many other IoT
% solutions.
%
% *Mesh Stack*:
%
% The figure below shows the Bluetooth mesh stack over the advertising
% bearer.
%
% <<../BluetoothMeshStackOverAdvBearer.png>>
%
% * Model Layer: This layer defines the models, messages and states
% required for user scenarios. For example, to change the state of a light
% to On or Off, Generic OnOff Set message from the Generic OnOff model is
% used. This example supports only two models, Generic OnOff and Light
% Lightness with set and status messages.
%
% * Foundation Model Layer: This layer defines the models, messages and
% states required to configure and manage the mesh network. This layer is
% used to configure element, publish and subscription addresses. This
% example assumes that the node is configured with all addresses.
%
% * Access Layer: This layer defines the interface to the upper transport
% layer and the format of the application data. It also controls the
% encryption and decryption of the application data in the upper transport
% layer. This example supports retransmissions and acknowledgments at this
% layer. You can configure the access layer using
% <matlab:edit('helperBLEMeshAccessLayer') helperBLEMeshAccessLayer>.
%
% * Upper Transport Layer: The functionality of upper transport layer
% includes encryption, decryption and authentication of the application
% data and is designed to provide confidentiality of access messages. This
% layer is also responsible for generation of transport control messages
% (Friendship and heartbeat) internally and transmits those messages to a
% peer upper transport layer. These messages are encrypted and
% authenticated at the network layer. In this example encryption,
% decryption, authentication and heartbeat messages are not supported.
%
% * Lower Transport Layer: The functionality of lower transport layer
% includes segmentation and reassembly of upper transport layer messages
% into multiple lower transport layer messages to deliver large upper
% transport layer messages to other nodes. This layer also defines the
% friend queue used by the Friend node to store the lower transport layer
% messages for a Low Power node. In this example, segmentation and
% reassembly is not supported. In this example, both the upper and the
% lower transport layers are implemented as a single transport layer object
% <matlab:edit('helperBLEMeshTransportLayer') helperBLEMeshTransportLayer>.
%
% * Network Layer: This layer defines encryption, decryption and
% authentication of the lower transport layer messages. It transmits the
% lower transport layer messages over the bearer layer and relays the mesh
% messages when 'Relay' feature is enabled. It also defines the message
% cache containing all the recently seen network messages. If the received
% message is found to be in the cache, then it is discarded. The message
% cache is used by the relay nodes (nodes in which the 'Relay' feature is
% enabled). In this example encryption, decryption and authentication is
% not supported. You can configure the network layer using
% <matlab:edit('helperBLEMeshNetworkLayer') helperBLEMeshNetworkLayer>.
%
% * Bearer Layer: This layer is an interface between the Bluetooth mesh
% stack and the BLE core specification. It is also responsible for creating
% a mesh network by provisioning the mesh nodes. This example assumes all
% the nodes are already provisioned into a mesh network. The two types of
% bearers supported by the Bluetooth mesh are advertising bearer and GATT
% bearer. This example considers only the advertising bearer.
%
% *BLE Core Stack*:
%
% * Generic Access Profile: This profile defines advertising data (AD)
% types for carrying mesh messages over the advertising bearer. This
% example supports "Mesh message" AD type and it is used for exchanging
% network layer messages between mesh nodes.
%
% * Link Layer: This layer defines Broadcaster and Observer roles for
% message exchange between the nodes within the Bluetooth mesh network. In
% a Broadcaster role, a node always advertises whereas in an Observer role
% the node always scans for the advertisers. Each node in the mesh network
% switches between these two roles to serve as a Bluetooth mesh node. You
% can configure the Link Layer using
% <matlab:edit('helperBLEMeshLLGAPBearer') helperBLEMeshLLGAPBearer>.

%% Friendship in Bluetooth Mesh
%
% Wireless Sensor Network (WSN) is known to be a highly resource
% constrained class of networks where energy consumption is one of the
% fundamental concerns. Most of the sensors are battery powered devices. In
% WSNs, sensor nodes are deployed in large scale and thus it is impractical
% to replace the batteries of sensor nodes. Therefore, each sensor node
% must use energy efficiently to survive for long time. The Bluetooth mesh
% defines the Friendship functionality for the energy constrained devices.
% The transport layer (upper and lower) in the Bluetooth mesh stack is
% mainly responsible for the Friendship functionality. It defines two types
% of nodes.
%
% * Low Power node: Low Power node has a limited power source and
% operates at reduced receiver duty cycles. This node switches to ON state
% only to receive data packets.
%
% * Friend node: Friend node enables the Friend feature and stores the
% messages destined for Low Power nodes. This node transmits the messages
% only when the Low Power nodes explicitly requests. This example supports
% Friendship between one Friend and one Low Power node.

%%
% *Friendship:*
%
% Friendship is established between Friend and Low Power nodes. The Low
% Power node initiates the Friendship as soon as it is provisioned into the
% Bluetooth mesh network. This example assumes that, Friendship is already
% established between Friend and Low Power nodes. After the Friendship is
% established, the Friend node stores the messages on behalf of a Low Power
% node in the friend queue. A polling mechanism is used for optimizing the
% energy consumption at the Low Power nodes. The Bluetooth mesh message
% exchange between the Low Power node and the Friend node is illustrated in
% this figure:
%
% <<../BLEMeshFriendshipBehaviour.png>>
%
% The timing parameters used in Friendship are:
%
% * Receive delay: This parameter specifies the time between Low Power node
% sending a request and listening for a response from the Friend node. Low
% Power node is in sleep state for the complete duration of the receive
% delay.
%
% * Receive window: This parameter specifies the time for which Low Power
% node listens for a response from the Friend node. Low Power node is in
% the scanning state for the complete duration of receive window.
%
% * Poll timeout: This parameter specifies the maximum time between two
% consecutive requests from a Low Power node. Within the poll timeout, if
% the Friend node or the Low Power node fails to receive request or
% response from the other node, Friendship is terminated.
%
% Periodically, Low Power nodes polls Friend nodes for any data messages
% stored in the friend queue. After polling the Friend node, Low Power
% nodes enter the sleep state for the duration of receive delay. The Friend
% node uses the receive delay to prepare the response for the Low Power
% node. After the receive delay, the Friend node responds to the Low Power
% node before the sum of receive delay and receive window.

%% Check for Support Package Installation

% Check if the 'Communications Toolbox Library for the Bluetooth Protocol'
% support package is installed or not.
commSupportPackageCheck('BLUETOOTH');

%% Bluetooth Mesh Energy Profiling Simulation
%
% This example allows you to create and configure a Bluetooth mesh network
% with different types of nodes such as End nodes, Relay nodes, Friend
% nodes, Low Power nodes. This example initiates and relays a sample mesh
% message from a configured source node to the configured destination node.
% If the same source node is transmitting the mesh messages to multiple
% destination nodes, then all the destination nodes form a group and the
% mesh message is transmitted to the group address. So, all the nodes in
% that group will receive the mesh message. Along with the mesh messages
% originated at the source node, Friendship messages are also exchanged
% between configured Friend and Low Power nodes. While the simulation is
% running, each node calculates the time spent in various states
% (transmission, listen, idle and sleep) of the node. This helps in
% calculating the lifetime of a node within the network.

%%
% *Goals:*
%
% # Create and configure a mesh network
% # Visualize message flooding
% # Analyze the behaviour of Friendship in the Bluetooth mesh network
% # Profile the energy consumed by each node in the Bluetooth mesh network
%
% *Configuration:*
%
% # Source and destination node pairs
% # TTL value for packet originated at each source
% # Friend and Low Power node pairs
% # Receive window and poll timeout value for each Friend and Low Power
% node pairs
% # Relay nodes
%
% *Results:*
%
% * Time spent in various states (transmission, listen, sleep and idle) by
% each node within the Bluetooth mesh network
% * Average time spent by each type (Relay, End, Friend and Low Power node)
% of node at various states

%%
% *Create and configure mesh network:*
%
% You can use <matlab:edit('helperBLEMeshNode') helperBLEMeshNode> and
% <matlab:edit('helperBLEMeshVisualizeNetwork')
% helperBLEMeshVisualizeNetwork> for creating and visualizing the mesh
% network respectively. In <matlab:edit('helperBLEMeshVisualizeNetwork')
% helperBLEMeshVisualizeNetwork> , |NumberOfNodes| specify the total number
% of nodes in the network, whereas |Positions| specify the respective node
% positions. The default value for |NodePositionType| is 'Grid'. You can
% also specify your own network by configuring the value of
% |NodePositionType| to 'UserInput' and node positions to |Positions|.

% Reset the random number generator seed
sprev = rng('default');

% Number of nodes in the Bluetooth mesh network
totalNodes = 55;

% Initialize "meshNodes" with an object of type helperBLEMeshNode
meshNodes(1, totalNodes) = helperBLEMeshNode();
for nodeIdx = 1:totalNodes
    % Create an object for a mesh node
    meshNode = helperBLEMeshNode();
    % Unique identifier for a mesh node
    meshNode.Identifier = nodeIdx;
    
    meshNodes(nodeIdx) = meshNode;
end

% Load node positions
load('bleMeshNodesPositions.mat');

% Visualization object for Bluetooth mesh network
meshNetworkGraph = helperBLEMeshVisualizeNetwork();
meshNetworkGraph.NumberOfNodes = totalNodes;
meshNetworkGraph.NodePositionType = 'UserInput';
meshNetworkGraph.Positions = bleMeshNodesPositions;
meshNetworkGraph.VicinityRange = 25;
meshNetworkGraph.Title = 'Energy Profiling: Bluetooth Mesh Network';

%%
% *Configure simulation parameters:* You can specify the number of source
% and destination pairs in the network using |sourceDestinationPairs|. You
% can specify the number of Friend and Low Power node pairs in the network
% using |friendLowPowerPairs|. The number of relay nodes in the network are
% specified using |relayNodeIDs|. The mesh node objects pertaining to each
% mesh node are specified in |meshNodes|. The paths obtained for source and
% destination pairs are stored in |paths|.

% Simulation time, in milliseconds
simulationTime = 6000;

% Enable/disable visualization
enableVisualization = true;

% Enable/disable the animation in the visualization. If the
% "enableVisualization" is set to false, "enableAnimation" is not
% considered.
enableAnimation = false;

% Source destination pairs - sample mesh message originates at the source
% node and delivered to the destination node
sourceDestinationPairs = [1 52; 1 17; 12 7; 6 53; 54 51; 9 33; 18 52; ...
    29 52; 31 7; 12 9; 54 53; 55 1; 9 17; 18 35];

% Time to live (TTL) value for each source and destination pair in the
% range [0 127]
ttl = [20 23 35 21 23 30 22 20 23 35 21 23 30 22];

% Friend Low Power pairs - assuming that Friendship is established between
% the configured Friend and Low Power node pairs
friendLowPowerPairs = [16 52];

% Receive window (in milliseconds) for each Friend and Low Power node pairs
% (>= 120 milliseconds and <= 255 milliseconds)
receiveWindow = 180;

% Poll timeout (in seconds) for each Friend and Low Power node pairs 
% (>= 2 seconds and <= 95.9 hours)
pollTimeout = 20;

% Relay nodes
relayNodeIDs = [3 4 5 8 10 11 15 19 20 21 23 25 28 30 32 34 36 37 38 39 41 ...
    42 43 44 45 46 47 48 49 26 2 16 13 27];

% Simulate the Bluetooth mesh network with the above configuration
[meshNodes, paths] = helperBLEMeshSimulation(meshNodes, totalNodes, meshNetworkGraph, ...
    simulationTime, sourceDestinationPairs, ttl, friendLowPowerPairs, receiveWindow, ...
    pollTimeout, relayNodeIDs, enableVisualization, enableAnimation);

% Restore the previous setting of random number generation
rng(sprev);

%% Statistics at Each Node
%
% The statistics captured at each node are:
%
% * Time spent in transmission state
% * Time spent in listening state
% * Time spent in sleep state
% * Time spent in idle state
% * Number of messages transmitted from the node
% * Number of messages received by the node
% * Number of messages relayed by the node
% * Number of messages dropped at the node
% * Number of messages received with CRC failures
%
% The workspace variable |statisticsAtEachNode| contains cumulative network
% statistics of all the nodes in the network. However, for a given
% simulation run, You can see the network statistics for a maximum of first
% five nodes. The network statistics for the first five nodes in the
% network are:

% Statistics of each node
statisticsAtEachNode = helperBLEMeshNodesStatistics(meshNodes);
statisticsForFirstFiveNodes = statisticsAtEachNode(1:min(totalNodes, 5), :)

%%
% The average time spent by each type of node at different states is
% calculated and plotted below. The results conclude that the Low Power
% nodes spend most of the time in sleep state, resulting in energy
% conservation and increased lifetime.

fprintf('Average time statistics of different Bluetooth mesh nodes are:\n');
meshNodesAvgStats = helperBLEMeshNodeAverageTime(meshNodes)

%%
% This example models a single message transmission from the source node to
% the destination node. However, you can configure the application traffic
% at the source node by calling the
% <matlab:edit('helperBLEMeshAccessLayer.pushModelMessage')
% pushModelMessage> function periodically. The transmission time at the End
% node depends upon the application traffic. Similarly, the transmission
% time at the Low Power node is influenced by the configured value of the
% poll timeout.

%% Further Exploration
%
%%
% *Calculate Lifetime of Low Power Node*:
%
% You can use <matlab:edit('helperBLEMeshNodeLifetime')
% helperBLEMeshNodeLifetime> to calculate the lifetime of a node in the
% Bluetooth mesh network at the end of simulation. The mesh node object of
% type <matlab:edit('helperBLEMeshNode') helperBLEMeshNode> is given as an
% input to <matlab:edit('helperBLEMeshNodeLifetime')
% helperBLEMeshNodeLifetime> along with |simulationTime| to compute the
% node lifetime. The energy parameters are hardware dependent which are
% used to calculate the node lifetime. You can update the respective
% hardware parameters in the function
% <matlab:edit('helperBLEMeshNodeLifetime') helperBLEMeshNodeLifetime>.

% Fetch one of the Low Power nodes for calculating the lifetime
meshNode = meshNodes(52);
lifeTime = helperBLEMeshNodeLifetime(meshNode, simulationTime);
fprintf('Lifetime of the node %d is: %.4f days.\n', meshNode.Identifier, lifeTime);

%%
% *Lifetime of Low Power Node by Varying Poll Timeout*
%
% The lifetime of a Low Power node depends on the time for which the node
% is in listen state. Most of the time, a Low Power node is in listen or
% sleep state for a given poll timeout. The time for which the node is in
% listen state is determined by the receive window for every poll request
% made by the Low Power node. The Low Power node spends the remaining time
% in sleep, idle and transmission state. However, the time spent in
% transmission state is negligible.
%
% This result shows the plot of lifetime of Low Power node as a function of
% poll timeout for receive window values 120 milliseconds, 200 milliseconds
% and 255 milliseconds.
%
% <<../BLEMeshLPNLifeTimeVSPolltimeout.png>>
%
% The results in the derived plot conclude that the lifetime of Low Power
% node is directly proportional to the poll timeout. This plot can be
% reproduced using the script
% <matlab:edit('helperBLEMeshLPNLifetimeVSPolltimeout')
% helperBLEMeshLPNLifetimeVSPolltimeout>.

%%
%
% This example shows how to create and configure a multi-node Bluetooth
% mesh network and then analyze the mesh message exchange through the
% statistics collected at each node within the network. This example also
% enables you to analyze the behavior and the advantages of the Friendship.
% The Bluetooth mesh network is simulated with multiple Friend and Low
% Power node pairs to calculate the time spent by each node on different
% states. The derived plot of the average time spent by each node in
% different states show that the Low Power nodes always consume less energy
% by spending more time in sleep state. Furthermore, you can also
% experiment by varying different configurations such as the receive window
% and poll timeout values as shown in the 'Low Power Node: Lifetime vs Poll
% Timeout' plot.

%% Appendix
%
% The features used in this example are:
%
% * <docid:comm_ref#obj_bleLLAdvertisingChannelPDUConfig
% bleLLAdvertisingChannelPDUConfig>: Create a configuration object for BLE
% Link Layer advertising channel PDU
% * <docid:comm_ref#mw_fccd1d53-97fd-42f0-bc75-3dcc8a93ca5e
% bleLLAdvertisingChannelPDU>: Generate BLE Link Layer advertising channel
% PDU
% * <docid:comm_ref#mw_0309e66e-dc52-4189-872e-2523a76669de
% bleLLAdvertisingChannelPDUDecode>: Decode BLE Link Layer advertising
% channel PDU
%
% The helpers used in this example are:
%
% * <matlab:edit('helperBLEMeshNode') helperBLEMeshNode>:
% Create an object for Bluetooth mesh node
% * <matlab:edit('helperBLEMeshAccessLayer') helperBLEMeshAccessLayer>:
% Create an object for Bluetooth mesh access layer functionality
% * <matlab:edit('helperBLEMeshNetworkLayer') helperBLEMeshNetworkLayer>:
% Create an object for Bluetooth mesh network layer functionality
% * <matlab:edit('helperBLEMeshTransportLayer')
% helperBLEMeshTransportLayer>: Create an object for Bluetooth mesh
% transport (upper and lower) layer functionality
% * <matlab:edit('helperBLEMeshLowPowerNode') helperBLEMeshLowPowerNode>:
% Create an object for Bluetooth mesh Low Power node functionality
% * <matlab:edit('helperBLEMeshFriendNode') helperBLEMeshFriendNode>:
% Create an object for Bluetooth mesh Friend node functionality
% * <matlab:edit('helperBLEMeshFriendTimer') helperBLEMeshFriendTimer>:
% Create an object for Bluetooth mesh friend timer
% * <matlab:edit('helperBLEMeshLLGAPBearer') helperBLEMeshLLGAPBearer>:
% Create an object for BLE LL advertising bearer functionality
% * <matlab:edit('helperBLEMeshAppGenericPDU') helperBLEMeshAppGenericPDU>:
% Generate Bluetooth mesh generic PDU
% * <matlab:edit('helperBLEMeshAppGenericPDUDecode')
% helperBLEMeshAppGenericPDUDecode>: Decode Bluetooth mesh generic PDU
% * <matlab:edit('helperBLEMeshLightnessPDU') helperBLEMeshLightnessPDU>:
% Generate Bluetooth mesh lightness PDU
% * <matlab:edit('helperBLEMeshLightnessPDUDecode')
% helperBLEMeshLightnessPDUDecode>: Decode Bluetooth mesh lightness PDU
% * <matlab:edit('helperBLEMeshAccessPDU') helperBLEMeshAccessPDU>:
% Generate Bluetooth mesh access PDU
% * <matlab:edit('helperBLEMeshAccessPDUDecode')
% helperBLEMeshAccessPDUDecode>: Decode Bluetooth mesh access PDU
% * <matlab:edit('helperBLEMeshNetworkPDU') helperBLEMeshNetworkPDU>:
% Generate Bluetooth mesh network PDU
% * <matlab:edit('helperBLEMeshNetworkPDUDecode')
% helperBLEMeshNetworkPDUDecode>: Decode Bluetooth mesh network PDU
% * <matlab:edit('helperBLEMeshTransportControlMessage')
% helperBLEMeshTransportControlMessage>: Generate Bluetooth mesh transport
% control message
% * <matlab:edit('helperBLEMeshTransportControlMessageDecode')
% helperBLEMeshTransportControlMessageDecode>: Decode Bluetooth mesh
% transport control message
% * <matlab:edit('helperBLEMeshTransportDataMessage')
% helperBLEMeshTransportDataMessage>: Generate Bluetooth mesh transport
% data message
% * <matlab:edit('helperBLEMeshTransportDataMessageDecode')
% helperBLEMeshTransportDataMessageDecode>: Decode Bluetooth mesh transport
% data message
% * <matlab:edit('helperBLEMeshGAPDataBlock') helperBLEMeshGAPDataBlock>:
% Generate advertising data with Bluetooth mesh network PDU
% * <matlab:edit('helperBLEMeshGAPDataBlockDecode')
% helperBLEMeshGAPDataBlockDecode>: Decode advertising data with Bluetooth
% mesh network PDU
% * <matlab:edit('helperBLEMeshQueue') helperBLEMeshQueue>: Create an
% object for Bluetooth mesh queue functionality
% * <matlab:edit('helperBLEMeshRetransmissions')
% helperBLEMeshRetransmissions>: Create an object for retransmissions in
% Bluetooth mesh
% * <matlab:edit('helperBLEMeshNetworkChannelMessage')
% helperBLEMeshNetworkChannelMessage>: Receive message from Bluetooth mesh
% network channel
% * <matlab:edit('helperBLEMeshPath') helperBLEMeshPath>: Return the path
% between source and destination within Bluetooth mesh network
% * <matlab:edit('helperBLEMeshVicinityNodes') helperBLEMeshVicinityNodes>:
% Obtain the vicinity nodes of a given node
% * <matlab:edit('helperBLEMeshGraphCursorCallback')
% helperBLEMeshGraphCursorCallback>: Display the node statistics on mouse
% hover action
% * <matlab:edit('helperBLEMeshVisualizeNetwork')
% helperBLEMeshVisualizeNetwork>: Create an object for Bluetooth mesh
% network visualization
% * <matlab:edit('helperBLEMeshSimulation') helperBLEMeshSimulation>:
% Simulate a Bluetooth mesh network
% * <matlab:edit('helperBLEMeshNodesStatistics')
% helperBLEMeshNodesStatistics>: Collect statistics at each node into a
% table
% * <matlab:edit('helperBLEMeshNodeLifetime') helperBLEMeshNodeLifetime>:
% Compute lifetime of a Bluetooth mesh node
% * <matlab:edit('helperBLEMeshNodeAverageTime')
% helperBLEMeshNodeAverageTime>: Compute average time spent in various
% states by the Bluetooth mesh nodes
% * <matlab:edit('helperBLEMeshLPNLifetimeVSPolltimeout')
% helperBLEMeshLPNLifetimeVSPolltimeout>: Script to compute the lifetime of
% Bluetooth mesh Low Power node for different poll timeout and receive
% window values
% * <matlab:edit('helperBLEPrependAccessAddress')
% helperBLEPrependAccessAddress>: Prepend the PDU with the access address

%% Selected Bibliography
%
% # Bluetooth Special Interest Group (SIG). "Bluetooth Core Specification".
% Version 5.0. https://www.bluetooth.com/
% # Bluetooth SIG. "Bluetooth Mesh Profile". Version 1.0.
% https://www.bluetooth.com/