| | 55 | |
| | 56 | == WiFi Packet Generation == |
| | 57 | \\ |
| | 58 | {{{#!matlab |
| | 59 | % Ryan Davis |
| | 60 | |
| | 61 | PAYLOAD = 1500; % bytes |
| | 62 | PATH = ""; |
| | 63 | |
| | 64 | for i = 0:7 |
| | 65 | filename = "WiFi_802.11n_" + i + "MCS_int16.dat"; |
| | 66 | ht = wlanHTConfig("MCS", i, "ChannelBandwidth", "CBW20"); |
| | 67 | |
| | 68 | payload = randi([0 1], [1 PAYLOAD*8]); |
| | 69 | txSig = wlanWaveformGenerator(payload,ht); |
| | 70 | |
| | 71 | output_txSig = formatOutput(txSig); |
| | 72 | |
| | 73 | fid = fopen(PATH + filename, "w"); |
| | 74 | fwrite(fid, output_txSig, "int16"); |
| | 75 | fclose(fid); |
| | 76 | end |
| | 77 | clear; |
| | 78 | |
| | 79 | function arr = formatOutput(txSig) |
| | 80 | arr = zeros(size(txSig)*2); |
| | 81 | j = 1; |
| | 82 | for i = 1:size(txSig) |
| | 83 | arr(j) = cast(real(txSig(i)), "int16"); |
| | 84 | arr(j+1) = cast(imag(txSig(i)), "int16"); |
| | 85 | j=j+2; |
| | 86 | end |
| | 87 | end |
| | 88 | }}} |
| | 89 | == Experiment Automation == |
| | 90 | \\ |
| | 91 | {{{#!ruby |
| | 92 | # Ryan Davis |
| | 93 | # Adapted from code by Ivan Seskar |
| | 94 | |
| | 95 | Experiment.name = "Artificial_WiFi" |
| | 96 | Experiment.project = "Artificial_WiFi" |
| | 97 | |
| | 98 | consoleExec("omf tell -t all -a offh") |
| | 99 | consoleExec("omf load -i usrpcal_2020-02-24.ndz -t node3-2,node3-19,node8-7,node8-14,node13-7,node13-14,node18-2,node18-19,node3-1,node3-20,node18-1,node18-20 -r 0") |
| | 100 | consoleExec("omf tell -t node3-2,node3-19,node8-7,node8-14,node13-7,node13-14,node18-2,node18-19,node3-1,node3-20,node18-1,node18-20 -a on") |
| | 101 | |
| | 102 | freqs = ["2412e6", "2437e6", "2462e6", "5180e6", "5240e6", "5745e6", "5825e6"] |
| | 103 | mcss = ["0", "1", "2", "3", "4", "5", "6", "7"] |
| | 104 | |
| | 105 | topos = {"3" => [["node18-1", "node18-2"], ["node3-1", "node3-2"], ["node18-19", "node18-20"], ["node3-19", "node3-20"]], # format: dist => [["txnode_A", "rxnode_A"], ["txnode_B", "rxnode_B"] ... ] |
| | 106 | "15" => [["node13-7", "node8-7"], ["node13-14","node8-14"]], |
| | 107 | "45" => [["node18-1", "node3-1"], ["node18-2", "node3-2"], ["node18-19", "node3-19"], ["node18-20", "node3-20"]], |
| | 108 | "72" => [["node18-20", "node3-1"], ["node18-1", "node3-20"]] } |
| | 109 | |
| | 110 | defApplication('tx', 'tx_samples_from_file') { |a| |
| | 111 | a.version(1, 0, 0) |
| | 112 | a.shortDescription = "" |
| | 113 | a.description = "" |
| | 114 | a.path = "export LC_ALL=C;/usr/local/lib/uhd/examples/tx_samples_from_file" |
| | 115 | a.defProperty('freq', "center frequency in Hz", '--freq', |
| | 116 | {:dynamic => false, :type => :string}) |
| | 117 | a.defProperty('ant', "antenna to be used", '--subdev', |
| | 118 | {:dynamic => false, :type => :string}) |
| | 119 | a.defProperty('rate', "baseband rate in Hz", '--rate', |
| | 120 | {:dynamic => false, :type => :string}) |
| | 121 | a.defProperty('gain', "receiver gain in dB", '--gain', |
| | 122 | {:dynamic => false, :type => :string}) |
| | 123 | a.defProperty('file', "reveived baseband waveform file name", '--file', |
| | 124 | {:dynamic => false, :type => :string}) |
| | 125 | a.defProperty('type', "sample types", '--type', |
| | 126 | {:dynamic => false, :type => :string}) |
| | 127 | a.defProperty('repeat', "continuously repeat", '--repeat', |
| | 128 | {:dynamic => false, :type => :string}) |
| | 129 | } |
| | 130 | |
| | 131 | defApplication('rx', 'rx_samples_to_file') { |a| |
| | 132 | a.version(1, 0, 0) |
| | 133 | a.shortDescription = "" |
| | 134 | a.description = "" |
| | 135 | a.path = "export LC_ALL=C;/usr/local/lib/uhd/examples/rx_samples_to_file" |
| | 136 | a.defProperty('freq', "center frequency in Hz", '--freq', |
| | 137 | {:dynamic => false, :type => :string}) |
| | 138 | a.defProperty('rate', "baseband rate in Hz", '--rate', |
| | 139 | {:dynamic => false, :type => :string}) |
| | 140 | a.defProperty('gain', "receiver gain in dB", '--gain', |
| | 141 | {:dynamic => false, :type => :string}) |
| | 142 | a.defProperty('nsamps', "number of samples", '--nsamps', |
| | 143 | {:dynamic => false, :type => :string}) |
| | 144 | a.defProperty('file', "reveived baseband waveform file name", '--file', |
| | 145 | {:dynamic => false, :type => :string}) |
| | 146 | a.defProperty('type', "sample types", '--type', |
| | 147 | {:dynamic => false, :type => :string}) |
| | 148 | a.defProperty('discardtime', "time at which storing samples starts", '--discardtime', |
| | 149 | {:dynamic => false, :type => :string}) |
| | 150 | } |
| | 151 | |
| | 152 | topos.each { |dist, topo| |
| | 153 | topo.each { |node_pair| |
| | 154 | freqs.each { |freq| |
| | 155 | mcss.each { |mcs| |
| | 156 | infilename = "WiFi_802.11n_"+mcs+"_int16.dat" |
| | 157 | exptag = dist+"ft_"+freq+"Hz_"+mcs+"MCS_"+node_pair[0]+","+node_pair[1] |
| | 158 | outfilename = "/root/rx_"+exptag+"_int16.dat" |
| | 159 | info("Setting up group for experiment: " + exptag) |
| | 160 | |
| | 161 | rxGroup = node_pair[1]+"@"+exptag |
| | 162 | txGroup = node_pair[0]+"@"+exptag |
| | 163 | |
| | 164 | defGroup(txGroup, node_pair[0]) { |n| |
| | 165 | n.addApplication('tx') { |app| |
| | 166 | app.setProperty('freq', freq) |
| | 167 | app.setProperty('ant', "A:0") |
| | 168 | app.setProperty('gain', "30") |
| | 169 | app.setProperty('type', "short") |
| | 170 | app.setProperty('file', infilename) |
| | 171 | app.setProperty('rate', "20e6") |
| | 172 | app.setProperty('repeat'," ") |
| | 173 | } |
| | 174 | } |
| | 175 | |
| | 176 | defGroup(rxGroup, node_pair[1]) { |n| |
| | 177 | n.addApplication('rx') { |app| |
| | 178 | app.setProperty('freq',freq) |
| | 179 | app.setProperty('gain', "30") |
| | 180 | app.setProperty('type',"short") |
| | 181 | app.setProperty('nsamps',"40000000") |
| | 182 | app.setProperty('file',outfilename) |
| | 183 | app.setProperty('rate',"40e6") |
| | 184 | } |
| | 185 | } |
| | 186 | } |
| | 187 | } |
| | 188 | } |
| | 189 | } |
| | 190 | trap("INT") { |
| | 191 | allGroups.stopApplications |
| | 192 | allGroups.exec("/usr/bin/pkill -9 -f rx_samples") |
| | 193 | allGroups.exec("/usr/bin/pkill -9 -f tx_samples") |
| | 194 | exit! |
| | 195 | } |
| | 196 | |
| | 197 | onEvent(:ALL_UP_AND_INSTALLED) { |event| |
| | 198 | # Wait for nodes to associate and give it an extra 5 sec just in case... |
| | 199 | sleep 5 |
| | 200 | |
| | 201 | # scp IQ binary file to transmitters |
| | 202 | txfiles = "txfiles/WiFi*" |
| | 203 | topos.each { |dist, topo| |
| | 204 | topo.each { |node_pair| |
| | 205 | consoleExec("ssh root@" + node_pair[0] + " rm -f /root/*.dat") |
| | 206 | consoleExec("ssh root@" + node_pair[1] + " rm -f /root/*.dat") |
| | 207 | |
| | 208 | consoleExec("scp -o StrictHostKeyChecking=no " + txfiles + " root@"+node_pair[0]+":"); |
| | 209 | consoleExec("scp -o StrictHostKeyChecking=no test.sh root@"+node_pair[0]+":"); # TODO temp for debugging |
| | 210 | } |
| | 211 | } |
| | 212 | |
| | 213 | topos.each { |dist, topo| |
| | 214 | topo.each { |node_pair| |
| | 215 | freqs.each { |freq| |
| | 216 | mcss.each { |mcs| |
| | 217 | exptag = dist+"ft_"+freq+"Hz_"+mcs+"MCS_"+node_pair[0]+","+node_pair[1] |
| | 218 | info ("\nStarting experiment: " + exptag) |
| | 219 | rxGroup = node_pair[1]+"@"+exptag |
| | 220 | txGroup = node_pair[0]+"@"+exptag |
| | 221 | |
| | 222 | group(rxGroup).startApplications # start receiver (captures for 1 sec) |
| | 223 | sleep 1 # make sure we do not start transmitting before receiving |
| | 224 | group(txGroup).startApplications # start transmitter |
| | 225 | |
| | 226 | sleep 5 # wait for applications to hopefully finish |
| | 227 | |
| | 228 | group(txGroup).stopApplications |
| | 229 | group(rxGroup).stopApplications |
| | 230 | |
| | 231 | outfilename = "/root/rx_"+exptag+"_int16.dat" |
| | 232 | consoleExec("scp -o StrictHostKeyChecking=no root@" + node_pair[1] + ":" + outfilename + " /spare/spectrum/Artificial_WiFi/") #copy recved data to archive |
| | 233 | consoleExec("ssh root@" + node_pair[1] + " rm -f " +outfilename) |
| | 234 | } |
| | 235 | } |
| | 236 | } |
| | 237 | } |
| | 238 | |
| | 239 | allGroups.stopApplications |
| | 240 | Experiment.done |
| | 241 | } |
| | 242 | }}} |
| | 243 | |