1 #include "bs_types.h"
2 #include "bs_tracing.h"
3 #include "bs_utils.h"
4 #include "bs_rand_main.h"
5 #include "WLAN_actmod_argparse.h"
6 #include "WLAN_actmod_phy_if.h"
7 #include <signal.h>
8 
9 /**
10  * This function calculates when the next WLAN transmission will start and end,
11  * given that <Now> the previous one has just finished
12  */
13 static inline
calculate_next_transmission(bs_time_t Now,bs_time_t * times_start,bs_time_t * times_end,WLAN_actmod_args_t * args)14 void calculate_next_transmission(bs_time_t Now, bs_time_t *times_start,
15                                  bs_time_t *times_end, WLAN_actmod_args_t *args)
16 {
17   //All calculations in us (double)
18   double SilenceT = args->DIFS;
19 
20   //we calculate a contention window:
21   SilenceT = SilenceT + bs_random_uniformR(0, args->AveCWSize * 2); //a U(0,AveCWSize*2)
22 
23   if (bs_random_uniform() >= args->p) { //and we check if there is or not just now a new transmission
24     //if we don't actually want to transmit, we calculate how far away in the future we will
25     SilenceT = SilenceT + bs_random_GPRND(args->kappa, args->sigma*1000, 0);
26   }
27 
28   if ( SilenceT > args->BeaconPeriod * 1e6 ) { //to have at least "beacons"
29     SilenceT = args->BeaconPeriod * 1e6;
30   }
31 
32   //And we calculate the Tx duration
33   //We draw a random packet:
34   double packet_size = bs_random_uniformRi( args->PacketMinSize, args->PacketMaxSize) * 8.0/ args->DataRate;
35   //And the total TX time (including the silent SIFS time is)
36   double tx_size = packet_size + args->PacketHeaderSize/args->DataRate
37                  + args->SIFS + args->ACKT + args->ACKBe/args->DataRate;
38 
39   *times_start = Now + SilenceT;
40   *times_end   = Now + SilenceT + tx_size;
41 }
42 
choose_a_port(WLAN_actmod_args_t * args)43 static unsigned int choose_a_port(WLAN_actmod_args_t *args){
44   //do a random drop and chose from which port this burst will go
45   if (args->number_ports == 1)
46     return 0;
47 
48   double drop = bs_random_uniform(); //a random number in [0..1]
49 
50   for (int i = 0 ; i < args->number_ports ; i ++) {
51     if (drop < args->ports_probs[i]) {
52       return i;
53     } else {
54       drop -= args->ports_probs[i];
55     }
56   }
57   //This should really not happen as args->ports_probs[*] adds to 1
58   return args->number_ports;
59 }
60 
main(int argc,char * argv[])61 int main(int argc, char *argv[]) {
62   WLAN_actmod_args_t args;
63 
64   /*
65    * Let's ensure that even if we are redirecting to a file, we get stdout line
66    * buffered (default for console)
67    * Note that glibc ignores size, just in case we set a reasonable number in
68    * case somebody tries to compile against a different library
69    */
70   setvbuf(stdout, NULL, _IOLBF, 512);
71   setvbuf(stderr, NULL, _IOLBF, 512);
72 
73   //when disconnecting we are not careful to check if the Phy has already closed its end
74   signal(SIGPIPE, SIG_IGN);
75 
76   bs_trace_set_prefix("d_??:");
77   bs_trace_register_time_function(WLAN_actmod_get_time);
78   WLAN_actmod_argparse(argc, argv, &args);
79 
80   bs_trace_raw(9,"Connecting...\n");
81   WLAN_actmod_init_phy_com(&args);
82 
83   bs_random_init(args.rseed);
84 
85   int i;
86   bs_time_t Time = 0;
87   p2G4_tx_t tx_s;
88 
89   tx_s.radio_params.modulation = args.modulation;
90   tx_s.packet_size = 0;
91   tx_s.phy_address = 0;
92   tx_s.radio_params.center_freq = args.centerfreq;
93   tx_s.power_level = args.powerdBm;
94   tx_s.abort.abort_time = TIME_NEVER;
95   tx_s.abort.recheck_time = TIME_NEVER;
96 
97   for (i = 0 ; i < args.n_times_start ; i ++) {
98     if ( args.times_start[i] <= Time ) {
99       bs_trace_error_line("The list of times needs to be ordered (index %i:"
100           " %i <= %i)\n",
101           i, args.times_start[i], Time);
102     }
103     if (args.times_end[i] <= args.times_start[i]) {
104       bs_trace_error_line("End times need to be bigger than starting times "
105           "(index %i: %i <= %i)\n",
106           i, args.times_end[i], args.times_start[i]);
107     }
108 
109     Time = args.times_start[i];
110 
111     while (Time < args.times_end[i]) {
112       bs_time_t start_time, end_time;
113 
114       calculate_next_transmission(Time, &start_time, &end_time, &args);
115 
116       if ( end_time > args.times_end[i]){
117         break;
118       }
119       tx_s.start_time = start_time;
120       tx_s.end_time = end_time;
121 
122       if (WLAN_actmod_Tx_in_port(&tx_s, choose_a_port(&args))) {
123         i = args.n_times_start; //to also exit the for loop
124         break; //while
125       }
126 
127       Time = end_time;
128     }
129   }
130 
131   bs_trace_raw_time(9,"Disconnecting...\n");
132   WLAN_actmod_disconnect_phy_com();
133 
134   return 0;
135 }
136