⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 action.m

📁 一个无线网络仿真程序
💻 M
📖 第 1 页 / 共 4 页
字号:
        if bdebug, disp(['wait_for_channel @ node ' num2str(i)]); end
%         if mac_status(i) == 0
%             % Reset by timeout_rreq after many RREQ retries
%             if ddebug, disp(['wait_for_channel: node ' num2str(i) 'mac_status reset because so many RREQ retries at network layer']); end
%             return;
%         end
        if node(i, 4) == 0 & carrier_sense(i) == 0
            % question: I want to transmit, but have to capture from many neighbors
            % the node is idle and the channel is free, can backoff now
            if backoff_counter(i) > 0   % resume the backoff
                newevent = event;
                newevent.instant = t + slot_time;
                newevent.type = 'backoff';
                newevent.node = i;
                NewEvents = [NewEvents; newevent]; clear newevent;
            else                        % start from DIFS first
                newevent = event;
                newevent.instant = t + DIFS;
                newevent.type = 'backoff_start';
                newevent.node = i;
                NewEvents = [NewEvents; newevent]; clear newevent;
            end
        else
            % the node is not idle; must be receiving...wait until this receiving is finished
            % or the channel is not free; wait until the channel is free
            newevent = event;
            newevent.instant = t + cca_time;
            newevent.type = 'wait_for_channel';
            newevent.node = i;
            NewEvents = [NewEvents; newevent]; clear newevent;
        end
    case 'backoff_start'  % after DIFS, start backoff
        t = event.instant;
        i = event.node;
        j = event.pkt.rv;
        if bdebug, disp(['backoff_start @ node ' num2str(i)]); end
        if node(i, 4) == 0 & carrier_sense(i) == 0
            % the node is still idle and the channel is free, start backoff
            % question: what if the channel was busy during this DIFS period?
            backoff_attempt(i) = 0;
            temp = min(backoff_attempt(i)+CW_min,CW_max);
            backoff_counter(i) = floor((2^temp-1)*rand);
            newevent = event;
            newevent.instant = t + slot_time;
            newevent.type = 'backoff';
            newevent.node = i;
            NewEvents = [NewEvents; newevent]; clear newevent;
        else
            % channel becomes busy during DIFS, wait until the channel is free
            newevent = event;
            newevent.instant = t + cca_time;
            newevent.type = 'wait_for_channel';
            newevent.node = i;
            NewEvents = [NewEvents; newevent]; clear newevent;
        end
    case 'backoff'
        t = event.instant;
        i = event.node;
        j = event.pkt.rv;
        if bdebug, disp(['backoff @ node ' num2str(i)]); end
        if node(i, 4) == 0 & carrier_sense(i) == 0
            % the node is still idle and the channel is free, continue backoff
            if backoff_counter(i) > 1
                backoff_counter(i) = backoff_counter(i) - 1;
                newevent = event;
                newevent.instant = t + slot_time;
                newevent.type = 'backoff';
                newevent.node = i;
                NewEvents = [NewEvents; newevent]; clear newevent;
            else    % ready to send the packet
                backoff_counter(i) = 0; % reset counter for next use
                newevent = event;
                newevent.instant = t;
                newevent.type = 'send_phy';
                newevent.node = i;
                NewEvents = [NewEvents; newevent]; 
                % txtime = tx_time(newevent.pkt);
                clear newevent;
                % mac_queue will be taken care of after really send this packet in 'send_phy_finish'
%                 if j == 0   % broadcast: the real data is sent here
%                     % we can send the next packet from mac_queue now
%                     if ~isempty(mac_queue(i).list)
%                         % more packets are waiting to be sent
%                         newevent = mac_queue(i).list(1);
%                         mac_queue(i).list(1) = [];
%                         newevent.instant = t + txtime + cca_time;   % question: should cca_time or other be used here?
%                         newevent.type = 'wait_for_channel';
%                         newevent.node = i;
%                         NewEvents = [NewEvents; newevent]; clear newevent;
%                     else
%                         % will reset in 'send_phy_finish'
%                         % mac_status(i) = 0;
%                     end
%                 else
%                     % unicast: the RTS is sent here, will wait for CTS or timeout_rts
%                     % do nothing here
%                 end
            end
        else   % channel becomes busy during backoff count-down
            if backoff_counter(i) > 1
                backoff_counter(i) = backoff_counter(i) - 1;
            else
                % start a new backoff counter when count-down is zero
                backoff_attempt(i) = backoff_attempt(i) + 1;
                temp = min(backoff_attempt(i)+CW_min,CW_max);
                backoff_counter(i) = floor((2^temp-1)*rand);
            end
            newevent = event;
            newevent.instant = t + cca_time;
            newevent.type = 'wait_for_channel';
            newevent.node = i;
            NewEvents = [NewEvents; newevent]; clear newevent;
        end
    case 'timeout_rts'
        t = event.instant;
        i = event.node;
        j = event.pkt.rv;
        if adebug, disp(['timeout_rts @ node ' num2str(i)]); end
        if pending_id(i) == event.pkt.id % not acknowledged yet, retransmit
            if cdebug, disp(['timeout_rts: node ' num2str(i) ' pending_id=' num2str(pending_id(i)) ' event_id=' num2str(event.pkt.id)]); end
            retransmit(i) = retransmit(i) + 1;
            if retransmit(i) > max_retries
                % so many retries, drop the packet
                if cdebug, disp(['timeout_rts: node ' num2str(i) ' has retried so many times to transmit RTS']); end
                retransmit(i) = 0;
                pending_id(i) = 0;
                % question: what if there are waiting packets in mac_queue?
                % answer: should send them anyway as if the current packet is done.
                % similar to the the operation when ACK is received
                if ~isempty(mac_queue(i).list)
                    % more packets are waiting to be sent
                    % newevent.instant = t + turnaround_time; % switch from receive to transmit
                    mac_status(i) = 1;
                    newevent = mac_queue(i).list(1);
                    mac_queue(i).list(1) = [];
                    newevent.instant = t + cca_time;    % question: cca_time or other
                    newevent.type = 'wait_for_channel';
                    newevent.node = i;
                    % packet setup is already done in 'send_mac' before put into the mac_queue
                    NewEvents = [NewEvents; newevent]; clear newevent;
                else
                    % cannot send RTS successfully, reset MAC layer
                    mac_status(i) = 0;
                end
                return;
            end
            if adebug, disp(['timeout_rts: node ' num2str(i) ' to retransmit RTS']); end
            % retransmit the RTS
            newevent = event;
            newevent.instant = t + cca_time;    % check channel status
            newevent.type = 'wait_for_channel';
            newevent.node = i;
            NewEvents = [NewEvents; newevent]; clear newevent;
        else
            % if pending_id(i) ~= 0 & ddebug, disp(['timeout_rts at node ' num2str(i) ' pending id=' num2str(pending_id(i)) ' does not match the waiting RTS id=' num2str(event.pkt.id)]); end
        end
    case 'timeout_data'
        t = event.instant;
        i = event.node;
        j = event.pkt.rv;
        if adebug, disp(['timeout_data @ node ' num2str(i)]); end
%         if pending_id(i) == event.pkt.id % not acknowledged yet
%             if adebug, disp(['timeout_data: node ' num2str(i) ' failed to transmit DATA, go back to transmit RTS']); end
%             % remove the pending id for DATA
%             pending_id(i) = 0;
%             retransmit(i) = 0;
%             % go back to send RTS
%             newevent = event;
%             newevent.instant = t + cca_time;    % check channel status
%             newevent.type = 'wait_for_channel';
%             newevent.node = i;
%             newevent.pkt.type = 'data';
%             newevent.pkt.nav = SIFS + cts_tx_time + SIFS + tx_time(newevent.pkt) + SIFS + ack_tx_time;
%             newevent.pkt.type = 'rts';
%             % create a new id for the new RTS
%             newevent.pkt.id = new_id(i);
%             NewEvents = [NewEvents; newevent]; clear newevent;
%         end
        if pending_id(i) == event.pkt.id % not acknowledged yet
            if cdebug, disp(['timeout_data: node ' num2str(i) ' pending_id=' num2str(pending_id(i)) ' event_id=' num2str(event.pkt.id)]); end
            retransmit(i) = retransmit(i) + 1;
            if retransmit(i) > max_retries
                % so many retries, drop the data packet
                if cdebug, disp(['timeout_data: node ' num2str(i) ' has retried so many times to transmit DATA']); end
                retransmit(i) = 0;
                pending_id(i) = 0;
                if ~isempty(mac_queue(i).list)
                    % more packets are waiting to be sent
                    mac_status(i) = 1;
                    newevent = mac_queue(i).list(1);
                    mac_queue(i).list(1) = [];
                    newevent.instant = t + cca_time;    % question: cca_time or other
                    newevent.type = 'wait_for_channel';
                    newevent.node = i;
                    NewEvents = [NewEvents; newevent]; clear newevent;
                else
                    % Cannot send DATA successfully, reset MAC layer
                    mac_status(i) = 0;
                end
                return;
            end
            if adebug, disp(['timeout_data: node ' num2str(i) ' to retransmit DATA']); end
            % retransmit the DATA
            newevent = event;
            newevent.instant = t + cca_time;    % check channel status
            newevent.type = 'wait_for_channel';
            newevent.node = i;
            % newevent.pkt.type = 'data';
            newevent.pkt.nav = SIFS + ack_tx_time; % necessary for retransmission because the initial DATA has NAV=0
            NewEvents = [NewEvents; newevent]; clear newevent;
        end
    case 'recv_mac'
        t = event.instant;
        i = event.pkt.tx;
        j = event.node;
        if adebug, disp(['recv_mac @ node ' num2str(j)]); end
        if event.pkt.rv == 0 & strcmp(event.pkt.type, 'data') == 0
            % broadcast but not data packet
            error(['recv_mac: node ' num2str(j) ' receives a broadcast packet with a wrong type: ' event.pkt.type]);
        end
        if j == i
            % I myself sent this packet, no action
            return;
        end
        switch event.pkt.type
            case 'rts'
                % send back a CTS
                newevent = event;
                newevent.instant = t + SIFS;
                newevent.type = 'send_phy';
                newevent.node = j;
                % keep the data size, rate, and id as RTS packet
                newevent.pkt.type = 'cts';
                newevent.pkt.tx=j;
                newevent.pkt.rv=i;
                newevent.pkt.nav=event.pkt.nav - SIFS - cts_tx_time;
                NewEvents = [NewEvents; newevent]; clear newevent;
            case 'cts'
                % remove pending id for RTS
                if pending_id(j) ~= event.pkt.id
                    if ddebug, disp(['the received CTS id ' num2str(event.pkt.id) ' does not match the pending RTS id ' num2str(pending_id(j))]); end
                    % probably this CTS is in response to an earlier RTS,
                    % but I have retransmitted a new RTS which is replied
                    % already or I have retransmitted so many times and given up
                    % so we just ignore this CTS.
                    return;
                end
                pending_id(j) = 0;
                retransmit(j) = 0;
                % send DATA
                newevent = event;
                newevent.instant = t + SIFS;
                newevent.type = 'send_phy';
                newevent.node = j;
                % keep the data size and rate as before
                % newevent.pkt.ttl = 1;
                newevent.pkt.type = 'data';
                newevent.pkt.tx=j;
                newevent.pkt.rv=i;
                % creat a new id for the data packet
                newevent.pkt.id = new_id(j);
                newevent.pkt.nav = 0; % not necessary because RTS already did so
                NewEvents = [NewEvents; newevent]; clear newevent;
            case 'data'
                % should check that this is not a duplicated or out-of-order packet
                if event.pkt.rv ~= 0    % send ACK if not broadcast
                    % send back an ACK
                    newevent = event;
                    newevent.instant = t + SIFS;
                    newevent.type = 'send_phy';
                    newevent.node = j;
                    % keep the data size, rate, and id the same as DATA packet
                    newevent.pkt.type = 'ack';
                    newevent.pkt.tx=j;
                    newevent.pkt.rv=i;
                    newevent.pkt.nav=0; % not necessary because CTS already did so
                    NewEvents = [NewEvents; newevent]; clear newevent;
                end
                % send data up to network layer
                newevent = event;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -