function messagingFrame = MessagingFrameGenerator(cfg)
%MessagingFrameGenerator Generate Smart Energy frames for the Messaging cluster
%   MESSAGINGFRAME = zigbee.MessagingFrameGenerator(CFG) generates ZigBee
%   frames for the Messaging cluster of the Smart Energy application
%   profile. The output frame MESSAGINGFRAME corresponds to the
%   configuration object CFG.
%
%   See also zigbee.MessagingFrameConfig, zigbee.MessagingFrameDecoder.

%   Copyright 2017-2023 The MathWorks, Inc.

switch cfg.CommandType
  case 'Display Message'
    % 1. Message Id
    messageID = int2bit(cfg.MessageID, 4*8, false);
    
    % 2. Message control
    messageControl = generateMessageControl(cfg);  
    
    % 3. Start time
    startTime = int2bit(cfg.StartTime, 4*8, false);
    
    % 4. Duration in minutes
    duration = int2bit(cfg.Duration, 2*8, false);
    
    % 5. Message
    lengthOfTheMessage = length(cfg.Message);
    message = zeros(8*length(cfg.Message) + 8, 1);
    message(1:8) = int2bit(lengthOfTheMessage, 8, false); % First octet contains the length of the message
    message(9:end) = zigbee.internal.encodeLabel(cfg.Message);
        
    % 7. Putting it all together:
    messagingFrame = [messageID; messageControl; startTime; duration; message];
    
  case 'Cancel Message'
    % 1. Message ID
    messageID = int2bit(cfg.MessageID, 4*8, false);
    
    % 2. Message control
    messageControl = generateMessageControl(cfg);
    
    % 3. Putting it all together:
    messagingFrame = [messageID; messageControl];
    
  case 'Get Last Message'
    
    messagingFrame = []; % There is no payload for this command
    
  case 'Message Confirmation'
    % 1. Message ID
    messageID = int2bit(cfg.MessageID, 4*8, false);
    
    % 2. Confirmation time
    confirmationTime = int2bit(cfg.ConfirmationTime, 4*8, false);
    
    % 5. Putting it all together
    messagingFrame   = [messageID; confirmationTime];
end
% Convert bits to bytes:
if ~isempty(messagingFrame)
  messagingFrame = zigbee.internal.bits2bytes(messagingFrame);
end
end

function messageControl = generateMessageControl(cfg)

  % 2. Message control
    messageControl = zeros(8, 1);
    
    % 2.1 Transmission type
    switch cfg.TransmissionType
      case 'Normal Transmission Only'
        messageControl(1:2) = [0 0];
      case 'Normal and Inter-PAN Transmission'
        messageControl(1:2) = [1 0];
      case 'Inter-PAN Transmission Only'
        messageControl(1:2) = [0 1];
    end
    
    % 2.2 Priority type
    switch cfg.Priority
      case 'Low'
        messageControl(3:4) = [0 0];
      case 'Medium'
        messageControl(3:4) = [1 0];
      case 'High'
        messageControl(3:4) = [0 1];
      case 'Critical'
        messageControl(3:4) = [1 1];
    end 
    
    % 2.4 Message confirmation
    messageControl(8) = double(cfg.MessageConfirmation);
    
end
