%% BLE Channel Selection Algorithms
%
% This example shows how to select a channel index using the channel
% selection algorithms specified in the Bluetooth(R) Low Energy (BLE) core
% specification [ <#28 1> ] using the Communications Toolbox(TM) Library
% for the Bluetooth(R) Protocol.

% Copyright 2018 The MathWorks, Inc.

%% BLE channels
%
% The BLE system operates in the 2.4 GHz ISM band at 2400 - 2483.5 MHz. It
% uses forty RF channels (each channel is 2 MHz wide). The figure below
% shows the mapping between the frequencies and BLE channels. Each of these
% RF channels is allocated a unique channel index (labelled as "BLE
% Channel" in the figure).
%
% <<../BLEChannels.png>>
%
% BLE classifies these forty RF channels into three advertising channels
% (channel indices: 37, 38, 39) and thirty-seven data channels (channel
% indices: 0 to 36). Note that the advertising channels are spread across
% the 2.4 GHz spectrum. The purpose of this wide spacing is to avoid
% interference from other devices operating in the same spectrum, such as
% WLAN. Advertising channels are mainly used for transmitting advertising
% packets, scan request/response packets and connection indication packets.
% Data channels are mainly used for exchanging data packets.

%% Channel Hopping
%
% Channel hopping is used in Bluetooth to reduce interference and improve
% throughput. The Bluetooth standard defines rules for switching between
% channels and algorithms used when performing channel hopping.
%
% Use of the unlicensed 2.4GHz ISM band by several wireless technologies
% causes increased interference and results in retransmissions to correct
% errors in received packets. Since BLE is a low energy oriented protocol,
% it is more susceptible to interference. BLE uses channel hopping to
% combat the impact of interference. When one channel is completely blocked
% due to interference, devices can still continue to communicate with each
% other on other channels.
%
% In classic Bluetooth, channel hopping is restricted to 1600 frequency
% hops/sec. For BLE, the channel hopping specification has been revised.
% Different rules apply for advertising and connected devices, and two
% channel selection algorithms are defined.
%
% An advertising device transmits advertising packets on the three
% advertising channels in a cyclic manner (starting from channel index 37).
% The same procedure is used by the scanning/initiating device, listening
% on the three advertising channels in a cyclic manner.
%
% A connected device changes to a new data channel for every connection
% event. A connection event is a sequence of data packet exchanges between
% two connected devices. The connection events occur periodically with an
% interval called connection interval. All the packets within a connection
% event are transmitted on the same data channel. A new connection event
% uses a new data channel.
%
% Two alternative channel selection algorithms are specified by the
% Bluetooth core specification (see Section 4.5.8, Part-B, Vol-6 of [ <#28
% 1> ]) can be used to select data channels for each connection event:
%
% # Algorithm #1
% # Algorithm #2
%
% The two channel selection algorithms avoid channels that are prone to
% transmission errors. A channel map is exchanged between the master and
% slave devices. This map indicates the good and bad data channels. The
% classification of good and bad data channels is implementation dependent
% and can be done based on various parameters like SNR (Signal-To-Noise
% Ratio), PER (Packet Error Rate), etc. Only the good data channels are
% used for communication between devices. The channel map will be updated
% by the master device if it recognizes any bad data channels. The two
% channel selection algorithms use the channel map to determine whether the
% selected data channel is good to use. If the selected data channel turns
% out to be bad, a new data channel is selected using channel remapping
% procedure (see Section 4.5.8, Part-B, Vol-6 of [ <#28 1> ]), which remaps
% the bad data channel to one of the good data channels. Each algorithm has
% a remapping procedure of its own.

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

%% Simulating Algorithm #1
%
% You can use <matlab:help('bleChannelSelection') bleChannelSelection>
% System object to select a new channel index. This System object
% configures the fields required for selecting a channel index.
%
% *Create a System object for 'Algorithm #1'*
%
% To select a channel index, create a <matlab:help('bleChannelSelection')
% bleChannelSelection> System object with |Algorithm| set to 1.

csa = bleChannelSelection('Algorithm', 1);
%%
% Configure the fields.
%
% * The |HopIncrement| property defines the hop increment count to be
% used. The default value is 5. This property is applicable for 'Algorithm
% #1'.
%
% * The |UsedChannels| property defines the list of used (good) data
% channels.

csa.HopIncrement = 8;
csa.UsedChannels = [0, 5, 13, 9, 24, 36]

%%
% * |ChannelIndex| is a read-only property that indicates the current
% channel being used.
%
% * |EventCounter| is a read-only property that indicates the number of
% connection events occurred until now. It is incremented for every new
% selected channel.
%
% *Select a channel index for next hop*
%
% Call the object |csa| as a function to determine the next channel hop and
% to select a new channel for each new connection event.

nextChannel = csa();
fprintf('Selected channel for connection event %d using ''Algorithm #1'' is: %d\n', csa.EventCounter, nextChannel);

%% Simulating Algorithm #2
%
% You can use <matlab:help('bleChannelSelection') bleChannelSelection>
% System object to select a new channel index. This System object
% configures the fields required for selecting a channel index.
%
% *Create a System object for 'Algorithm #2'*
%
% To select a channel index, Create a <matlab:help('bleChannelSelection')
% bleChannelSelection> System object with |Algorithm| set to 2.

csa = bleChannelSelection('Algorithm', 2);

%%
% Configure the fields.
%
% * The |AccessAddress| property defines the 32-bit unique connection
% address between two devices. The default value is '8E89BED6'. This
% property is applicable for 'Algorithm #2'.
%
% * The |UsedChannels| property defines the list of used (good) data
% channels.

csa.AccessAddress = 'E89BED68';
csa.UsedChannels = [9, 10, 21, 22, 23, 33, 34, 35, 36]

%%
% *Select a channel index for next hop*
%
% Call the object |csa| as a function to determine the next channel hop and
% to select a new channel for each new connection event.

nextChannel = csa();
fprintf('Selected channel for connection event %d using ''Algorithm #2'' is: %d\n', csa.EventCounter, nextChannel);

%% GUI for analyzing Channel Selection Algorithms
%
% The function <matlab:edit('helperBLEChannelHopSelectionUI')
% helperBLEChannelHopSelectionUI> provides a graphical user interface to
% generate desired number of channel hops for analyzing the algorithm. Both
% channel selection algorithms can be analyzed using this GUI. It can be
% used to plot the channel hopping pattern of an algorithm and also plots
% the corresponding histogram.

helperBLEChannelHopSelectionUI()

%% Algorithm verification with sample data
% Sample data is provided to verify Algorithm #2 (see Section 3, Vol 6,
% Part C in [ <#28 1> ]). However, there is no sample data available for
% verifying Algorithm #1.
%
% *Sample data 1 (thirty-seven good data channels)*
%
% # Access Address = 8E89BED6
% # Used Channels  = [0:36]
%
% When the above inputs are used, the Algorithm #2 is expected to select
% the following channels according to Section 3.1, Part-B, Vol-6 of [ <#28
% 1> ]

%%
% <html>
% <table border="1">
% <tr> <td> <b> EventCounter </b> </td>  <td> <b> Channel </b> </td> </tr>
% <tr> <td> 1 </td> <td> 20 </td> </tr>
% <tr> <td> 2 </td> <td> 6 </td> </tr>
% <tr> <td> 3 </td> <td> 21 </td> </tr>
% </table>
% </html>

%%
% The following code selects three channels for the first three
% connection events.

% Create a System object for 'Algorithm #2'
csa = bleChannelSelection('Algorithm', 2);

%%
% Configure the fields with sample data #1.

% Connection access address
csa.AccessAddress = '8E89BED6';
% Use 37 good data channels as used channels according to the sample data
csa.UsedChannels = (0:36);

%%
% Select channel indices for first 3 connection events. Verify the
% generated outputs with the table mentioned above.
numConnectionEvents = 3;
for i = 1:numConnectionEvents
    channel = csa();
    fprintf('Event Counter: %d, selected Channel: %d\n', csa.EventCounter, channel);
end

%%
% *Sample data 2 (nine good data channels)*
%
% # Access Address = 8E89BED6
% # Used Channels  = [9, 10, 21, 22, 23, 33, 34, 35, 36]
%
% When the above inputs are used, the Algorithm #2 is expected to select
% the following channels according to Section 3.2, Part-B, Vol-6 of [ <#28
% 1> ]. Since the channel map contains bad channels, the channel remapping
% procedure used in the algorithm is also verified.

%%
% <html>
% <table border="1">
% <tr> <td> <b> EventCounter </b> </td>  <td> <b> Channel </b> </td> </tr>
% <tr> <td> 6 </td> <td> 23 </td> </tr>
% <tr> <td> 7 </td> <td> 9 </td> </tr>
% <tr> <td> 8 </td> <td> 34 </td> </tr>
% </table>
% </html>

%%
% The following code selects eight channels for the first eight
% connection events.

% Create a System object for 'Algorithm #2'
csa = bleChannelSelection('Algorithm', 2);

%%
% Configure the fields with sample data #2.

% Connection access address
csa.AccessAddress = '8E89BED6';
% Use 9 good data channels as used channels according to the sample data
csa.UsedChannels = [9, 10, 21, 22, 23, 33, 34, 35, 36];

%%
% Select channel indices for first 8 connection events. Verify the
% generated outputs with the table mentioned above.
numConnectionEvents = 8;
for i = 1:numConnectionEvents
    channel = csa();
    fprintf('Event Counter: %d, selected Channel: %d\n', csa.EventCounter, channel);
end

%% Plot and analyze the hopping pattern - Algorithm #1 and Algorithm #2
%
% The following code selects channel indices for the first hundred
% connection events using 'Algorithm #1'. The selected channels are
% plotted and compared with those of 'Algorithm #2'.

% Channel selection algorithm System object for 'Algorithm #1'
csa = bleChannelSelection;
% For 100 connection events
numConnectionEvents = 100;
hopSequence = zeros(1, numConnectionEvents);
% Generate channel hop sequence for 100 connection events
for i = 1:numConnectionEvents
    hopSequence(i) = csa();
end

%%
% The <matlab:edit('helperBLEPlotChannelHopSequence')
% helperBLEPlotChannelHopSequence> function plots the hopping pattern and
% also outputs a histogram of the selected channels.
helperBLEPlotChannelHopSequence(csa, hopSequence);

%%
% The following code generates channel indices for the first hundred
% connection events using 'Algorithm #2'. The selected channels are plotted
% and compared with those of 'Algorithm #1'.

% Channel selection algorithm System object for 'Algorithm #2'
csa = bleChannelSelection('Algorithm', 2);
% For 100 connection events
numConnectionEvents = 100;
hopSequence = zeros(1, numConnectionEvents);
% Generate channel hop sequence for 100 connection events
for i = 1:numConnectionEvents
    hopSequence(i) = csa();
end

%%
% The <matlab:edit('helperBLEPlotChannelHopSequence')
% helperBLEPlotChannelHopSequence> function plots the hopping pattern and
% also outputs a histogram of the selected channels.
helperBLEPlotChannelHopSequence(csa, hopSequence);

%%
%
% *Algorithm #1 vs Algorithm #2*
%
% The above plots show the difference between the two algorithms.
%
% * Algorithm #1 is a simple incremental algorithm that produces a uniform
% sequence of channels. There is no randomization involved in the process
% of selecting a new channel.
%
% * Algorithm #2 was introduced in version 5.0 of the Bluetooth Core
% Specification [ <#28 1> ]. Compared to Algorithm #1, this is more complex
% and produces a randomized sequence of channels.

%% Conclusion
%
% This example demonstrated the behavior of the channel selection
% algorithms specified in the Bluetooth core specification [ <#28 1> ].

%% Appendix
%
% This example uses the following helper functions
%
% * <matlab:edit('helperBLEChannelHopSelectionUI') helperBLEChannelHopSelectionUI>
% * <matlab:edit('helperBLEPlotChannelHopSequence') helperBLEPlotChannelHopSequence>

%% Selected Bibliography
%
% # Bluetooth SIG, Bluetooth core specification v5.0: https://www.bluetooth.com/
% # IEEE Standard 802.15.2(TM)-2003
