├── CCMA ├── Is_collide.m ├── increase_one.m ├── increase_retry.m ├── increase_CWmin.m ├── reset_retry_counter.m ├── channel_generation.m ├── equal_slove.m ├── decrease_one.m ├── retry_backoff.m ├── equal_solve_20131219.m ├── recover.m ├── Is_win.m ├── ZF_SIC.m ├── myfun_20131219.m ├── CCMA_main.m └── CSMA_CA_model_main.m ├── CCMA-oppMAC ├── Is_collide.m ├── increase_one.m ├── increase_retry.m ├── increase_CWmin.m ├── reset_retry_counter.m ├── channel_generation.m ├── log_exp.m ├── PJoin.m ├── equal_solve_opp_20131229.m ├── retry_backoff.m ├── recover.m ├── Channel_Allocation.m ├── decrease_one_opp.m ├── Is_win.m ├── ZF_SIC.m ├── log_chi.m ├── myfun_opp_20131229.m ├── throughput_plot_opp.m ├── CCMA_model_opp_main.m ├── freeze.m └── CCMA_opp_main.m ├── README.md └── LICENSE.md /CCMA/Is_collide.m: -------------------------------------------------------------------------------- 1 | function is_collide = Is_collide(channel_win, AP_antenna) 2 | % this function checks whether collision has happened 3 | m = length(channel_win); 4 | if (m>AP_antenna) 5 | is_collide = 1; 6 | else 7 | is_collide = 0; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA-oppMAC/Is_collide.m: -------------------------------------------------------------------------------- 1 | function is_collide = Is_collide(channel_win, AP_antenna) 2 | % this function checks whether collision has happened 3 | m = length(channel_win); 4 | if (m>AP_antenna) 5 | is_collide = 1; 6 | else 7 | is_collide = 0; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA/increase_one.m: -------------------------------------------------------------------------------- 1 | function tx_time_new = increase_one(tx_time, channel_win) 2 | % this function increases the transmission time for the clients who has won 3 | % the channel 4 | m = length(channel_win); 5 | tx_time_new = tx_time; 6 | for i = 1:m 7 | tx_time_new(channel_win(i)) = tx_time_new(channel_win(i)) +1; 8 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/increase_one.m: -------------------------------------------------------------------------------- 1 | function tx_time_new = increase_one(tx_time, channel_win) 2 | % this function increases the transmission time for the clients who has won 3 | % the channel 4 | m = length(channel_win); 5 | tx_time_new = tx_time; 6 | for i = 1:m 7 | tx_time_new(channel_win(i)) = tx_time_new(channel_win(i)) +1; 8 | end -------------------------------------------------------------------------------- /CCMA/increase_retry.m: -------------------------------------------------------------------------------- 1 | function retry_counter_new = increase_retry(retry_counter, channel_win) 2 | %this function increase the retry_counter for clients who has won the 3 | %channel 4 | retry_counter_new = retry_counter; 5 | m = length(channel_win); 6 | for i = 1:m 7 | retry_counter_new(channel_win(i)) = retry_counter_new(channel_win(i)) + 1; 8 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/increase_retry.m: -------------------------------------------------------------------------------- 1 | function retry_counter_new = increase_retry(retry_counter, channel_win) 2 | %this function increase the retry_counter for clients who has won the 3 | %channel 4 | retry_counter_new = retry_counter; 5 | m = length(channel_win); 6 | for i = 1:m 7 | retry_counter_new(channel_win(i)) = retry_counter_new(channel_win(i)) + 1; 8 | end -------------------------------------------------------------------------------- /CCMA/increase_CWmin.m: -------------------------------------------------------------------------------- 1 | function backoff_new = increase_CWmin(backoff, channel_win, CWmin, t_slot) 2 | % this function gives a CWmin backoff time to clients who have successfully 3 | % transmitted their data. 4 | m = length(channel_win); 5 | backoff_new = backoff; 6 | for i = 1:m 7 | backoff_new(channel_win(i)) = (unidrnd(CWmin+1)-1)*t_slot; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA/reset_retry_counter.m: -------------------------------------------------------------------------------- 1 | function retry_counter_new = reset_retry_counter (retry_counter, channel_win) 2 | % this function reset the retry_counter to zero for clients that have 3 | % successfully transmitted their data 4 | m = length(channel_win); 5 | retry_counter_new = retry_counter; 6 | for i =1:m 7 | retry_counter_new(channel_win(i)) = 0; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA-oppMAC/increase_CWmin.m: -------------------------------------------------------------------------------- 1 | function backoff_new = increase_CWmin(backoff, channel_win, CWmin, t_slot) 2 | % this function gives a CWmin backoff time to clients who have successfully 3 | % transmitted their data. 4 | m = length(channel_win); 5 | backoff_new = backoff; 6 | for i = 1:m 7 | backoff_new(channel_win(i)) = (unidrnd(CWmin+1)-1)*t_slot; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA-oppMAC/reset_retry_counter.m: -------------------------------------------------------------------------------- 1 | function retry_counter_new = reset_retry_counter (retry_counter, channel_win) 2 | % this function reset the retry_counter to zero for clients that have 3 | % successfully transmitted their data 4 | m = length(channel_win); 5 | retry_counter_new = retry_counter; 6 | for i =1:m 7 | retry_counter_new(channel_win(i)) = 0; 8 | end 9 | -------------------------------------------------------------------------------- /CCMA/channel_generation.m: -------------------------------------------------------------------------------- 1 | function channel_vector = channel_generation(AP_antenna, network_size) 2 | % this function randomly generates the channels, each term follows a 3 | % circularly symmetrical distribution CN(0,1). 4 | h = raylrnd(1/sqrt(2),network_size,AP_antenna); 5 | theta = rand(network_size, AP_antenna)*2*pi; 6 | temp = complex(cos(theta), sin(theta)); 7 | channel_vector = h.*temp; 8 | -------------------------------------------------------------------------------- /CCMA-oppMAC/channel_generation.m: -------------------------------------------------------------------------------- 1 | function channel_vector = channel_generation(AP_antenna, network_size) 2 | % this function randomly generates the channels, each term follows a 3 | % circularly symmetrical distribution CN(0,1). 4 | h = raylrnd(1/sqrt(2),network_size,AP_antenna); 5 | theta = rand(network_size, AP_antenna)*2*pi; 6 | temp = complex(cos(theta), sin(theta)); 7 | channel_vector = h.*temp; 8 | -------------------------------------------------------------------------------- /CCMA/equal_slove.m: -------------------------------------------------------------------------------- 1 | function tau = equal_slove(network_size, concurrent_tx, CWmin, backoff_stage) 2 | % this function calculates the transmission probability (tau) in a 802.11 3 | % CSMA/CA based MU-MIMO system 4 | c = zeros(1,4); 5 | c(1) = network_size; 6 | c(2) = concurrent_tx; 7 | c(3) = CWmin; 8 | c(4) = backoff_stage; 9 | x0 = [0.3; 0.3]; 10 | x = fsolve(@(x) myfun(x,c), x0); 11 | tau = x(1); -------------------------------------------------------------------------------- /CCMA-oppMAC/log_exp.m: -------------------------------------------------------------------------------- 1 | function rate = log_exp(degree,BW, tx_power) 2 | % this function computes the average transmission rate for each concurrent 3 | % client, based on the fact that the channel gain is chi-squared 4 | % distributed with degree degrees of freedom 5 | x = 0:0.01:1000; 6 | y = chi2pdf(x,degree); 7 | rate = 0; 8 | for i = 1: length(x) 9 | rate = rate + BW*log2(1+tx_power*x(i))*y(i)*0.01; 10 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/PJoin.m: -------------------------------------------------------------------------------- 1 | function p_join = PJoin(threshold) 2 | %this function calculates the probability that clients will join the second 3 | %contention 4 | dx = 0.01; 5 | x = 0:dx:1000; 6 | temp = 0; 7 | b = chi2pdf(x,4); 8 | for i = 1:length(x) 9 | c = sqrt(threshold/x(i)); 10 | if (c>1) 11 | a = pi/2; 12 | else 13 | a = asin(c); 14 | end 15 | temp = temp + 2*a/pi*b(i)*dx; 16 | end 17 | p_join = 1-temp; -------------------------------------------------------------------------------- /CCMA-oppMAC/equal_solve_opp_20131229.m: -------------------------------------------------------------------------------- 1 | function [tau, p] = equal_solve_opp_20131229(network_size, CWmin, backoff_stage,p_join) 2 | % this function calculates the transmission probability (tau) in a 802.11 3 | % CSMA/CA based MU-MIMO system 4 | % c = zeros(1,4); 5 | % c(1) = network_size; 6 | % c(2) = concurrent_tx; 7 | % c(3) = CWmin; 8 | % c(4) = backoff_stage; 9 | x0 = [0.04; 0.4]; 10 | x = fsolve(@(x) myfun_opp_20131229(x,network_size, CWmin, backoff_stage,p_join), x0); 11 | tau = x(1); 12 | p = x(2); -------------------------------------------------------------------------------- /CCMA/decrease_one.m: -------------------------------------------------------------------------------- 1 | function backoff_new = decrease_one(backoff, channel_win) 2 | % this function decrease one backoff period for clients that haven't won 3 | % the channel 4 | network_size = length(backoff); 5 | backoff_new = backoff - 1; 6 | if (isempty(channel_win) == 0) 7 | m = length(channel_win); 8 | for i = 1: network_size 9 | for j = 1:m 10 | if (i==channel_win(j)) 11 | backoff_new(i) = backoff_new(i)+1; 12 | end 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MU-MIMO-WLAN 2 | 3 | We provide Matlab codes for modeling and analyzing a CSMA/CA-based MAC protocol operating in a multiuser MIMO (MU-MIMO) wireless LAN (WLAN). They are supplementary materials to the following paper: [Performance Study on a CSMA/CA-Based MAC 4 | Protocol for Multi-User MIMO Wireless LANs][MU-MIMO]. The MAC protocoal simulation is provided in the `*_main.m` function while the analytical model is given in the `*_model_main.m` function. 5 | 6 | [MU-MIMO]: http://wushanshan.github.io/files/MU-MIMO.pdf 7 | -------------------------------------------------------------------------------- /CCMA/retry_backoff.m: -------------------------------------------------------------------------------- 1 | function backoff_new = retry_backoff(backoff, channel_win, retry_counter, CWmin, t_slot, CWmax) 2 | %this function returns the backoff time for collided clients. 3 | backoff_new = backoff; 4 | m = length(channel_win); 5 | for i =1:m 6 | CW = (CWmin+1)*2^(retry_counter(channel_win(i)))-1; 7 | if (CW>CWmax) 8 | CW = CWmax; 9 | end 10 | backoff_new(channel_win(i)) = (unidrnd(CW+1)-1)*t_slot + 4*t_slot; % set ACK_timeout as 70us, a value that is larger enough to cover a SIFS and ACK time. 11 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/retry_backoff.m: -------------------------------------------------------------------------------- 1 | function backoff_new = retry_backoff(backoff, channel_win, retry_counter, CWmin, t_slot, CWmax) 2 | %this function returns the backoff time for collided clients. 3 | backoff_new = backoff; 4 | m = length(channel_win); 5 | for i =1:m 6 | CW = (CWmin+1)*2^(retry_counter(channel_win(i)))-1; 7 | if (CW>CWmax) 8 | CW = CWmax; 9 | end 10 | backoff_new(channel_win(i)) = (unidrnd(CW+1)-1)*t_slot + 4*t_slot; % set ACK_timeout as 70us, a value that is larger enough to cover a SIFS and ACK time. 11 | end -------------------------------------------------------------------------------- /CCMA/equal_solve_20131219.m: -------------------------------------------------------------------------------- 1 | function [tau, p] = equal_solve_20131219(network_size, concurrent_num, CWmin, backoff_stage,t_frame,t_slot,t_pre,concurrent_tx) 2 | % this function calculates the transmission probability (tau) in a 802.11 3 | % CSMA/CA based MU-MIMO system 4 | % c = zeros(1,4); 5 | % c(1) = network_size; 6 | % c(2) = concurrent_tx; 7 | % c(3) = CWmin; 8 | % c(4) = backoff_stage; 9 | x0 = [0.04; 0.4]; 10 | x = fsolve(@(x) myfun_20131219(x,network_size, concurrent_num, CWmin, backoff_stage, t_frame,t_slot,t_pre,concurrent_tx), x0); 11 | tau = x(1); 12 | p = x(2); -------------------------------------------------------------------------------- /CCMA/recover.m: -------------------------------------------------------------------------------- 1 | function backoff_new = recover(backoff, channel_win, contention_time, t_slot) 2 | % This function helps ensure that every client has an integer time of 3 | % t_slot as the backoff time before the contention of each round. 4 | m = floor(contention_time/t_slot); 5 | n = length(backoff); 6 | k = length(channel_win); 7 | win = 0; 8 | backoff_new = zeros(1,n); 9 | for i = 1:n 10 | for j = 1:k 11 | if (i == channel_win(j)) 12 | win = 1; 13 | end 14 | end 15 | if (win == 0) 16 | backoff_new(i) = backoff(i) + contention_time - m*t_slot; 17 | end 18 | win = 0; 19 | end 20 | -------------------------------------------------------------------------------- /CCMA-oppMAC/recover.m: -------------------------------------------------------------------------------- 1 | function backoff_new = recover(backoff, channel_win, contention_time, t_slot) 2 | % This function helps ensure that every client has an integer time of 3 | % t_slot as the backoff time before the contention of each round. 4 | m = floor(contention_time/t_slot); 5 | n = length(backoff); 6 | k = length(channel_win); 7 | win = 0; 8 | backoff_new = zeros(1,n); 9 | for i = 1:n 10 | for j = 1:k 11 | if (i == channel_win(j)) 12 | win = 1; 13 | end 14 | end 15 | if (win == 0) 16 | backoff_new(i) = backoff(i) + contention_time - m*t_slot; 17 | end 18 | win = 0; 19 | end 20 | -------------------------------------------------------------------------------- /CCMA-oppMAC/Channel_Allocation.m: -------------------------------------------------------------------------------- 1 | function channel_vector = Channel_Allocation(network_size) 2 | % this function randomly generates the channels, each term follows a 3 | % circularly symmetrical distribution CN(0,1), Consider a network where the AP has 4 | % two antennas, network_size denote the total number of clients 5 | channel_vector = zeros(network_size,2); 6 | for j = 1: network_size 7 | h1 = raylrnd(1/sqrt(2)); 8 | theta1 = rand(1,1)*2*pi; 9 | h2 = raylrnd(1/sqrt(2)); 10 | theta2 = rand(1,1)*2*pi; 11 | channel_vector(j,1) = h1*complex(cos(theta1),sin(theta1)); 12 | channel_vector(j,2) = h2*complex(cos(theta2),sin(theta2)); 13 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/decrease_one_opp.m: -------------------------------------------------------------------------------- 1 | function backoff_new = decrease_one_opp(backoff, channel_win, freeze_client) 2 | % this function decrease one backoff period for clients that haven't won 3 | % the channel 4 | network_size = length(backoff); 5 | backoff_new = backoff - 1; 6 | if (isempty(channel_win) == 0) 7 | m = length(channel_win); 8 | n = length(freeze_client); 9 | for i = 1: network_size 10 | for j = 1:m 11 | if (i==channel_win(j)) 12 | backoff_new(i) = backoff_new(i)+1; 13 | end 14 | end 15 | for k = 1:n 16 | if (i==freeze_client(k)) 17 | backoff_new(i) = backoff_new(i)+1; 18 | end 19 | end 20 | end 21 | end -------------------------------------------------------------------------------- /CCMA/Is_win.m: -------------------------------------------------------------------------------- 1 | function [is_win, channel_win_new] = Is_win(backoff, channel_win) 2 | %this function determines whether a client and which client has won the channel 3 | network_size = length(backoff); 4 | channel_win_new = []; 5 | has_won = 0; 6 | if (isempty(channel_win) == 0) 7 | m = length(channel_win); 8 | for i = 1:network_size 9 | if (backoff(i)==0) 10 | has_won = 0; 11 | for j = 1:m 12 | if (i == channel_win(j)) 13 | has_won = 1; 14 | end 15 | end 16 | if(has_won == 0) 17 | channel_win_new = [channel_win_new i]; 18 | end 19 | end 20 | end 21 | else 22 | for i = 1:network_size 23 | if (backoff(i)==0) 24 | channel_win_new = [channel_win_new i]; 25 | end 26 | end 27 | end 28 | if (isempty(channel_win_new)==1) 29 | is_win = 0; 30 | else 31 | is_win = 1; 32 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/Is_win.m: -------------------------------------------------------------------------------- 1 | function [is_win, channel_win_new] = Is_win(backoff, channel_win) 2 | %this function determines whether a client and which client has won the channel 3 | network_size = length(backoff); 4 | channel_win_new = []; 5 | has_won = 0; 6 | if (isempty(channel_win) == 0) 7 | m = length(channel_win); 8 | for i = 1:network_size 9 | if (backoff(i)==0) 10 | has_won = 0; 11 | for j = 1:m 12 | if (i == channel_win(j)) 13 | has_won = 1; 14 | end 15 | end 16 | if(has_won == 0) 17 | channel_win_new = [channel_win_new i]; 18 | end 19 | end 20 | end 21 | else 22 | for i = 1:network_size 23 | if (backoff(i)==0) 24 | channel_win_new = [channel_win_new i]; 25 | end 26 | end 27 | end 28 | if (isempty(channel_win_new)==1) 29 | is_win = 0; 30 | else 31 | is_win = 1; 32 | end -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Shanshan Wu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CCMA/ZF_SIC.m: -------------------------------------------------------------------------------- 1 | function rate = ZF_SIC(chan, channel_win, BW, tx_power, t_frame) 2 | %this function computes the transmission rates for concurrent clients 3 | %according to their channel vectors and the orders of transmission 4 | [network_size,AP_antenna] = size(chan); 5 | concurrent_tx = length(channel_win); 6 | rate = zeros(1, network_size); 7 | H = zeros(AP_antenna, concurrent_tx); 8 | for i = 1:concurrent_tx 9 | H(:,i) = chan(channel_win(i),:).'; 10 | end 11 | no_symbol = BW*t_frame; % number of symbols in one frame 12 | noise = channel_generation(AP_antenna, no_symbol); 13 | noise = noise.'; 14 | for i = 1:(concurrent_tx) 15 | pseudo_inv = pinv(H); 16 | noise_variance = pseudo_inv * noise; 17 | noise_power = abs(noise_variance(concurrent_tx-i+1,:)).*abs(noise_variance(concurrent_tx-i+1,:)); 18 | temp = 0; 19 | for j = 1:no_symbol 20 | temp = temp + BW*log2(1+tx_power/noise_power(j)); 21 | end 22 | %rate(channel_win(concurrent_tx-i+1)) = BW*log2(1+tx_power/mean(noise_power)); 23 | rate(channel_win(concurrent_tx-i+1)) = temp/no_symbol; 24 | if i~=concurrent_tx 25 | H = H(:,1:(concurrent_tx-i)); 26 | end 27 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/ZF_SIC.m: -------------------------------------------------------------------------------- 1 | function rate = ZF_SIC(chan, channel_win, BW, tx_power, t_frame) 2 | %this function computes the transmission rates for concurrent clients 3 | %according to their channel vectors and the orders of transmission 4 | [network_size,AP_antenna] = size(chan); 5 | concurrent_tx = length(channel_win); 6 | rate = zeros(1, network_size); 7 | H = zeros(AP_antenna, concurrent_tx); 8 | for i = 1:concurrent_tx 9 | H(:,i) = chan(channel_win(i),:).'; 10 | end 11 | no_symbol = BW*t_frame; % number of symbols in one frame 12 | noise = channel_generation(AP_antenna, no_symbol); 13 | noise = noise.'; 14 | for i = 1:(concurrent_tx) 15 | pseudo_inv = pinv(H); 16 | noise_variance = pseudo_inv * noise; 17 | noise_power = abs(noise_variance(concurrent_tx-i+1,:)).*abs(noise_variance(concurrent_tx-i+1,:)); 18 | temp = 0; 19 | for j = 1:no_symbol 20 | temp = temp + BW*log2(1+tx_power/noise_power(j)); 21 | end 22 | %rate(channel_win(concurrent_tx-i+1)) = BW*log2(1+tx_power/mean(noise_power)); 23 | rate(channel_win(concurrent_tx-i+1)) = temp/no_symbol; 24 | if i~=concurrent_tx 25 | H = H(:,1:(concurrent_tx-i)); 26 | end 27 | end -------------------------------------------------------------------------------- /CCMA-oppMAC/log_chi.m: -------------------------------------------------------------------------------- 1 | function rate_opp = log_chi(BW, tx_power, threshold) 2 | % this function calculates the rate of the first contention winner and the average rate of the second contention winner 3 | % of the opportunistic MAC when ||Q_kh_k||^2 is chi-squared distributed 4 | % with 2 degrees of freedom 5 | % rate_opp = zeros(1,2); 6 | % rate_opp(1) = BW *log2(1+2*tx_power); 7 | % prob = 1/(pi/2-theta_th); 8 | % dtheta = 0.01; 9 | % for theta = theta_th:dtheta:pi/2 10 | % rate_opp(2) = rate_opp(2) + BW * log2(1+tx_power*2*sin(theta)*sin(theta))*prob*dtheta; 11 | % end 12 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 | rate_opp = zeros(1,2); 14 | rate_opp(1) = log_exp(4,BW, tx_power); 15 | x = threshold:0.01:100; 16 | y = chi2pdf(x,2); 17 | norm = 1-chi2cdf(threshold,2); 18 | rate = 0; 19 | for i = 1: length(x) 20 | rate = rate + BW*log2(1+tx_power*x(i))*y(i)*0.01; 21 | end 22 | rate_opp(2) = rate/norm; 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | % rate_opp = zeros(1,2); 25 | % rate_opp(1) = log_exp(4,BW, tx_power); 26 | % x = threshold:0.1:100; 27 | % norm = PJoin(threshold); 28 | % rate = 0; 29 | % for i=1:(length(x)-1) 30 | % delta = (PJoin(x(i))-PJoin(x(i+1)))/norm; 31 | % rate = rate + BW*log2(1+tx_power*x(i))*delta; 32 | % end 33 | % rate_opp(2) = rate; -------------------------------------------------------------------------------- /CCMA-oppMAC/myfun_opp_20131229.m: -------------------------------------------------------------------------------- 1 | function F = myfun_opp_20131229(x,network_size, CWmin, backoff_stage,p_join) 2 | concurrent_num = 2; 3 | p_success_1 = (network_size)*x(1)*(1-x(1))^(network_size - 1)/(1-(1-x(1))^(network_size)); % success probability of 1st contention 4 | temp = (1-p_join)^(network_size-1); 5 | for N_join = 1:(network_size-1) 6 | N_join_prob = nchoosek(network_size-1, N_join)*p_join^N_join*(1-p_join)^(network_size-1-N_join); 7 | temp = temp + N_join*x(1)*(1-x(1))^(N_join - 1)/(1-(1-x(1))^N_join)*N_join_prob; 8 | end 9 | N_join_0 = p_success_1*(1-p_join)^(network_size-1); 10 | p_success = p_success_1*temp; % probability of successful transmission 11 | network_size_new = network_size - 1; 12 | p_success_1_new = (network_size_new)*x(1)*(1-x(1))^(network_size_new - 1)/(1-(1-x(1))^(network_size_new)); % success probability of 1st contention 13 | temp_new = (1-p_join)^(network_size_new-1); 14 | for N_join = 1:(network_size_new-1) 15 | N_join_prob = nchoosek(network_size_new-1, N_join)*p_join^N_join*(1-p_join)^(network_size_new-1-N_join); 16 | temp_new = temp_new + N_join*x(1)*(1-x(1))^(N_join - 1)/(1-(1-x(1))^N_join)*N_join_prob; 17 | end 18 | %N_join_0_new = p_success_1_new*(1-p_join)^(network_size_new-1); 19 | p_success_new = p_success_1_new*temp_new; % probability of successful transmission 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%two nonlinear equations%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | p_success_include_i = concurrent_num/network_size * (p_success-N_join_0) + 1/network_size*N_join_0; 22 | p_success_not_include_i = (1-concurrent_num/network_size) * (p_success-N_join_0) + (1-1/network_size)*N_join_0; 23 | %eq2_pre = concurrent_num/network_size * p_success*p_success_new/(p_success_new - (1-concurrent_num/network_size)*p_success); 24 | eq2_pre = p_success_include_i*p_success_new/(p_success_new-p_success_not_include_i); 25 | eq1 = x(1) - 2*(1-2*x(2))/((1-2*x(2))*(CWmin+1)+x(2)*CWmin*(1-(2*x(2))^backoff_stage)); 26 | eq2 = x(2) - 1 + eq2_pre; 27 | F = [eq1 eq2]; -------------------------------------------------------------------------------- /CCMA-oppMAC/throughput_plot_opp.m: -------------------------------------------------------------------------------- 1 | function [network_throughput, delay] = throughput_plot_opp(total_time, t_slot, t_frame, BW, tx_power) 2 | % this function plots the network_throughput versus network_size, with 3 | % different theta_threshold, under the opportunistic MAC, AP_antenna = 2 4 | network_size = [10 15 20 25 30 40]; 5 | %network_size = [30]; 6 | %theta_th = [pi/8 pi/4 5*pi/16 3*pi/8]; 7 | %theta_th = [pi/4 3*pi/8]; 8 | threshold = [0.5 1 1.5]; 9 | network_throughput = zeros(length(threshold),length(network_size)); 10 | delay = network_throughput; 11 | for i = 1:length(threshold) 12 | for j = 1:length(network_size) 13 | %[network_throughput, client_throughput, delay] = CSMA_CA_opp(network_size, total_time, t_slot, t_frame, threshold) 14 | [network_throughput(i,j), ~, delay(i,j)] = CSMA_CA_opp(network_size(j), total_time, t_slot, t_frame, threshold(i), BW, tx_power); 15 | end 16 | plot(network_size, network_throughput(i,:),'ro'); 17 | hold on; 18 | end 19 | network_throughput_analysis = zeros(1, 46); 20 | for i = 1:length(threshold) 21 | %rate_opp = log_chi(BW, tx_power, threshold(i)); 22 | for j = 5:50 23 | network_throughput_analysis(j-4) = CSMA_CA_model_opp_20131229(j,t_slot,t_frame, 20, 128, 3, BW, tx_power, threshold(i)); 24 | end 25 | plot(5:50, network_throughput_analysis,'b-'); 26 | hold on; 27 | end 28 | fileID = fopen('simulation_opp.txt','w'); 29 | fprintf(fileID,'%20s %20f\n', 'total time = ', total_time); 30 | fprintf(fileID,'%20s %20f\n', 't_slot = ', t_slot); 31 | fprintf(fileID,'%20s %20f\n', 't_frame = ', t_frame); 32 | fprintf(fileID,'%20s %20f\n', 'BW (MHz) = ', BW); 33 | fprintf(fileID,'%20s %20f\n', 'tx_power/noise = ', tx_power); 34 | fprintf(fileID,'%20s\n', 'network throughput'); 35 | fprintf(fileID,'%12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f\n',network_throughput'); 36 | fprintf(fileID,'%20s\n', 'average delay'); 37 | fprintf(fileID,'%12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f\n',delay'); 38 | %fprintf(fileID,'%20s\n', 'retry number'); 39 | %fprintf(fileID,'%12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f %12.8f\n',retry_no'); 40 | fclose(fileID); -------------------------------------------------------------------------------- /CCMA-oppMAC/CCMA_model_opp_main.m: -------------------------------------------------------------------------------- 1 | function [network_throughput, delay] = CCMA_model_opp_main(network_size,t_slot,t_frame, t_pre, CWmin, backoff_stage, BW, tx_power, threshold) 2 | %this function provides the analytically derived network throughput for a 3 | %802.11 CSMA/CA based MU-MIMO system, with a 2-antenna AP, and client joining 4 | %the second contention period at probability p_join. We assume that the total 5 | %number of clients is larger than 2. 6 | SIFS = 16; 7 | ACK = 39; 8 | DIFS = 34; 9 | p_join = PJoin(threshold); 10 | %p_join = (14-9.2)/14; 11 | tau = equal_solve_opp_20131229(network_size, CWmin, backoff_stage,p_join);% probability that one STA transmits in each slot time 12 | payload = zeros(1, 2); % average number of transmitted data if one has won the m's concurrent transmission opportunity 13 | payload(1) = t_frame; 14 | for N_join = 1:(network_size-1) 15 | no_tx = (1-tau)^(N_join); 16 | N2 = 1/(1-no_tx); 17 | N2_prob = nchoosek(network_size-1, N_join)*p_join^N_join*(1-p_join)^(network_size-1-N_join); 18 | payload(2) = payload(2) + (t_frame - t_pre - t_slot*N2)*N2_prob; 19 | end 20 | rate_opp = log_chi(BW, tx_power, threshold); % unit:Mbps 21 | success_payload = zeros(1,2); 22 | for i = 1:2 23 | success_payload(i) = payload(i)*rate_opp(i); 24 | end 25 | p_success_1 = (network_size)*tau*(1-tau)^(network_size - 1)/(1-(1-tau)^(network_size)); % success probability of 1st contention 26 | temp = (1-p_join)^(network_size-1);%probability that a successful round contains only one client 27 | for N_join = 1:(network_size-1) 28 | N_join_prob = nchoosek(network_size-1, N_join)*p_join^N_join*(1-p_join)^(network_size-1-N_join); 29 | temp = temp + N_join*tau*(1-tau)^(N_join - 1)/(1-(1-tau)^N_join)*N_join_prob; 30 | end 31 | p_success = p_success_1*temp; % probability of successful transmission 32 | N_coll = (1-p_success)/p_success; % average number of collisions before one successful transmission 33 | t_coll = t_slot*(1-tau)^network_size/(1-(1-tau)^network_size) + t_pre + t_frame + DIFS; % average time of one collision 34 | t_success = t_slot*(1-tau)^network_size/(1-(1-tau)^network_size) + t_pre + t_frame + SIFS + ACK + DIFS; % average time of one successful transmission 35 | N_join_0 = p_success_1*(1-p_join)^(network_size-1); 36 | network_throughput = sum(success_payload)/(N_coll * t_coll + t_success); 37 | p_success_include_i = 2/network_size * (p_success-N_join_0) + 1/network_size*N_join_0; 38 | delay = (N_coll * t_coll + t_success)*p_success/p_success_include_i; %unit:us 39 | %delay = network_size*(N_coll * t_coll + t_success)/2; %unit:us -------------------------------------------------------------------------------- /CCMA-oppMAC/freeze.m: -------------------------------------------------------------------------------- 1 | function freeze_client = freeze(backoff, channel_vector, threshold, channel_win, BW, tx_power, t_frame) 2 | %this function freezes clients with an probability of p_join, and put the 3 | %freezed clients into freeze_client, the client with backoff=0 will not be 4 | %considered in the freeze operation. 5 | % freeze_client = []; 6 | % for i = 1:length(backoff) 7 | % if (backoff(i)~=0) 8 | % if(rand(1,1)>p_join) 9 | % freeze_client = [freeze_client i]; 10 | % end 11 | % end 12 | % end 13 | % length(freeze_client) 14 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 15 | % freeze_client = []; 16 | % theta_1st = angle(channel_vector(channel_win(1))); 17 | % network_size = length(backoff); 18 | % for i = 1:network_size 19 | % if (backoff(i)~=0) 20 | % delta = abs(angle(channel_vector(i)) - theta_1st); 21 | % if (abs(sin(delta))1) 6 | for m = 2:concurrent_num 7 | no_tx = (1-x(1))^(network_size+1-m); 8 | temp = temp - t_pre - t_slot*1/(1-no_tx); 9 | % if (temp <0) 10 | % temp = 0; 11 | % end 12 | payload(m) = temp; 13 | end 14 | end 15 | p_success = zeros(1, concurrent_num); % probability that a random chosen round is a successful round with i clients (1<= i <= concurrent_num) 16 | waiting_time = zeros(1, concurrent_num); % if clients will not join a round with i preamble pauses, it has to wait for waiting_time(i) time 17 | waiting_time(1) = t_frame; 18 | for i = 2:concurrent_num 19 | waiting_time(i) = waiting_time(i-1) - t_pre; 20 | end 21 | temp = 1; 22 | for m = 1:concurrent_num 23 | %temp = temp * (network_size-m+1)*x(1)*(1-x(1))^(network_size - m)/(1-(1-x(1))^(network_size+1-m)); 24 | if (m==1) 25 | temp = temp * (network_size-m+1)*x(1)*(1-x(1))^(network_size - m)/(1-(1-x(1))^(network_size+1-m)); 26 | else 27 | temp = temp * (network_size-m+1)*(1-x(1))^((payload(m-1)-t_pre-payload(m))/t_slot*(network_size-m+1))*x(1)*(1-x(1))^(network_size-m); 28 | %temp = temp * (network_size-m+1)*x(1)*(1-x(1))^(network_size - m); 29 | end 30 | if (m~=concurrent_num) 31 | %p_success(j) = temp * (1-payload(j)/t_slot*(network_size-j)*x(1)); 32 | %p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1)*(1-x(1))^(ceil((waiting_time(m)-payload(m))/t_slot)*(network_size-m))*(1-x(1))^(abs(payload(m)/t_slot)*(network_size-m)); 33 | %p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1)*(1-x(1))^(ceil(waiting_time(m)/t_slot)*(network_size-m)); 34 | p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1)*(1-x(1))^((payload(m)/t_slot)*(network_size-m)); 35 | else 36 | %p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1)*(1-x(1))^(ceil((waiting_time(m)-payload(m))/t_slot)*(network_size-m)); 37 | p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1); 38 | end 39 | end 40 | p_success_include_i = 0; 41 | p_success_not_include_i = 0; 42 | for j = 1:concurrent_num 43 | p_success_include_i = p_success_include_i + p_success(j)*j/network_size; 44 | p_success_not_include_i = p_success_not_include_i + p_success(j)*(1-j/network_size); 45 | end 46 | %----- calculate the probability conditioned on the Client i does not tx in round r -----% 47 | network_size_new = network_size - 1; 48 | if (concurrent_num > network_size_new) 49 | concurrent_num_new = network_size_new; 50 | else 51 | concurrent_num_new = concurrent_num; 52 | end 53 | p_success_new = zeros(1, concurrent_num_new); % probability that a random chosen round is a successful round with i clients (1<= i <= concurrent_num) 54 | %p_a1_new = x(1)*(1-x(1))^(network_size_new-1)/(1-(1-x(1))^network_size_new); 55 | waiting_time_new = zeros(1, concurrent_num_new); % if clients will not join a round with i preamble pauses, it has to wait for waiting_time(i) time 56 | waiting_time_new(1) = t_frame; 57 | for i = 2:concurrent_num_new 58 | waiting_time_new(i) = waiting_time_new(i-1) - t_pre; 59 | end 60 | temp = 1; 61 | for m = 1:concurrent_num_new 62 | %temp = temp * (network_size_new-m+1)*x(1)*(1-x(1))^(network_size_new - m)/(1-(1-x(1))^(network_size_new+1-m)); 63 | if (m==1) 64 | temp = temp * (network_size_new-m+1)*x(1)*(1-x(1))^(network_size_new - m)/(1-(1-x(1))^(network_size_new+1-m)); 65 | else 66 | temp = temp * (network_size_new-m+1)*(1-x(1))^((payload(m-1)-t_pre-payload(m))/t_slot*(network_size_new-m+1))*x(1)*(1-x(1))^(network_size_new-m); 67 | end 68 | if (m~=concurrent_num_new) 69 | %p_success(j) = temp * (1-payload(j)/t_slot*(network_size-j)*x(1)); 70 | %p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1)*(1-x(1))^(ceil((waiting_time_new(m)-payload(m))/t_slot)*(network_size_new-m))*(1-x(1))^(abs(payload(m)/t_slot)*(network_size_new-m)); 71 | p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1)*(1-x(1))^((payload(m)/t_slot)*(network_size_new-m)); 72 | else 73 | %p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1)*(1-x(1))^(ceil((waiting_time_new(m)-payload(m))/t_slot)*(network_size_new-m)); 74 | p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1); 75 | end 76 | end 77 | 78 | %-------------- construct the two nonlinear equations in tau and p --------------% 79 | eq1 = x(1) - 2*(1-2*x(2))/((1-2*x(2))*(CWmin+1)+x(2)*CWmin*(1-(2*x(2))^backoff_stage)); 80 | eq2_pre = p_success_include_i/(1-p_success_not_include_i/sum(p_success_new)); 81 | %eq2_pre = p_success_include_i/(1-(1-x(1))^(floor(t_frame/t_slot))); 82 | eq2 = x(2) - 1 + eq2_pre; 83 | F = [eq1 eq2]; -------------------------------------------------------------------------------- /CCMA/CCMA_main.m: -------------------------------------------------------------------------------- 1 | function [network_throughput, delay] = CCMA_main(network_size, total_time, t_slot, t_frame, AP_antenna, BW, tx_power) 2 | % This function calculates the network throughput and the throughput of 3 | % each client of a 802.11 MU-MIMO system. The network_size is the total 4 | % number of clients in the system. The total_time is the time we are 5 | % considering, with a time unit of 1 us. t_slot is the slot time needed to 6 | % reduce the backoff counter. t_frame is the time used to 7 | % transmit a frame by the first client who wins the channel. The Access 8 | % Point has AP_antenna number of antennas. 9 | channel_vector = channel_generation(AP_antenna, network_size); 10 | client_tx = zeros(1,network_size); % number of successful transmissions performed by each client 11 | client_throughput = zeros(1, network_size); 12 | channel_win = []; % clients that have won the channel in a round 13 | CWmin = 127; 14 | CWmax = 1023; 15 | SIFS = 16; 16 | ACK = 39; 17 | DIFS = SIFS + 2*t_slot; 18 | preamble = 20; 19 | data_counter = 0; 20 | parallel_counter = 0; %number of ongoing transmission 21 | tx_time= zeros(1, network_size);% how long each client has transmit 22 | retry_counter = zeros(1, network_size);% increment every time collision happens 23 | channel_state = 'idle'; %channel state: idle, prea, data, SIFS, aACK, DIFS 24 | state_time = 0; % how long will the channel state last, except the idle state 25 | contention_time = 0; % how long that the channel has been idle during contention period 26 | backoff = zeros(1, network_size); 27 | is_collision = 0; 28 | for i = 1:network_size 29 | backoff(i) = (unidrnd(CWmin+1)-1)*t_slot; 30 | end 31 | if (Is_win(backoff, channel_win)==1) 32 | [is_win, channel_win_new] = Is_win(backoff, channel_win); % the new client who has won the channel 33 | if (length(channel_win_new)>1) 34 | is_collision = 1; 35 | end 36 | channel_state = 'prea'; 37 | state_time = preamble; 38 | end 39 | for i = 1: total_time 40 | if (channel_state == 'idle') 41 | contention_time = contention_time + 1; 42 | backoff = decrease_one(backoff, channel_win); 43 | if (Is_win(backoff, channel_win)==1) 44 | [is_win, channel_win_new] = Is_win(backoff, channel_win); % the new client who has won the channel 45 | if (length(channel_win_new)>1) 46 | is_collision = 1; 47 | end 48 | channel_state = 'prea'; 49 | state_time = preamble; 50 | contention_time = 0; 51 | end 52 | if (data_counter ~= 0) 53 | data_counter = data_counter - 1; 54 | tx_time = increase_one(tx_time, channel_win); 55 | end 56 | if (data_counter == 0 && parallel_counter > 0) 57 | channel_state = 'SIFS'; 58 | backoff = recover(backoff, channel_win,contention_time,t_slot); 59 | contention_time = 0; 60 | state_time = SIFS; 61 | end 62 | elseif (channel_state == 'prea') 63 | state_time = state_time - 1 ; 64 | if (parallel_counter < AP_antenna && data_counter ~=0) 65 | data_counter = data_counter - 1; 66 | tx_time = increase_one(tx_time, channel_win); % channel_win contains the clients who have won the channel 67 | end 68 | if (data_counter == 0 && parallel_counter > 0) 69 | channel_state = 'SIFS'; 70 | state_time = SIFS; 71 | elseif (state_time == 0) 72 | parallel_counter = parallel_counter + 1; 73 | channel_win = [channel_win channel_win_new]; 74 | if (parallel_counter == 1) 75 | data_counter = t_frame; 76 | end 77 | if (parallel_counter == AP_antenna) 78 | channel_state = 'data'; 79 | state_time = data_counter; 80 | elseif (parallel_counter < AP_antenna) 81 | channel_state = 'idle'; 82 | contention_time = 0; 83 | end 84 | end 85 | elseif (channel_state == 'data') 86 | state_time = state_time - 1; 87 | data_counter = data_counter -1; 88 | tx_time = increase_one(tx_time, channel_win); 89 | if (state_time == 0 ) 90 | channel_state = 'SIFS'; 91 | state_time = SIFS; 92 | end 93 | elseif (channel_state == 'SIFS') 94 | state_time = state_time - 1; 95 | if (state_time == 0) 96 | if (Is_collide(channel_win,AP_antenna) == 1 || is_collision == 1) 97 | channel_state = 'DIFS'; 98 | state_time = DIFS - SIFS; 99 | retry_counter = increase_retry(retry_counter, channel_win); 100 | backoff = retry_backoff(backoff, channel_win, retry_counter, CWmin, t_slot, CWmax); 101 | else 102 | channel_state = 'aACK'; 103 | state_time = ACK; 104 | end 105 | end 106 | elseif (channel_state == 'aACK') 107 | state_time = state_time - 1; 108 | if (state_time == 0) 109 | rate = ZF_SIC(channel_vector, channel_win, BW, tx_power, t_frame); % determine the transmission rate according to channel matrix and the tx order 110 | client_throughput = client_throughput + tx_time.*rate;% this round's tx rate 111 | backoff = increase_CWmin(backoff, channel_win, CWmin, t_slot); % backoff at least CWmin before next trasmission 112 | retry_counter = reset_retry_counter(retry_counter, channel_win); 113 | for p = 1: length(channel_win) 114 | client_tx(channel_win(p)) = client_tx(channel_win(p)) + 1; 115 | end 116 | channel_state = 'DIFS'; 117 | state_time = DIFS; 118 | end 119 | elseif (channel_state == 'DIFS') 120 | state_time = state_time - 1; 121 | if (state_time == 0) 122 | is_collision = 0; 123 | parallel_counter = 0; 124 | tx_time = zeros(1, network_size); 125 | channel_win = []; 126 | channel_vector = channel_generation(AP_antenna, network_size); 127 | if (Is_win(backoff, channel_win)==1) 128 | [is_win, channel_win_new] = Is_win(backoff, channel_win); 129 | if (length(channel_win_new)>1) 130 | is_collision = 1; 131 | end 132 | channel_state = 'prea'; 133 | state_time = preamble; 134 | contention_time = 0; 135 | else 136 | channel_state = 'idle'; 137 | contention_time = 0; 138 | end 139 | end 140 | end 141 | end 142 | network_throughput = sum(client_throughput)/total_time; %unit: mbps 143 | delay = total_time/mean(client_tx); %unit: us -------------------------------------------------------------------------------- /CCMA-oppMAC/CCMA_opp_main.m: -------------------------------------------------------------------------------- 1 | function [network_throughput, client_throughput, delay] = CCMA_opp_main(network_size, total_time, t_slot, t_frame, threshold, BW, tx_power) 2 | % This function calculates the network throughput and the throughput of 3 | % each client of a 802.11 MU-MIMO system. The network_size is the total 4 | % number of clients in the system. The total_time is the time we are 5 | % considering, with a time unit of 1 us. t_slot is the slot time needed to 6 | % reduce the backoff counter. t_frame is the time used to 7 | % transmit a frame by the first client who wins the channel. The Access 8 | % Point has 2 antennas, and the network_size>2. Client joining 9 | %the second contention period if its effective SNR is larger than threshold*SNRorig. 10 | network_throughput = 0; 11 | AP_antenna = 2; 12 | freeze_client = []; 13 | client_throughput = zeros(1, network_size); 14 | channel_vector = Channel_Allocation(network_size); 15 | client_tx = zeros(1,network_size); % number of successful transmissions performed by each client 16 | channel_win = []; % clients that have won the channel in a round 17 | count =[];% number of concurrent clients in a round 18 | tx_time_count = []; % time of clients in each round 19 | % CWmin = 15; 20 | % CWmax = 1023; 21 | CWmin = 127; 22 | CWmax = 1023; 23 | SIFS = 16; 24 | ACK = 39; 25 | DIFS = SIFS + 2*t_slot; 26 | preamble = 20; 27 | data_counter = 0; 28 | parallel_counter = 0; %number of ongoing transmission 29 | tx_time= zeros(1, network_size);% how long each client has transmit 30 | retry_counter = zeros(1, network_size);% increment every time collision happens 31 | channel_state = 'idle'; %channel state: idle, prea, data, SIFS, aACK, DIFS 32 | state_time = 0; % how long will the channel state last, except the idle state 33 | contention_time = 0; % how long that the channel has been idle during contention period 34 | backoff = zeros(1, network_size); 35 | is_collision = 0; 36 | for i = 1:network_size 37 | backoff(i) = (unidrnd(CWmin+1)-1)*t_slot; 38 | end 39 | if (Is_win(backoff, channel_win)==1) 40 | [is_win, channel_win_new] = Is_win(backoff, channel_win); % the new client who has won the channel 41 | if (length(channel_win_new)>1) 42 | is_collision = 1; 43 | end 44 | channel_state = 'prea'; 45 | state_time = preamble; 46 | end 47 | for i = 1: total_time 48 | if (channel_state == 'idle') 49 | contention_time = contention_time + 1; 50 | backoff = decrease_one_opp(backoff, channel_win, freeze_client); 51 | if (Is_win(backoff, channel_win)==1) 52 | [is_win, channel_win_new] = Is_win(backoff, channel_win); % the new client who has won the channel 53 | if (length(channel_win_new)>1) 54 | is_collision = 1; 55 | end 56 | channel_state = 'prea'; 57 | state_time = preamble; 58 | contention_time = 0; 59 | end 60 | if (data_counter ~= 0) 61 | data_counter = data_counter - 1; 62 | tx_time = increase_one(tx_time, channel_win); 63 | end 64 | if (data_counter == 0 && parallel_counter > 0) 65 | channel_state = 'SIFS'; 66 | backoff = recover(backoff, channel_win,contention_time,t_slot); 67 | contention_time = 0; 68 | state_time = SIFS; 69 | end 70 | elseif (channel_state == 'prea') 71 | state_time = state_time - 1 ; 72 | if (parallel_counter < AP_antenna && data_counter ~=0) 73 | data_counter = data_counter - 1; 74 | tx_time = increase_one(tx_time, channel_win); % channel_win contains the clients who have won the channel 75 | end 76 | if (data_counter == 0 && parallel_counter > 0) 77 | channel_state = 'SIFS'; 78 | state_time = SIFS; 79 | elseif (state_time == 0) 80 | parallel_counter = parallel_counter + 1; 81 | channel_win = [channel_win channel_win_new]; 82 | if (parallel_counter==1) 83 | freeze_client = freeze(backoff, channel_vector, threshold, channel_win, BW, tx_power, t_frame); 84 | end 85 | if (parallel_counter == 1) 86 | data_counter = t_frame; 87 | %rate = parallel_rate(channel_win, network_size); 88 | %backoff = prefer(backoff, channel_win, rate, network_size, C); % backoff time is changed after the first client winning the channel 89 | %rate = Rate(channel_win(1),:); 90 | end 91 | if (parallel_counter == AP_antenna) 92 | channel_state = 'data'; 93 | state_time = data_counter; 94 | elseif (parallel_counter < AP_antenna) 95 | channel_state = 'idle'; 96 | contention_time = 0; 97 | end 98 | end 99 | elseif (channel_state == 'data') 100 | state_time = state_time - 1; 101 | data_counter = data_counter -1; 102 | tx_time = increase_one(tx_time, channel_win); 103 | if (state_time == 0 ) 104 | channel_state = 'SIFS'; 105 | state_time = SIFS; 106 | end 107 | elseif (channel_state == 'SIFS') 108 | state_time = state_time - 1; 109 | if (state_time == 0) 110 | % freeze_client 111 | freeze_client = []; %release the freezed clients after each round 112 | if (Is_collide(channel_win,AP_antenna) == 1 || is_collision == 1) 113 | channel_state = 'DIFS'; 114 | state_time = DIFS - SIFS; 115 | retry_counter = increase_retry(retry_counter, channel_win); 116 | backoff = retry_backoff (backoff, channel_win, retry_counter, CWmin, t_slot, CWmax); 117 | %BO = [BO backoff];used for debugging 118 | else 119 | channel_state = 'aACK'; 120 | state_time = ACK; 121 | end 122 | end 123 | elseif (channel_state == 'aACK') 124 | state_time = state_time - 1; 125 | if (state_time == 0) 126 | %rate = Rate_Allocation(channel_win, channel_vector, BW, tx_power); 127 | % rate = zeros(1, network_size); 128 | % rate_opp = log_chi(BW, tx_power, threshold); 129 | % rate(channel_win(1)) = rate_opp(1); 130 | % if (length(channel_win)>1) 131 | % rate(channel_win(2)) = rate_opp(2); 132 | % end 133 | rate = ZF_SIC(channel_vector, channel_win, BW, tx_power, t_frame); 134 | client_throughput = client_throughput + tx_time.*rate;% this round's tx rate 135 | % tx_time 136 | % rate (channel_win(2)) 137 | backoff = increase_CWmin(backoff, channel_win, CWmin, t_slot); % backoff at least CWmin before next trasmission 138 | %BO = [BO backoff];used for debugging 139 | retry_counter = reset_retry_counter (retry_counter, channel_win); 140 | for p = 1: length(channel_win) 141 | client_tx(channel_win(p)) = client_tx(channel_win(p)) + 1; 142 | end 143 | channel_state = 'DIFS'; 144 | state_time = DIFS; 145 | end 146 | elseif (channel_state == 'DIFS') 147 | state_time = state_time - 1; 148 | if (state_time == 0) 149 | is_collision = 0; 150 | parallel_counter = 0; 151 | tx_time = zeros(1, network_size); 152 | %channel_win 153 | channel_win = []; 154 | channel_vector = Channel_Allocation(network_size); 155 | if (Is_win(backoff, channel_win)==1) 156 | [is_win, channel_win_new] = Is_win(backoff, channel_win); 157 | if (length(channel_win_new)>1) 158 | is_collision = 1; 159 | end 160 | channel_state = 'prea'; 161 | state_time = preamble; 162 | contention_time = 0; 163 | else 164 | channel_state = 'idle'; 165 | contention_time = 0; 166 | end 167 | end 168 | end 169 | end 170 | % count 171 | % tx_time_count 172 | network_throughput = sum(client_throughput)/total_time; 173 | delay = total_time/mean(client_tx); %unit: us -------------------------------------------------------------------------------- /CCMA/CSMA_CA_model_main.m: -------------------------------------------------------------------------------- 1 | function [network_throughput, delay, retry_no] = CSMA_CA_model_main(network_size,concurrent_tx,t_slot,t_frame, t_pre, CWmin, backoff_stage, BW, tx_power) 2 | % this function calculates the throughput of a CSMA/CA-based MU-MIMO WLAN, 3 | % by considering the case that there may be less than concurrent_tx clients 4 | % transmitting in a successful round. 5 | if (concurrent_tx > network_size) 6 | concurrent_num = network_size; 7 | else 8 | concurrent_num = concurrent_tx; 9 | end 10 | tau = equal_solve_20131219(network_size, concurrent_num, CWmin, backoff_stage,t_frame,t_slot,t_pre,concurrent_tx);% probability that one STA transmits in each slot time 11 | %tau = 0.011; 12 | payload = zeros(1, concurrent_num); % average number of transmitted data if one has won the m's concurrent transmission opportunity 13 | payload(1) = t_frame; 14 | SIFS = 16; 15 | ACK = 39; 16 | DIFS = 34; 17 | temp = t_frame; 18 | if (concurrent_num >1) 19 | for m = 2:concurrent_num 20 | no_tx = (1-tau)^(network_size+1-m); 21 | temp = temp - t_pre - t_slot*1/(1-no_tx); 22 | % if (temp <0) 23 | % temp = 0; 24 | % end 25 | payload(m) = temp; %average transmission time for each pkt 26 | end 27 | end 28 | %payload 29 | rate = zeros(1, concurrent_num); % average transmission rate for each concurrent client 30 | %rate(1) = BW*log2(1+AP_antenna*tx_power); 31 | for i = 1:concurrent_num 32 | degree = 2*(concurrent_tx - i+1); 33 | rate(i) = log_exp(degree,BW, tx_power); 34 | end 35 | p_success = zeros(1, concurrent_num); % probability that a random chosen round is a successful round with i clients (1<= i <= concurrent_num) 36 | waiting_time = zeros(1, concurrent_num); % if clients will not join a round with i preamble pauses, it has to wait for waiting_time(i) time 37 | waiting_time(1) = t_frame; 38 | for i = 2:concurrent_num 39 | waiting_time(i) = waiting_time(i-1) - t_pre; 40 | end 41 | temp = 1; 42 | for m = 1:concurrent_num 43 | if (m==1) 44 | temp = temp * (network_size-m+1)*tau*(1-tau)^(network_size - m)/(1-(1-tau)^(network_size+1-m)); 45 | else 46 | temp = temp * (network_size-m+1)*(1-tau)^((payload(m-1)-t_pre-payload(m))/t_slot*(network_size-m+1))*tau*(1-tau)^(network_size-m); 47 | end 48 | if (m~=concurrent_num) 49 | p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1)*(1-tau)^((payload(m)/t_slot)*(network_size-m)); 50 | else 51 | p_success(m) = temp * nchoosek(ceil(waiting_time(m)/t_slot)-1,m-1); 52 | end 53 | end 54 | p_success_include_i = zeros(1, concurrent_num); 55 | p_success_not_include_i = zeros(1, concurrent_num); 56 | for i = 1:concurrent_num 57 | p_success_include_i(i) = i/network_size*p_success(i); 58 | p_success_not_include_i(i) = (network_size-i)/network_size*p_success(i); 59 | end 60 | network_size_new = network_size - 1; 61 | if (concurrent_tx > network_size_new) 62 | concurrent_num_new = network_size_new; 63 | else 64 | concurrent_num_new = concurrent_tx; 65 | end 66 | p_success_new = zeros(1, concurrent_num_new); % probability that a random chosen round is a successful round with i clients (1<= i <= concurrent_num) 67 | waiting_time_new = zeros(1, concurrent_num_new); % if clients will not join a round with i preamble pauses, it has to wait for waiting_time(i) time 68 | waiting_time_new(1) = t_frame; 69 | for i = 2:concurrent_num_new 70 | waiting_time_new(i) = waiting_time_new(i-1) - t_pre; 71 | end 72 | temp = 1; 73 | for m = 1:concurrent_num_new 74 | if (m==1) 75 | temp = temp * (network_size_new-m+1)*tau*(1-tau)^(network_size_new - m)/(1-(1-tau)^(network_size_new+1-m)); 76 | else 77 | temp = temp * (network_size_new-m+1)*(1-tau)^((payload(m-1)-t_pre-payload(m))/t_slot*(network_size_new-m+1))*tau*(1-tau)^(network_size_new-m); 78 | end 79 | if (m~=concurrent_num_new) 80 | p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1)*(1-tau)^((payload(m)/t_slot)*(network_size_new-m)); 81 | else 82 | p_success_new(m) = temp * nchoosek(ceil(waiting_time_new(m)/t_slot)-1,m-1); 83 | end 84 | end 85 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | % p_a1 = tau*(1-tau)^(network_size-1)/(1-(1-tau)^network_size); 87 | % s = ceil(t_frame/t_slot); 88 | % for i = 2:concurrent_num 89 | % waiting_time(i) = waiting_time(i-1) - t_pre; 90 | % end 91 | % for i = 1:concurrent_num 92 | % if (waiting_time(i) <= 0) 93 | % p_success(i) = 0; 94 | % else 95 | % p_success(i) = nchoosek(network_size,i)*factorial(i)*p_a1*(1-(1-tau)^s)^(i-1)*nchoosek(s,m)/s^m*(1-tau)^(ceil(waiting_time(i)/t_slot)*(network_size-i)); 96 | % %p_success(i) = nchoosek(network_size,i)*factorial(i)*(1-tau)^(ceil(waiting_time(i)/t_slot)*(network_size-i))*tau^i; 97 | % end 98 | % end 99 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 100 | % p_win = (1-tau)^ceil(t_frame/t_slot); % probability that a client wins the transmission opportunity before the first contention winner finishes 101 | % p_success(1) = network_size*tau*(1-tau)^(network_size - 1)/(1-(1-tau)^network_size)*p_win^(network_size-1); 102 | % for j = 2:concurrent_num 103 | % p_success(j) = p_success(j-1)*(1-p_win)/p_win*(j-1)*tau*(1-tau)^(j-2)/(1-(1-tau)^(j-1)); 104 | % end 105 | % temp = 1; 106 | % for j = 1:concurrent_num 107 | % temp = temp * (network_size-j+1)*tau*(1-tau)^(network_size - j)/(1-(1-tau)^(network_size+1-j)); 108 | % if (j~=concurrent_num) 109 | % %p_success(j) = temp * (1-payload(j)/t_slot*(network_size-j)*tau); 110 | % p_success(j) = temp * (1-tau)^(ceil(payload(j)/t_slot)*(network_size-j)); 111 | % else 112 | % p_success(j) = temp; 113 | % end 114 | % end 115 | for i = 1:concurrent_num 116 | if (payload(i)<0) 117 | payload(i)=0; 118 | end 119 | end 120 | success_payload = zeros(1, concurrent_num); % the transmitted data in a successful round, with i clients/round (1<= i <= concurrent_num) 121 | temp = 0; 122 | for i = 1:concurrent_num 123 | temp = temp + payload(i)*rate(i); 124 | success_payload(i) = p_success(i)*temp/sum(p_success); 125 | end 126 | N_coll = (1-sum(p_success))/sum(p_success); % average number of collisions before one successful transmission 127 | %t_coll = t_slot*1/(1-(1-tau)^network_size) + t_pre + t_frame + DIFS; 128 | t_coll = t_slot*(1-tau)^network_size/(1-(1-tau)^network_size) + t_pre + t_frame + DIFS; % average time of one collision 129 | %t_success = t_slot*(1-tau)^network_size/(1-(1-tau)^network_size) + t_pre + t_frame + SIFS + ACK + DIFS; % average time of one successful transmission 130 | t_success = t_slot*1/(1-(1-tau)^network_size)*(1-1/CWmin)^concurrent_num + t_pre + t_frame + SIFS + ACK + DIFS; 131 | network_throughput = sum(success_payload)/(N_coll * t_coll + t_success); %unit: mbps 132 | delay = (N_coll * t_coll + t_success)*sum(p_success)/sum(p_success_include_i); %unit:micro-second 133 | p_include_i = 1-sum(p_success_not_include_i)/sum(p_success_new); 134 | retry_no = N_coll*p_include_i*sum(p_success)/sum(p_success_include_i); 135 | % payload_new = zeros(1, concurrent_num_new); % average number of transmitted data if one has won the m's concurrent transmission opportunity 136 | % payload_new(1) = t_frame; 137 | % temp = t_frame; 138 | % if (concurrent_num_new >1) 139 | % for m = 2:concurrent_num_new 140 | % no_tx = (1-tau)^(network_size_new+1-m); 141 | % temp = temp - t_pre - t_slot*1/(1-no_tx); 142 | % if (temp <0) 143 | % temp = 0; 144 | % end 145 | % payload_new(m) = temp; 146 | % end 147 | % end 148 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 149 | % for i = 1:concurrent_num_new 150 | % if (waiting_time_new(i) <= 0) 151 | % p_success_new(i) = 0; 152 | % else 153 | % p_success_new(i) = nchoosek(network_size_new,i)*factorial(i)*(1-tau)^(ceil(waiting_time_new(i)/t_slot)*(network_size_new-i))*tau^i; 154 | % end 155 | % end 156 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 157 | % p_win_new = (1-tau)^ceil(t_frame/t_slot); % probability that a client wins the transmission opportunity before the first contention winner finishes 158 | % p_success_new(1) = network_size_new*tau*(1-tau)^(network_size_new - 1)/(1-(1-tau)^network_size_new)*p_win_new^(network_size_new-1); 159 | % for j = 2:concurrent_num_new 160 | % p_success_new(j) = p_success_new(j-1)*(1-p_win_new)/p_win_new*(j-1)*tau*(1-tau)^(j-2)/(1-(1-tau)^(j-1)); 161 | % end 162 | % temp = 1; 163 | % for j = 1:concurrent_num_new 164 | % temp = temp * (network_size_new-j+1)*tau*(1-tau)^(network_size_new - j)/(1-(1-tau)^(network_size_new+1-j)); 165 | % if (j~=concurrent_num_new) 166 | % %p_success(j) = temp * (1-payload(j)/t_slot*(network_size-j)*tau); 167 | % p_success_new(j) = temp * (1-tau)^(ceil(payload_new(j)/t_slot)*(network_size_new-j)); 168 | % else 169 | % p_success_new(j) = temp; 170 | % end 171 | % end --------------------------------------------------------------------------------