function hdlcoder_receivedFullMPDUGUI(header, mpdu, plcpCRC, mpduCRC, resetGUI, ...
  openGUI, figPos)
%hdlcoder_receivedFullMPDUGUI Display and update MPDU figure
%   hdlcoder_receivedFullMPDUGUI(H, B, PLCPCRC, MPDUCRC, R) displays and updates the
%   received MPDU contents figure for the 802.11 WLAN Beacon Frame receiver
%   with captured data example. H and B are structures that hold the MPDU
%   frame header and body contents. PLCPCRC and MPDUCRC are CRC values
%   for the PLCP and the MPDU frames. When R is set to 1, the GUI resets
%   the PLCP and MPDU CRC states to error.

%   Copyright 2012 The MathWorks, Inc.

persistent hGUI handles

if (openGUI == true)
  
  if (isempty(hGUI) || ~ishghandle(hGUI))
    [hGUI, handles] = renderGUI(figPos);
  end
  
  if resetGUI
    figure(hGUI)
    plcpCRC = true;
    mpduCRC = true;
  end
  
  updateGUI(handles, header, mpdu, plcpCRC, mpduCRC);
end

end

%--------------------------------------------------------------------------
function updateGUI(handles, header, mpdu, plcpCRC, mpduCRC)

persistent icons

if isempty(icons)
  icons = load('hdlcoder_comm80211RxIcons');
end

% Set CRC icons
if plcpCRC
  icon = icons.errorIcon;
else
  icon = icons.checkIcon;
end
image(icon, 'Parent', handles.PlcpCRCFig);

if mpduCRC
  icon = icons.errorIcon;
else
  icon = icons.checkIcon;
end
image(icon, 'Parent', handles.MpduCRCFig)

if ~plcpCRC && ~mpduCRC
  % Set frame control
  switch header.FrameCtrl.Type
    case 0
      typeStr = 'Management';
      switch header.FrameCtrl.Subtype
        case 0
          subTypeStr = 'Association request';
        case 1
          subTypeStr = 'Association response';
        case 2
          subTypeStr = 'Reassociation request';
        case 3
          subTypeStr = 'Reassociation response';
        case 4
          subTypeStr = 'Probe request';
        case 5
          subTypeStr = 'Probe response';
        case 6
          subTypeStr = 'Reserved';
        case 7
          subTypeStr = 'Reserved';
        case 8
          subTypeStr = 'Beacon';
        case 9
          subTypeStr = 'ATIM';
        case 10
          subTypeStr = 'Disassociation';
        case 11
          subTypeStr = 'Authentication';
        case 12
          subTypeStr = 'Deauthentication';
        case 13
          subTypeStr = 'Action';
        otherwise
          subTypeStr = 'Reserved';
      end
    case 1
      typeStr = 'Control';
      switch header.FrameCtrl.Subtype
        case 8
          subTypeStr = 'Block Ack Request';
        case 9
          subTypeStr = 'Block Ack';
        case 10
          subTypeStr = 'PS-Poll';
        case 11
          subTypeStr = 'RTS';
        case 12
          subTypeStr = 'CTS';
        case 13
          subTypeStr = 'ACK';
        case 14
          subTypeStr = 'CF-End';
        case 15
          subTypeStr = 'CF-End + CF-Ack';
        otherwise
          subTypeStr = 'Reserved';
      end
    case 2
      typeStr = 'Data';
      switch header.FrameCtrl.Subtype
        case 0
          subTypeStr = 'Data';
        case 1
          subTypeStr = 'Data + CF-Ack';
        case 2
          subTypeStr = 'Data + CF-Poll';
        case 3
          subTypeStr = 'DATA + CF-Ack + CF-Pall';
        case 4
          subTypeStr = 'Null';
        case 5
          subTypeStr = 'CF-Ack (no data)';
        case 6
          subTypeStr = 'CF-Poll (no data)';
        case 7
          subTypeStr = 'CF-Ack + CF-Poll (no data)';
        case 8
          subTypeStr = 'QoS Data';
        case 9
          subTypeStr = 'QoS Data + CF-Ack';
        case 10
          subTypeStr = 'QoS Data + CF-Poll';
        case 11
          subTypeStr = 'QoS Data + CF-Ack + CF-Poll';
        case 12
          subTypeStr = 'QoS Null';
        case 13
          subTypeStr = 'Reserved';
        case 14
          subTypeStr = 'QoS CF-Poll (no data)';
        case 15
          subTypeStr = 'QoS CF-Ack + CF-Poll (no data)';
      end
  end
  
  data = {double(header.FrameCtrl.ProtocolVersion), ''; ...
    double(header.FrameCtrl.Type), typeStr; ...
    double(header.FrameCtrl.Subtype), subTypeStr; ...
    double(header.FrameCtrl.ToDS), ''; ...
    double(header.FrameCtrl.FromDS), ''; ...
    double(header.FrameCtrl.MoreFragments), ''; ...
    double(header.FrameCtrl.Retry), ''; ...
    double(header.FrameCtrl.PowerManagement), ''; ...
    double(header.FrameCtrl.MoreData), ''; ...
    double(header.FrameCtrl.ProtectedFrame), ''; ...
    double(header.FrameCtrl.Order), ''; ...
    };
  set(handles.FrameCtrl, 'Data', data);
  
  if all(header.Address1 == 255)
    addressStr = 'Broadcast';
  else
    addressStr = '';
  end
  
  % Set MAC Header rest
  data = {oct2hex(header.DurationID), ''; ...
    oct2hex(header.Address1), addressStr; ...
    oct2hex(header.Address2), ''; ...
    oct2hex(header.Address3), ''; ...
    '', ''; ...
    mat2str(bitand(header.SequenceControl(1), 240)), ''; ...
    mat2str(bitand(header.SequenceControl(1), 15)*2^8 + ...
    header.SequenceControl(2)), ''; ...
    };
  set(handles.HeaderRest, 'Data', data);
  
  % Set frame body rest
  data = {oct2dec(mpdu.TimeStamp); ...
    oct2dec(mpdu.BeaconInterval)};
  set(handles.FrameBodyRest, 'Data', data);
  
  % Set capability
  if mpdu.Capability.Privacy
    privacyStr = 'Secured';
  else
    privacyStr = 'Open';
  end
  
  data = {double(mpdu.Capability.ESS), 'Access point'; ...
    double(mpdu.Capability.IBSS), 'Ad-hoc';...
    double(mpdu.Capability.CFPollable), ''; ...
    double(mpdu.Capability.CFPollRequest), ''; ...
    double(mpdu.Capability.Privacy), privacyStr; ...
    double(mpdu.Capability.ShortPreamble), ''; ...
    double(mpdu.Capability.PBCC), ''; ...
    double(mpdu.Capability.ChannelAgility), ''; ...
    double(mpdu.Capability.SpectrumManagement), ''; ...
    double(mpdu.Capability.QoS), ''; ...
    double(mpdu.Capability.ShortSlotTime), ''; ...
    double(mpdu.Capability.APSD), ''; ...
    double(mpdu.Capability.Reserved), ''; ...
    double(mpdu.Capability.DSSOFDM), ''; ...
    double(mpdu.Capability.DelayedBlockAck), ''; ...
    double(mpdu.Capability.ImmediateBlockAck), ''};
  set(handles.Capability, 'Data', data);
  
  data = cell(mpdu.NumInfoElements,1);
  rowLabel = cell(mpdu.NumInfoElements,1);
  rowCnt = 1;
  subPrefix = ' * ';
  for p=1:mpdu.NumInfoElements
    switch mpdu.InfoElements(p).ID
      case 0  % SSID
        rowLabel{rowCnt, 1} = 'SSID';
        data{rowCnt, 1} = ...
          char(mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length));
      case 1  % Supported Rates
        rowLabel{rowCnt, 1} = 'Supported Rates';
        data{rowCnt, 1} = mat2str(getSupportedRates( ...
          mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length)));
      case 2  % FH Parameters
        rowLabel{rowCnt, 1} = 'FH Parameter Set';
        value = mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length);
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Dwell Time (TU)'];
        data{rowCnt, 1} = mat2str(oct2dec(value(1:2)));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Hop Set'];
        data{rowCnt, 1} = mat2str(value(3));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Hop Pattern'];
        data{rowCnt, 1} = mat2str(value(4));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Hop Index'];
        data{rowCnt, 1} = mat2str(value(5));
      case 3  % DS Parameters
        rowLabel{rowCnt, 1} = 'DS Parameter Set';
        data{rowCnt, 1} = ...
          mat2str(mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length));
      case 4  % CF Parameters
        rowLabel{rowCnt, 1} = 'CF Parameter Set';
        value = mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length);
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'CFP Count'];
        data{rowCnt, 1} = mat2str(value(1));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'CFP Period'];
        data{rowCnt, 1} = mat2str(value(2));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'CFP Max Duration'];
        data{rowCnt, 1} = mat2str(value(3));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'CFP Dur Remaining'];
        data{rowCnt, 1} = mat2str(value(4));
      case 5  % TIM
        rowLabel{rowCnt, 1} = 'TIM';
        value = mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length);
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'DTIM Count'];
        data{rowCnt, 1} = mat2str(value(1));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'DTIM Period'];
        data{rowCnt, 1} = mat2str(value(2));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Bitmap Control'];
        data{rowCnt, 1} = mat2str(value(3));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Partial Virtual Bitmap'];
        data{rowCnt, 1} = mat2str(value(4:end));
      case 6  % IBSS Parameters
        rowLabel{rowCnt, 1} = 'IBSS Parameter Set';
        data{rowCnt, 1} = mat2str(...
          oct2dec(mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length)));
      case 7 % Country
      case 8 % Hopping pattern
      case 9 % Hopping table
      case 32 % Power constraint
      case 37 % Channel switch announcement
      case 40 % Quite
      case 41 % IBSS DFS
      case 35 % TPC report
      case 42 % ERP information
        rowLabel{rowCnt, 1} = 'ERP Information';
        value = mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length);
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'NonERP Present'];
        data{rowCnt, 1} = mat2str(bitget(value(1),8));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Use Protection'];
        data{rowCnt, 1} = mat2str(bitget(value(1),7));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Barker preamble mode'];
        data{rowCnt, 1} = mat2str(bitget(value(1),6));
      case 50 % Extended supported rates
        rowLabel{rowCnt, 1} = 'Extended Supported Rates';
        data{rowCnt, 1} = mat2str(getSupportedRates( ...
          mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length)));
      case 48 % RSN
      case 11 % BSS load
      case 12 % EDCA parameter set
      case 46 % QoS capability
      case 221 % Vendor specific
        rowLabel{rowCnt, 1} = 'Vendor Specific';
        value = mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length);
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'OUI'];
        data{rowCnt, 1} = mat2str(value(1:3));
        rowCnt = rowCnt + 1;
        rowLabel{rowCnt, 1} = [subPrefix 'Content'];
        data{rowCnt, 1} = mat2str(value(4:end));
      otherwise % Reserved
        rowLabel{rowCnt, 1} = 'Reserved';
        data{rowCnt, 1} = mat2str(...
          mpdu.InfoElements(p).Value(1:mpdu.InfoElements(p).Length));
    end
    rowCnt = rowCnt+1;
  end % FOR
  
  set(handles.InfoElemTable, 'Data', data);
  set(handles.InfoElemTable, 'RowName', rowLabel);
end
end % function updateGUI

%--------------------------------------------------------------------------
function [hGUI, handles] = renderGUI(figPos)

margin = 5;
panelMargin = 10;

hGUI = figure('Position', figPos, ...
  'Visible', 'off', ...
  'HandleVisibility', 'off', ...
  'Color', [0.8 0.8 0.8], ...
  'MenuBar', 'none', ...
  'Name', '802.11 Beacon Frame', ...
  'IntegerHandle', 'off', ...
  'NumberTitle', 'off', ...
  'Tag', '802.11 Beacon Frame');

% Create main container
hMain = uicontainer('Parent', hGUI);

% Create the main grid
hGrid = siglayout.gridbaglayout(hMain);
hGrid.VerticalGap = 1;
hGrid.HorizontalGap = 5;
hGrid.VerticalWeights = [0 0 1];

% Create information container
hInfoContainer = uicontainer(hGUI);
add(hGrid, hInfoContainer, 3, 1, ...
  'Fill', 'Both', ...
  'MinimumHeight', 100, ...
  'MinimumWidth', 230);


%==========================================================================
% MAC Header Panel
hMACHeader = uipanel(hInfoContainer, ...
  'Title', '', ...
  'Units', 'normalized', ...
  'Position', [0 0 1 1], ...
  'Tag', 'macheader');

hMACHeaderGrid = siglayout.gridbaglayout(hMACHeader);
hMACHeaderGrid.VerticalGap = margin;
hMACHeaderGrid.HorizontalGap = margin;
hMACHeaderGrid.VerticalWeights = [0.64 0.36];

%--------------------------------------------------------------------------
% MAC Header except Frame Ctrl
rowLabels = {'Duration/ID', 'DA', 'SA', 'BSSID', 'Sequence control', ...
  ' * Fragment #', ' * Sequence #'};
columnLabels = {'Value', 'Explanation'};
data = repmat({'', ''}, length(rowLabels), 1); 
columnWidth = {150, 80};
handles.HeaderRest = uitable(hMACHeader, ...
  'RowName', rowLabels, ...
  'ColumnName', columnLabels, ...
  'Data', data, ...
  'Tag', 'HeaderRest', ...
  'ColumnWidth', columnWidth);
add(hMACHeaderGrid, handles.HeaderRest, 2, 1, 'Fill', 'Both');

%--------------------------------------------------------------------------
% Frame Ctrl
hFrameCtrlPanel = uipanel(hMACHeader, ...
  'Title', 'Frame Control', ...
  'Tag', 'framectrlpanel');
add(hMACHeaderGrid, hFrameCtrlPanel, 1, 1, 'Fill', 'Both');

rowLabels = {'Protocol version', 'Type', 'Subtype', 'To DS', 'From DS', ...
  'More fragments', 'Retry', 'Power management', 'More data', ...
  'Protected frame', 'Order'};
data = repmat({0, ''}, length(rowLabels), 1);
columnWidth = {50, 180};
handles.FrameCtrl = uitable(hFrameCtrlPanel, ...
  'RowName', rowLabels, ...
  'ColumnName', columnLabels, ...
  'Data', data, ...
  'Tag', 'FrameCTRL', ...
  'ColumnWidth', columnWidth);

hFrameCtrlGrid = siglayout.gridbaglayout(hFrameCtrlPanel);
hFrameCtrlGrid.VerticalGap = panelMargin + margin;
hFrameCtrlGrid.HorizontalGap = margin;
add(hFrameCtrlGrid, handles.FrameCtrl, 1, 1, 'Fill', 'Both');

%==========================================================================
% Frame Body Panel
hFrameBody = uipanel(hInfoContainer, ...
  'Title', '', ...
  'Units', 'normalized', ...
  'Position', [0 0 1 1], ...
  'Tag', 'framebody', ...
  'Visible', 'off');

hFrameBodyGrid = siglayout.gridbaglayout(hFrameBody);
hFrameBodyGrid.VerticalGap = margin;
hFrameBodyGrid.HorizontalGap = margin;
hFrameBodyGrid.VerticalWeights = [0.20 0.80];
%--------------------------------------------------------------------------
% Capability
hCapabilityPanel = uipanel(hFrameBody, ...
  'Title', 'Capability', ...
  'Tag', 'capabilitypanel');
add(hFrameBodyGrid, hCapabilityPanel, 2, 1, 'Fill', 'Both');

rowLabels = {'ESS', 'IBSS', 'CF pollable', 'CF poll request', 'Privacy', ...
  'Short preamble', 'PBCC', 'Channel agility', 'Spectrum management', ...
  'QoS', 'Short time slot', 'APSD', 'Reserved', 'DSSS-OFDM', ...
  'Delayed block ACK', 'Immediate block ACK'};
data = repmat({0, ''}, length(rowLabels), 1);
columnWidth = {50, 150};
handles.Capability = uitable(hCapabilityPanel, ...
  'RowName', rowLabels, ...
  'ColumnName', columnLabels, ...
  'Data', data, ...
  'Tag', 'Capability', ...
  'ColumnWidth', columnWidth);

hCapabilityGrid = siglayout.gridbaglayout(hCapabilityPanel);
hCapabilityGrid.VerticalGap = panelMargin + margin;
hCapabilityGrid.HorizontalGap = margin;
add(hCapabilityGrid, handles.Capability, 1, 1, 'Fill', 'Both');

%--------------------------------------------------------------------------
% Frame body except Capability
rowLabels = {'Time stamp', 'Beacon interval (TU)'};
columnLabels = {'Value'};
data = zeros(length(rowLabels), 1);
columnWidth = {190};
handles.FrameBodyRest = uitable(hFrameBody, ...
  'RowName', rowLabels, ...
  'ColumnName', columnLabels, ...
  'Data', data, ...
  'Tag', 'FrameBodyRest', ...
  'ColumnWidth', columnWidth);
add(hFrameBodyGrid, handles.FrameBodyRest, 1, 1, 'Fill', 'Both');

%==========================================================================
% Information Elements Panel
hInfoElem = uipanel(hInfoContainer, ...
  'Title', '', ...
  'Units', 'normalized', ...
  'Position', [0 0 1 1], ...
  'Tag', 'infoelem', ...
  'Visible', 'off');

hInfoElemGrid = siglayout.gridbaglayout(hInfoElem);
hInfoElemGrid.VerticalGap = margin;
hInfoElemGrid.HorizontalGap = margin;

rowLabels = {''};
columnLabels = {'Value'};
data = zeros(length(rowLabels), 1);
columnWidth = {200, 150};
handles.InfoElemTable = uitable(hInfoElem, ...
  'RowName', rowLabels, ...
  'ColumnName', columnLabels, ...
  'Data', data, ...
  'Tag', 'InfoElemTable', ...
  'ColumnWidth', columnWidth);
add(hInfoElemGrid, handles.InfoElemTable, 1, 1, 'Fill', 'Both');

%==========================================================================
% Tab buttons
hTabButons = uicontainer('Parent', hMain);
buttonHeight = 30;
buttonWidth = 140;
add(hGrid, hTabButons, 2, 1, ...
  'Fill', 'Both', ...
  'MinimumHeight', buttonHeight+2*margin, ...
  'MinimumWidth', 3*buttonWidth+4*margin);

macHeaderButtonX = margin;
macHeaderButtonY = margin;
hMACHeaderButton = uicontrol(hTabButons, 'Style', 'togglebutton', ...
  'String', 'MAC Header', ...
  'Tag', 'macheaderbutton', ...
  'Value', true, ...
  'Units', 'pixels', ...
  'Position', [macHeaderButtonX macHeaderButtonY ...
  buttonWidth buttonHeight]);

frameBodyButtonX = macHeaderButtonX + buttonWidth;
hFrameBodyButton = uicontrol(hTabButons, 'Style', 'togglebutton', ...
  'String', 'Frame Body', ...
  'Tag', 'framebodybutton', ...
  'Units', 'pixels', ...
  'Position', [frameBodyButtonX macHeaderButtonY ...
  buttonWidth buttonHeight]);

infoElemButtonX = frameBodyButtonX + buttonWidth;
hInfoElemButton = uicontrol(hTabButons, 'Style', 'togglebutton', ...
  'String', 'Information Elements', ...
  'Tag', 'infoelembutton', ...
  'Units', 'pixels', ...
  'Position', [infoElemButtonX macHeaderButtonY ...
  buttonWidth buttonHeight]);

set(hMACHeaderButton, 'Callback', ...
  @(src,data)buttoncb(src,...
  hMACHeaderButton,hFrameBodyButton,hInfoElemButton, ...
  hMACHeader, hFrameBody, hInfoElem));
set(hFrameBodyButton, 'Callback', ...
  @(src,data)buttoncb(src,...
  hMACHeaderButton,hFrameBodyButton,hInfoElemButton, ...
  hMACHeader, hFrameBody, hInfoElem));
set(hInfoElemButton, 'Callback', ...
  @(src,data)buttoncb(src,...
  hMACHeaderButton,hFrameBodyButton,hInfoElemButton, ...
  hMACHeader, hFrameBody, hInfoElem));

%==========================================================================
% CRCs
hCRCs = uicontainer('Parent', hMain);
textHeight = 12;
textWith = 125;
add(hGrid, hCRCs, 1, 1, ...
  'Fill', 'Both', ...
  'MinimumHeight', textHeight+2*margin, ...
  'MinimumWidth', 3*buttonWidth+4*margin);

plcpCRCTextX = margin;
plcpCRCTextY = margin;
hPlcpCRCText = uicontrol(hCRCs, 'Style', 'Text', ...
  'String', 'PLCP CRC: ', ...
  'Tooltip', 'Physical Layer Convergence Procedure', ...
  'HorizontalAlignment', 'left', ...
  'Tag', 'plcpcrctext', ...
  'Units', 'pixels', ...
  'Position', [plcpCRCTextX plcpCRCTextY ...
  textWith textHeight]);

handles.PlcpCRCFig = axes('Parent', hCRCs, ...
  'HandleVisibility', 'off', ...
	'XTick', [], ...
  'YTick', [], ...
  'Color', get(hPlcpCRCText, 'BackgroundColor'), ...
	'Xcolor', get(hPlcpCRCText, 'BackgroundColor'), ...
	'Ycolor', get(hPlcpCRCText, 'BackgroundColor'), ...
  'NextPlot', 'add', ...
  'YDir', 'reverse', ...
  'Tag', 'plcpcrcfig', ...
  'Units', 'pixels', ...
  'Position', [plcpCRCTextX+textWith plcpCRCTextY ...
  textHeight textHeight]);

mpduCRCTextX = infoElemButtonX;
mpduCRCTextY = plcpCRCTextY;
hMpduCRCText = uicontrol(hCRCs, 'Style', 'Text', ...
  'String', 'MPDU CRC: ', ...
  'Tooltip', 'MAC Protocol Data Unit', ...
  'HorizontalAlignment', 'left', ...
  'Tag', 'mpduheadercrctext', ...
  'Units', 'pixels', ...
  'Position', [mpduCRCTextX mpduCRCTextY ...
  textWith textHeight]); %#ok<NASGU>

handles.MpduCRCFig = axes('Parent', hCRCs, ...
  'HandleVisibility', 'off', ...
	'XTick', [], ...
  'YTick', [], ...
  'Color', get(hPlcpCRCText, 'BackgroundColor'), ...
	'Xcolor', get(hPlcpCRCText, 'BackgroundColor'), ...
	'Ycolor', get(hPlcpCRCText, 'BackgroundColor'), ...
  'NextPlot', 'add', ...
  'YDir', 'reverse', ...
  'Tag', 'mpduheadercrcfig', ...
  'Units', 'pixels', ...
  'Position', [mpduCRCTextX+textWith mpduCRCTextY ...
  textHeight textHeight]);

set(hGUI, 'Visible', 'on');
end % function renderGUI

%--------------------------------------------------------------------------
function out = oct2dec(in)
  out = double(in) * 256.^(0:length(in)-1)';
end

%--------------------------------------------------------------------------
function out = oct2hex(in)
l = length(in);
out = char(zeros(1, 2*l+l-1));
cnt = 1;
for p=1:l
  out(cnt+(0:1)) = dec2hex(in(p),2);
  out(cnt+2) = '_';
  cnt = cnt+3;
end
out(cnt-1) = ' ';
end
%--------------------------------------------------------------------------
function rates = getSupportedRates(value)
rates = zeros(size(value));
for p=1:length(value)
  rates(p) = double(bitand(value(p), 2^7-1)) * (500e3/1e6);
end
end

%--------------------------------------------------------------------------
function buttoncb(src, ...
  hMACHeaderButton,hFrameBodyButton,hInfoElemButton, ...
  hMACHeader, hFrameBody, hInfoElem)

value = get(src, 'Value');
if value
  state = 'on';
  notState = 'off';
  
  switch src
    case hMACHeaderButton
      set(hFrameBodyButton, 'Value', not(value));
      set(hInfoElemButton, 'Value', not(value));
      set(hMACHeader, 'Visible', state);
      set(hFrameBody, 'Visible', notState);
      set(hInfoElem, 'Visible', notState);
    case hFrameBodyButton
      set(hInfoElemButton, 'Value', not(value));
      set(hMACHeaderButton, 'Value', not(value));
      set(hMACHeader, 'Visible', notState);
      set(hFrameBody, 'Visible', state);
      set(hInfoElem, 'Visible', notState);
    case hInfoElemButton
      set(hMACHeaderButton, 'Value', not(value));
      set(hFrameBodyButton, 'Value', not(value));
      set(hMACHeader, 'Visible', notState);
      set(hFrameBody, 'Visible', notState);
      set(hInfoElem, 'Visible', state);
  end
end
end
