%% Bluetooth Mesh Flooding in Wireless Sensor Networks
%
% This example demonstrates network layer flooding in a Bluetooth mesh
% network using the Communications Toolbox(TM) Library for the Bluetooth(R)
% Protocol. Flooding is a mechanism in which every incoming packet is sent
% through every outgoing link except the one it arrived on. The flooding
% mechanism is studied by identifying a path between source and destination
% nodes through intermediate relay nodes. This example also shows how to
% perform Monte Carlo simulations on the Bluetooth mesh network to obtain
% numerical results averaged over multiple iterations.

% Copyright 2019-2020 The MathWorks, Inc.

%% Bluetooth Mesh Stack
%
% The Bluetooth Core Specification [ <#23 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
% 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
% notification alerts used in such applications as home automation,
% health-care, fitness, and Internet of Things (IoT).
%
% The Bluetooth mesh profile [ <#23 2> ] defines the fundamental
% requirements to implement a mesh networking solution for BLE. The mesh
% stack is located on top of the BLE core specification and consists of
% Model Layer, Foundation Model Layer, Access Layer, Upper Transport Layer,
% Lower Transport Layer, Network Layer and Bearer Layer. Bluetooth mesh
% networking enables large-scale device networks in the applications such
% as smart lighting, industrial automation, sensor networking, asset
% tracking, and many other IoT solutions.
%
% The two types of bearers supported by Bluetooth mesh are advertising
% bearer and GATT bearer. This example considers only the advertising
% bearer. The figure below shows Bluetooth mesh stack over advertising
% bearer.
%
% <<../BLEMeshStackOverAdvBearer.png>>

%% Bluetooth Mesh Network Layer
%
% The network layer is mainly responsible for:
%
% * Transmitting the upper layer messages over the network using bearer
% layer
% * Relaying the mesh messages
% * Network level security
%
% Some of the major functionalities of the network layer are shown below.

%%
% *Relay feature:* In order to have a reliable and efficient flooding
% mechanism, the Bluetooth mesh standard defines the relay feature. Relay
% feature enabled nodes can retransmit mesh messages over the network. This
% helps in reducing the channel congestion compared to the traditional
% flooding where each node retransmits the received message. Nodes can
% enable or disable the relay feature based on network conditions. The
% relay node (any mesh node having relay feature enabled) forwards the
% received message throughout the network. This helps in extending the
% reach of mesh message to enable large-scale networks.

%%
% *Managed flooding:* The Bluetooth mesh profile [ <#23 2> ] specifies the
% methods to optimize the flooding operation for an efficient network. This
% is called as managed flooding. Major methods used in managed flooding
% are:
%
% * Message Cache: All nodes must implement a network message cache. The
% message cache contains all the recently seen network messages. If the
% received message is found to be in the cache, then it gets discarded.
% * TTL: Time-to-live (TTL) controls the number of hops a message is
% relayed in a network. Choosing an optimal TTL value conserves energy over
% the network. If the TTL value at a node is greater than or equal to 2, it
% indicates that the message may have been relayed and can be relayed. TTL
% value less than 2, indicates the message may have been relayed but will
% not be relayed.
% * Heartbeats: Heartbeat messages are sent by the nodes periodically. It
% is used as an indication to the receiving nodes, that the sending node is
% alive. At the receiving node the optimal TTL value for publishing a
% message to the sender is derived from the heartbeat message.

%%
% *Network Addresses:* The network layer defines four types of addresses:
%
% * Unassigned Address: An unassigned address indicates no address has been
% allocated to the node
% * Unicast Address: A unicast address is used for unique identification of
% the node
% * Group Address: A group address is used to identify a group of nodes
% * Virtual Address: A virtual address represents a set of destination
% addresses. Each virtual address logically represents a 128-bit label UUID
% (Universally Unique Identifier)

%%
% In Bluetooth mesh flooding, the network layer plays a crucial role. All
% the network messages received and transmitted in the network layer use
% either the advertising bearer or the GATT bearer. The relay and proxy
% features in the network layer help in enabling large-scale mesh networks.
% The relay feature is used to relay/forward network PDUs received by a
% node over the advertising bearer. The proxy feature is used to
% relay/forward network PDUs received by a node between GATT and
% advertising bearers. In this example, Bluetooth mesh flooding in a
% wireless sensor network using advertising bearer is demonstrated.

%% 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 Flooding Simulation
%
% This example allows you to create and configure a Bluetooth mesh network.
% Two network scenarios, each consisting of a fifty node mesh network are
% created and some of these nodes are configured as relays. In each
% scenario, source and destination node pairs and their corresponding TTL
% values are specified. In the first scenario, the paths between source and
% destination nodes are identified. You can also visualize the message flow
% in the network with statistics. In the second scenario, some of the relay
% and end nodes (any node in the mesh network) are failed. Moreover, the
% relay feature of some of the relay nodes is also disabled. The
% simulations show that there is a chance of having a path between the
% selected source and destination nodes, even if some of the intermediate
% relay and end nodes fail in the network.

%%
% *Goals:*
%
% * Create and configure a mesh network
% * Visualize message flooding
% * Derive path between selected source and destination
% * Display statistics (refer <#17 Network Layer Statistics at Each Node>)
% at each node
%
% *Configuration:*
%
% * Source and destination node pairs
% * TTL value for packet originated at each source
% * Relay nodes
% * Failed nodes
%
% *Results:*
%
% * Path between source and destination for both the scenarios
% * Cumulative statistics (refer <#17 Network Layer Statistics at Each
% Node>) for both the scenarios

%%
% *Create and configure mesh network:*
%
% You can use <matlab:edit('helperBLEMeshNetworkNode')
% helperBLEMeshNetworkNode> and
% <matlab:edit('helperBLEMeshVisualizeNetwork')
% helperBLEMeshVisualizeNetwork> for creating and visualizing the mesh
% network respectively. You need to specify |NumberOfNodes| and
% |NodePositionType| in <matlab:edit('helperBLEMeshVisualizeNetwork')
% helperBLEMeshVisualizeNetwork>. 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|.

% Set random number generator seed to 'default'
sprev = rng('default');

% Number of nodes in the mesh network
totalNodes = 50;

% Initialize 'bleMeshNodes' vector with objects of type
% helperBLEMeshNetworkNode
bleMeshNodes(1, totalNodes) = helperBLEMeshNetworkNode;
% Configure mesh nodes
for idx = 1:totalNodes
    meshNode = helperBLEMeshNetworkNode;
    meshNode.Identifier = idx;
    meshNode.NetworkLayer.ElementAddresses = dec2hex(idx, 4);
    bleMeshNodes(idx) = meshNode;
end

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

% Create visualization objects for two scenarios
numberOfScenarios = 2;
% Initialize 'meshNetworkPlots' vector with objects of type
% helperBLEMeshVisualizeNetwork
meshNetworkPlots(1, numberOfScenarios) = helperBLEMeshVisualizeNetwork;
for idx = 1:numberOfScenarios
    meshNetworkPlots(idx) = helperBLEMeshVisualizeNetwork;
    meshNetworkPlots(idx).NumberOfNodes = totalNodes;
    % Set type of allocation 'Grid' | 'UserInput'
    meshNetworkPlots(idx).NodePositionType = 'UserInput';
    % Set node positions based on number of nodes (applicable for
    % 'UserInput'), in meters
    meshNetworkPlots(idx).Positions = bleMeshNetworkNodePositions;
    % Set vicinity range based on node positions, in meters
    meshNetworkPlots(idx).VicinityRange = 25;
    % Set title
    meshNetworkPlots(idx).Title = ...
        ['Scenario ' num2str(idx) ': Bluetooth Mesh Flooding'];
end

%%
% *Configure simulation parameters:* Simulation parameters are configured
% as shown below. You can specify the number of source and destination
% pairs in the network using |srcDstPairs|. The simulation results contain
% the obtained paths corresponding to each source and destination pair. You
% can also view the network layer statistics at each node. However, in the
% displayed plot, you can visualize the results for the first three source
% and destination pairs.

% Simulation time, in milliseconds
simulationTime = 600;

% Enable/disable visualization
enableVisualization = true;

% Source and destination pairs
srcDstPairs = [1 7; 13 29];

% TTL values for packet originated at each source node
ttl = [25; 25];

%%
% *Simulations:* The functions
% <matlab:edit('helperBLEMeshFloodingSimulation')
% helperBLEMeshFloodingSimulation> and
% <matlab:edit('helperBLEMeshFloodingSimulationResults')
% helperBLEMeshFloodingSimulationResults> run the simulation and gather
% simulation results respectively.

%%
% * *Scenario one:* In this scenario, all the fifty nodes in the network
% are active. Some of these nodes are selected as relays. The plot shown
% below highlights the corresponding paths for each source and destination
% pair. Results containing the obtained paths are stored in
% |scenarioOneResults|.

% 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];

% Failed nodes (nodes that are out of network)
failedNodeIDs = [];

% Simulate the scenario
pathScenarioOne = helperBLEMeshFloodingSimulation(totalNodes, bleMeshNodes, meshNetworkPlots(1), ...
    simulationTime, srcDstPairs, ttl, relayNodeIDs, failedNodeIDs, ...
    enableVisualization);

%%

% Scenario result
scenarioOneResults = helperBLEMeshFloodingSimulationResults(srcDstPairs, pathScenarioOne)

%%
% * *Scenario two:* The network configuration is altered to demonstrate
% that there is an alternate path between the source and destination nodes.
% In this scenario, relay feature is disabled at the node 41. Whereas, the
% nodes 3 and 43 are removed from the network. The plot shown below
% highlights the corresponding paths for each source and destination pair.
% Results containing the obtained paths are stored in |scenarioTwoResults|.

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

% Failed nodes (nodes that are out of network)
failedNodeIDs = [3, 43];

% Simulate the scenario
pathScenarioTwo = helperBLEMeshFloodingSimulation(totalNodes, bleMeshNodes, meshNetworkPlots(2), ...
    simulationTime, srcDstPairs, ttl, relayNodeIDs, failedNodeIDs, ...
    enableVisualization);

%%

% Scenario result
scenarioTwoResults = helperBLEMeshFloodingSimulationResults(srcDstPairs, pathScenarioTwo)

%% Network Layer Statistics at Each Node
%
% The network layer statistics captured at each node are:
%
% * Number of messages transmitted from the node
% * Number of messages received by the node
% * Number of application Rx messages i.e. messages considered for further
% processing at the node
% * Number of messages relayed by the node
% * Number of messages dropped at the node
%
% The workspace variable |statisticsAtEachNode| contains cumulative network
% statistics of all the nodes for both the scenarios. 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:

statisticsAtEachNode = helperBLEMeshFloodingSimulationResults(bleMeshNodes);
statisticsForFirstFiveNodes = statisticsAtEachNode(1:min(5, totalNodes), :)

%% Further Exploration
%
% The Monte Carlo method [ <#23 3> ] is used for obtaining numerical
% results averaged over multiple simulations. Monte Carlo simulations are
% performed on the Bluetooth mesh network using these configuration
% parameters to analyze the probability of message delivery by modeling
% node failures.

% Source and destination nodes
srcDstPair = [16 12];

% TTL value for the message originated at the above source node
ttl = 25;

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

% Failed nodes (nodes that are out of network)
failedNodeIDs = [];

%%
% In each simulation, relay nodes are disabled randomly between the source
% and destination nodes, and the corresponding path is stored. These
% simulations are run by varying ten thousand seeds for the random number
% generator. The statistics observed after performing the Monte Carlo
% simulations are:
%
% * Probability of a message delivery from source to destination when relay
% nodes are failing randomly in the network
% * Average hop count needed between the source and destination nodes
% * Critical relays in having a path between source and destination
%
% For the above configuration, you can see the simulation results in the
% MAT file |bleMeshMonteCarloResults.mat|.

load('bleMeshMonteCarloResults.mat');
disp(['Probability of having a route between nodes ' num2str(srcDstPair(1)) ...
    ' and ' num2str(srcDstPair(2)) ' is: ' ...
    num2str(probabilityOfSuccess) '%']);
disp(['Average hop count between nodes ' num2str(srcDstPair(1)) ' and ' ...
    num2str(srcDstPair(2)) ' is: ' ...
    num2str(averageHopCount)]);
disp(['Apart from the vicinity nodes of node ' num2str(srcDstPair(1)) ...
    ' and node ' num2str(srcDstPair(2)) ', nodes [' num2str(criticalRelaysInfo{1:5, 1}') ...
    '] are the top five critical relays in having a path between them.']);
% Restore the previous setting of random number generation
rng(sprev);

%%
% You can run/modify <matlab:edit('helperBLEMeshMonteCarloSimulations')
% helperBLEMeshMonteCarloSimulations> script (long run simulation) for
% generating results through Monte Carlo simulations.

%%
% This example enables you to create and configure a multi-node Bluetooth
% mesh network and analyze the network layer flooding. To study the
% flooding behavior, two simulation scenarios are considered. In the first
% scenario, the path between source and destination nodes is identified and
% visualized by selecting some intermediate nodes as relay nodes. In the
% second scenario, some nodes (Relay and End) are dropped, and the relay
% feature for some of the relay nodes is disabled. The obtained results
% show that there exists a path between the source and destination nodes
% even if nodes (Relay and End) fail randomly in the network.
%
% This example allows you to create your own Bluetooth mesh network and
% visualize network flooding in it with statistics. Furthermore, you can
% also perform Monte Carlo simulations on the Bluetooth mesh network to
% obtain numerical results averaged over multiple iterations.

%% Appendix
%
% The example uses these helpers:
%
% * <matlab:edit('helperBLEMeshNetworkNode') helperBLEMeshNetworkNode>:
% Create an object for Bluetooth mesh node
% * <matlab:edit('helperBLEMeshNetworkLayer') helperBLEMeshNetworkLayer>:
% Create an object for Bluetooth mesh network layer functionality
% * <matlab:edit('helperBLEMeshNetworkPDU') helperBLEMeshNetworkPDU>:
% Generate Bluetooth mesh network PDU
% * <matlab:edit('helperBLEMeshNetworkPDUDecode')
% helperBLEMeshNetworkPDUDecode>: Decode Bluetooth mesh network PDU
% * <matlab:edit('helperBluetoothQueue') helperBluetoothQueue>: Create an
% object for Bluetooth queue functionality
% * <matlab:edit('helperBLEMeshRetransmissions')
% helperBLEMeshRetransmissions>: Create an object for retransmissions in
% Bluetooth mesh node
% * <matlab:edit('helperBLEMeshChannelMessage')
% helperBLEMeshChannelMessage>: Receive message from Bluetooth mesh network
% channel
% * <matlab:edit('helperBLEMeshPath') helperBLEMeshPath>: Derive path
% between source and destination within Bluetooth mesh network
% * <matlab:edit('helperBLEMeshVicinityNodes') helperBLEMeshVicinityNodes>:
% Get 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('helperBLEMeshFloodingSimulation')
% helperBLEMeshFloodingSimulation>: Simulate a Bluetooth mesh network
% * <matlab:edit('helperBLEMeshFloodingSimulationResults')
% helperBLEMeshFloodingSimulationResults>: Bluetooth mesh network
% simulation results
% * <matlab:edit('helperBLEMeshMonteCarloSimulations')
% helperBLEMeshMonteCarloSimulations>: Bluetooth mesh network Monte Carlo
% simulations

%% Selected Bibliography
%
% # Bluetooth Special Interest Group (SIG). "Bluetooth Core Specification".
% Version 5.0. https://www.bluetooth.com/.
% # Bluetooth Special Interest Group (SIG). "Bluetooth Mesh Profile".
% Version 1.0. https://www.bluetooth.com/.
% # Metropolis, Nicholas, and S. Ulam. "The Monte Carlo Method." _Journal
% of the American Statistical Association_ 44, no. 247 (September 1949):
% 335&ndash;41. https://doi.org/10.1080/01621459.1949.10483310.
