function [msgType, output] = helperBLEMeshTransportControlMessageDecode(transportControlMessage)
%helperBLEMeshTransportControlMessageDecode Decode Bluetooth mesh transport
%control message
%   [MSGTYPE, FSN] =
%   helperBLEMeshTransportControlMessageDecode(TRANSPORTCONTROLMESSAGE)
%   Bluetooth mesh transport control message (friend poll) corresponding to
%   the input parameter TRANSPORTCONTROLMESSAGE. Use this syntax to decode
%   friend poll message.
%
%   [MSGTYPE, MD] =
%   helperBLEMeshTransportControlMessageDecode(TRANSPORTCONTROLMESSAGE)
%   decodes Bluetooth mesh transport control message (friend update)
%   corresponding to the input parameter TRANSPORTCONTROLMESSAGE. Use this
%   syntax to decode friend update message.
%
%   MSGTYPE returns the type of the decoded transport control message as a
%   character vector either 'Friend poll' or 'Friend update'.
%
%   FSN is the decoded output of Bluetooth mesh friend poll message,
%   returned as either 0 or 1.
%
%   MD is the decoded output of Bluetooth mesh friend update message,
%   returned as a logical scalar.
%
%   TRANSPORTCONTROLMESSAGE is the Bluetooth mesh transport control message
%   of type column vector of decimal octets.

%   Copyright 2019 The MathWorks, Inc.

%#codegen

msgType = blanks(0);
output = -1;

% Validate the transport control message
validateattributes(transportControlMessage, {'numeric'}, {'vector', ...
    'nonempty'}, mfilename, 'transportControlMessage');
transportControlMessageSize = length(transportControlMessage);

% Validate the size of the transport control message
validateattributes(transportControlMessageSize, {'numeric'}, {'scalar', ...
    'integer', '>=', 2, '<=', 7}, mfilename, 'transportControlMessageSize');

if transportControlMessageSize == 2
    controlMessage = [transportControlMessage; zeros(5, 1)];
else
    controlMessage = [transportControlMessage; ...
        zeros(7-transportControlMessageSize, 1)];
end

% Convert octet0 of transport control message to binary
octet0 = comm.internal.utilities.de2biBase2LeftMSB(controlMessage ...
    (1), 8);

% segmented: '0b0' (no segmentation)
segmented = octet0(1);

% Transport control message is an unsegmented message
if ~segmented
    
    % opcode: '0b0000001' or '0b0000010'(Opcode field determines the format
    % of the parameters field)
    opcode = comm.internal.utilities.bi2deLeftMSB(octet0(2:8), 2);
    
    % Decode friend poll message
    if opcode == 1
        msgType = 'Friend Poll';
        
        % fsn: '0b0'(fsn is used to acknowledge receipt of previous
        % messages from the Friend node to the Low Power node)
        fsn = comm.internal.utilities.de2biBase2LeftMSB( ...
            controlMessage(2), 8);
        
        output = fsn(8);
        
    % Decode friend update message
    elseif opcode == 2   
        msgType = 'Friend Update';
        
        % moredata: '0b00000000' (Set to 0 if friend queue is empty and set
        % to 1 if friend queue is not empty)
        moreData = controlMessage(7);
        
        % Validate moredata
        if moreData > 1
            fprintf('Valid values of more data field are either 0 or 1');
        else
            output = moreData;
        end
        
    % Other transport control message
    else
        fprintf(['helperBLEMeshTransportControlMessageDecode function' ...
            ' decodes either friend poll or friend update message']);
    end
    
% Transport control message is a segmented message    
else
    fprintf(['helperBLEMeshTransportControlMessageDecode function does not' ...
        ' support decoding of segmented transport control message']);
end
end