-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlf_tx_power.py
executable file
·2197 lines (1909 loc) · 136 KB
/
lf_tx_power.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/python3
'''
LANforge 192.168.100.178
Controller at 192.168.100.112 admin/Cisco123
Controller is 192.1.0.10
AP is 192.1.0.2'''
EPILOG = '''\
##############################################################################################
# Support History
##############################################################################################
##############################################################################
Sample script to run create station, wlan and talk to ap 1/26/2021 run on 9800
carriage returns specifically left out
##############################################################################
./lf_tx_power.py -d 172.19.27.55 -u admin -p Wnbulab@123 --port 2013 --scheme telnet --ap 9120_Candela --bandwidth "20" --channel "52 100 104" --nss 4 --txpower "1" --pathloss 56 --antenna_gain 6 --band a --upstream_port eth2 --series 9800 --radio wiphy5 --slot 1 --ssid open-wlan --prompt "katar_candela" --create_station sta0001 --ssidpw [BLANK] --security open --verbose --wlan open-wlan --wlanID 1 --wlanSSID open-wlan --ap_info "ap_scheme==telnet ap_prompt==9120_Candela ap_ip==172.19.27.55 ap_port==2008 ap_user==admin ap_pw==Wnbulab@123"
#############################################################
Sample to test pf_ignore_offset switch 1/27/2021 run on 9800
carriage returns specifically left out
#############################################################
./lf_tx_power.py -d 172.19.27.55 -u admin -p Wnbulab@123 --port 2013 --scheme telnet --ap 9120_Candela --bandwidth "20" --channel "36 52 100 104 161" --nss 4 --txpower "1" --pathloss 56 --antenna_gain 6 --band a --upstream_port eth2 --series 9800 --radio wiphy5 --slot 1 --ssid open-wlan --prompt "katar_candela" --create_station sta0001 --ssidpw [BLANK] --security open --verbose --wlan open-wlan --wlanID 1 --wlanSSID open-wlan --pf_ignore_offset "35"
##############################################################################################
##############################################################################################
make sure pexpect is installed:
$ sudo yum install python3-pexpect
$ sudo yum install python3-xlsxwriter
You might need to install pexpect-serial using pip:
$ pip3 install pexpect-serial
$ pip3 install XlsxWriter
This script will automatically create and start a layer-3 UDP connection between the
configured upstream port and station.
The user also has the option of setting up the station oustide of this script, however.
# Examples:
# See cisco_power_results.txt when complete.
# See cisco_power_results.xlsx when complete.
NOTE: Telnet port 23 unless specified , ssh port 22 unless specified, scheme defaults to ssh
##############################################################################################
# read AP for powercfg values using : show controllers dot11Radio 1 powercfg | g T1'
##############################################################################################
./lf_tx_power.py -d 172.19.27.55 -u admin -p Wnbulab@123 --port 2013 --scheme telnet \
--ap 9120_Candela --bandwidth "20" --channel "149" --nss 4 --txpower "1" \
--pathloss 56 --band a --upstream_port eth2 --series 9800 --radio wiphy5 --slot 1 --ssid open-wlan \
--prompt "katar_candela" --create_station sta0001 --ssidpw [BLANK] --security open --verbose \
--antenna_gain "6" --wlanID 1 --wlan open-wlan --wlanSSID open-wlan\
--ap_info "ap_scheme==telnet ap_prompt==9120_Candela ap_ip==172.19.27.55 ap_port==2008 ap_user==admin ap_pw==Wnbulab@123"
##############################################################################################
# send email and or text on --exit_on_fail
##############################################################################################
./lf_tx_power.py -d 192.168.100.112 -u admin -p Cisco123 -s ssh --port 22 -a APA453.0E7B.CF9C --lfmgr 192.168.100.178 \
--bandwidth "80" --channel "144" --nss 4 --txpower "1" --pathloss 51 --antenna_gain 10 --lfmgr 192.168.100.178 --band a \
--upstream_port eth3 --outfile cisco_power_results --create_station sta0001 --radio wiphy1 --ssid test_candela --ssidpw [BLANK] \
--security open -l out_file2 -D 14 --exit_on_fail \
--email "[email protected] passwd==lanforge123 [email protected] smtp==smtp.gmail.com port==465"\
--email "[email protected] passwd==lanforge123 [email protected] smtp==smtp.gmail.com port==465"\
--series "3504" --prompt "(Cisco Controler)"
##############################################################################################
# Long duration test -- need to create the ---wlanID 1 --wlan open-wlan --wlanSSID open-wlan
##############################################################################################
./lf_tx_power.py -d 172.19.36.168 -u admin -p Wnbulab@123 --port 23 --scheme telnet --ap "APA453.0E7B.CF60" \
--bandwidth "20 40 80" --channel "36 40 44 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 144 149 153 157 161 165" \
--nss 4 --txpower "1 2 3 4 5 6 7 8" --pathloss 54 --antenna_gain 6 --band a --upstream_port eth2 --series 9800 \
--wlanID 1 --wlan open-wlan --wlanSSID open-wlan --create_station sta0001 --radio wiphy1 --ssid open-wlan --ssidpw [BLANK] --security open \
--outfile cisco_power_results_60_chan_ALL --cleanup --slot 1 --verbose
##############################################################################################
# Per-channel path-loss example station present
##############################################################################################
./lf_tx_power.py -d 192.168.100.112 -u admin -p Cisco123 -s ssh --port 22 -a VC --lfmgr 192.168.100.178 \
--station sta00000 --bandwidth "20 40 80 160" --channel "36:64 149:60" --antenna_gain 5 --nss 4 --txpower "1 2 3 4 5 6 7 8" --pathloss 64 \
--band a --upstream_port eth2 --lfresource2 2 --verbose
##############################################################################################
# To create a station run test against station create open-wlan
##############################################################################################
./lf_tx_power.py -d <router IP> -u admin -p Cisco123 -port 23 --scheme telnet --ap AP6C71.0DE6.45D0 \
--station sta2222 --bandwidth "20" --channel "36" --nss 4 --txpower "1 2 3 4 5 6 7 8" --pathloss 54 --antenna_gain 6 --band a \
--upstream_port eth2 --series 9800 --wlanID 1 --wlan open-wlan --wlanSSID open-wlan --create_station sta2222 --radio wiphy1 --ssid open-wlan \
--ssidpw [BLANK] --security open --verbose
##############################################################################################
# station already present
##############################################################################################
./lf_tx_power.py -d <router IP> -u admin -p Cisco123 -port 23 --scheme telnet --ap AP6C71.0DE6.45D0 \
--station sta0000 --bandwidth "20" --channel "36" --nss 4 --txpower "1 2 3 4 5 6 7 8" --pathloss 64 --antenna_gain 5 --band a \
--upstream_port eth2 --series 9800 --wlanID 1 --wlan open-wlan --wlanSSID open-wlan --verbose
##############################################################################################
# to create a station
##############################################################################################
./lf_associate_ap.pl --radio wiphy1 --ssid open-wlan --passphrase [BLANK] ssecurity open --upstream eth1 \
--first_ip DHCP --first_sta sta0001 --duration 5 --cxtype udp
Changing regulatory domain should happen outside of this script.
##############################################################################################
# If wish to send Text after test completion follow the email format based on carrier
##############################################################################################
Text message via email:
T-Mobile – [email protected]
Virgin Mobile – [email protected]
AT&T – [email protected]
Sprint – [email protected]
Verizon – [email protected]
Tracfone – [email protected]
Ting – [email protected]
Boost Mobile – [email protected]
U.S. Cellular – [email protected]
Metro PCS – [email protected]
##############################################################################################
# OUTPUT in XLSX file - Spread sheet how values determined
##############################################################################################
Tx Power : Input from command line (1-8)
Allowed Per Path : Read from the Controller
Cabling Pathloss : Input from command line, best if verified prior to testing
Antenna Gain : Input from command line, if AP cannot detect antenna connection
Beacon RSSI (beacon_sig) : From Lanforge probe, command ./lf_portmod.pl with cli parameter probe_port 1 (~line 1183, ~line 1209)
Combined RSSI User (sig) : From Lanforge probe, command ./lf_portmod.pl with cli parameter probe_port 1 (~line 1183, ~line 1193)
RSSI 1, RSSI 2, RSSI 3, RSSI 4 : (~line 1160)
ants[q] (antX) read from Lanforge probe, command ./lf_portmod.pl with cli parameter probe_port 1
Ant 1, Ant 2, Ant 3, Ant 4 : ()
Starting Value for antX read from lanforge probe, using command ./lf_portmod.pl with cli parameter porbe_port 1
_noise_bear (_noise_i) = from Lanforge returning NOISE from command (!line 1070) lf_portmod.pl reading --show_port
"AP, IP, Mode, NSS, Bandwith, Channel, Signal, NOISE, Status, RX-Rate
rssi_adj (only used if --adjust_nf and _noise_bare != None) (~line 1263) _noise_i(_noise_bear) - nf_at_calibration (fixed value of -105)
Thus calc_antX = int(antX read from Lanforge) + pi (path loss from command line) + rssi_adj + ag (antenna gain from command line)
calc_antX is put on the spread sheet under Ant X
Offset 1, Offset 2, Offset 3, Offset 4: which in the code is diff_aX = calc_antX - allowed_per_path (adjusted based on number of streams)
Pass/Fail : (~line 1286) If the diff / offset is greater than the pfrange determins the pass or fail
'''
import sys
if sys.version_info[0] != 3:
print("This script requires Python 3")
exit()
import re
import logging
import time
from time import sleep
import argparse
import subprocess
import xlsxwriter
import math
NL = "\n"
CR = "\r\n"
Q = '"'
A = "'"
FORMAT = '%(asctime)s %(name)s %(levelname)s: %(message)s'
lfmgr = "127.0.0.1"
lfstation = "sta00000"
lfresource = "1"
lfresource2 = "1"
outfile = "cisco_power_results.txt"
full_outfile = "cisco_power_results_full.txt"
outfile_xlsx = "cisco_power_results.xlsx"
upstream_port = "eth1"
pf_dbm = 6
# Allow one chain to have a lower signal, since customer's DUT has
# lower tx-power on one chain when doing high MCS at 4x4.
pf_ignore_offset = 0
# Threshold for allowing a pass
failed_low_threshold = 0
# This below is only used when --adjust_nf is used.
# Noise floor on ch 36 where we calibrated -54 path loss (based on hard-coded -95 noise-floor in driver)
nf_at_calibration = -105
# older ath10k driver hard-codes noise-floor to -95 when calculating RSSI
# RSSI = NF + reported_power
# Shift RSSI by difference in actual vs calibrated noise-floor since driver hard-codes
# the noise floor.
# rssi_adjust = (current_nf - nf_at_calibration)
def usage():
print("############ USAGE ############")
print("-d|--dest: destination host, address of the controller")
print("-o|--port: destination port, default = 23")
print("-u|--user: login name or username")
print("-p|--passwd: password")
print("-s|--scheme (serial|telnet|ssh): connect via serial, ssh or telnet")
print("-t|--tty tty serial device")
print("-l|--log <store true> log has same namelog messages here ,stdout means output to console, default stdout")
print("-a|--ap select AP")
print("-b|--bandwidth: List of bandwidths to test: 20 40 80 160, NA means no change, 160 can only do 2x2 spatial streams due to radio limitations")
print("-c|--channel: List of channels, with optional path-loss to test: 36:64 100:60 , NA means no change")
print("-n|--nss: List of spatial streams to test: 1x1 2x2 3x3 4x4, NA means no change")
print("-T|--txpower: List of TX power values to test: 1 2 3 4 5 6 7 8, NA means no change, 1 is highest power, the power is halved for each subsquent setting")
print("-k|--keep_state <store true> keep the state, no configuration change at the end of the test, store true flage present ")
print("--station: LANforge station name for test(sta0000), use if station present and --create_station not used")
print("--upstream_port: LANforge upstream port name (eth1)")
print("--lfmgr: LANforge manager IP address")
print("--lfresource: LANforge resource ID for station")
print("--lfresource2: LANforge resource ID for upstream port")
print("--outfile: Output file for txt and xlsx data, default cisco_power_results")
print("--pathloss: Calculated path-loss between LANforge station and AP")
print("--antenna_gain: Antenna gain for AP, if no Antenna attached then antenna gain needs to be taken into account, default 0")
print("--band: Select band (a | b | abgn), a means 5Ghz, b means 2.4, abgn means 2.4 on dual-band AP, default a")
print("--pf_dbm: Pass/Fail range, default is 6")
print("--pf_ignore_offset: Allow one chain to use lower tx-power and still pass when doing 4x4, default 100. so disabled")
print("--wait_forever: <store true> Wait forever for station to associate, may aid debugging if STA cannot associate properly")
print("--adjust_nf: <store true> Adjust RSSI based on noise-floor. ath10k without the use-real-noise-floor fix needs this option")
print("--wlan: for 9800, wlan identifier ")
print("--wlanID: wlanID for 9800 , defaults to 1")
print("--wlanSSID: wlanSSID for 9800")
print("--series: controller series 9800 , defaults to 3504")
print("--slot: 9800 AP slot defaults to 1")
print("--create_station", "create LANforge station at the beginning of the test")
print("--radio" ,"radio to create LANforge station on at the beginning of the test")
print("--ssid", "ssid default open-wlan")
print("--ssidpw", "ssidpw default [BLANK]")
print("--security", "security default open")
print("--cleanup", "<store true> Clean up all stations after test completes, only need switch for True, Defaults False")
print("--vht160", "<store true> Enables VHT160 in lanforge, only need switch for True, Defaults False")
print("--verbose","<store ture> switch the cisco controller output will be captured")
print("--exit_on_fail","--exit_on_fail, exit on test failure")
print("--exit_on_error","--exit_on_error, exit on test error, test mechanics failed")
print('-e','--email', "--email user==<from email> passwd==<email password> to==<to email> smtp==<smtp server> port==<smtp port> 465 (SSL)")
print('-ccp','--prompt', "--prompt controller prompt default WLC")
print('--beacon_dbm_diff', "--beacon_dbm_diff <value> is the delta that is allowed between the controller tx and the beacon measured")
print('--show_lf_portmod',"<store_true> show the output of lf_portmod after traffic to verify RSSI values measured by lanforge")
print('-api','--ap_info', "--ap_info ap_scheme==<telnet,ssh or serial> ap_prompt==<ap_prompt> ap_ip==<ap ip> ap_port==<ap port number> ap_user==<ap user> ap_pw==<ap password>")
print("-h|--help")
# see https://stackoverflow.com/a/13306095/11014343
class FileAdapter(object):
def __init__(self, logger):
self.logger = logger
def write(self, data):
# NOTE: data can be a partial line, multiple lines
data = data.strip() # ignore leading/trailing whitespace
if data: # non-blank
self.logger.info(data)
def flush(self):
pass # leave it to logging to flush properly
def exit_test(workbook):
workbook.close()
sleep(0.5)
exit(1)
def main():
global lfmgr
global lfstation
global lfresource
global lfresource2
global outfile
global outfile_xlsx
global full_outfile
global upstream_port
global pf_dbm
global pf_ignore_offset
global failed_low_threshold
scheme = "ssh"
parser = argparse.ArgumentParser(description="Cisco TX Power report Script",epilog=EPILOG,
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("-d", "--dest", type=str, help="address of the cisco controller",required=True)
parser.add_argument("-o", "--port", type=str, help="control port on the controller",required=True)
parser.add_argument("-u", "--user", type=str, help="credential login/username",required=True)
parser.add_argument("-p", "--passwd", type=str, help="credential password",required=True)
parser.add_argument("-s", "--scheme", type=str, choices=["serial", "ssh", "telnet"], help="Connect via serial, ssh or telnet")
parser.add_argument("-t", "--tty", type=str, help="tty serial device")
parser.add_argument("-l", "--log", action='store_true', help="create logfile for messages, default stdout")
parser.add_argument("-a", "--ap", type=str, help="select AP")
parser.add_argument("-b", "--bandwidth", type=str, help="List of bandwidths to test. NA means no change")
parser.add_argument("-c", "--channel", type=str, help="List of channels to test, with optional path-loss, 36:64 149:60. NA means no change")
parser.add_argument("-n", "--nss", type=str, help="List of spatial streams to test. NA means no change")
parser.add_argument("-T", "--txpower", type=str, help="List of txpowers to test. NA means no change")
parser.add_argument("-k","--keep_state", action="store_true",help="keep the state, no configuration change at the end of the test")
parser.add_argument('-D','--duration', type=str, help='--traffic <how long to run in seconds> example -t 20 (seconds) default: 20 ',default='20')
parser.add_argument("--station", type=str, help="LANforge station to use (sta0000, etc) use if station present and --create_station not used")
parser.add_argument("--upstream_port", type=str, help="LANforge upsteram-port to use (eth1, etc)")
parser.add_argument("--lfmgr", type=str, help="LANforge Manager IP address")
parser.add_argument("--lfresource", type=str, help="LANforge resource ID for the station")
parser.add_argument("--lfresource2", type=str, help="LANforge resource ID for the upstream port system")
parser.add_argument("--outfile", type=str, help="Output file for csv data",default="cisco_power_results")
parser.add_argument("--pathloss", type=str, help="Calculated pathloss between LANforge Station and AP")
parser.add_argument("--antenna_gain", type=str, help="Antenna gain, take into account the gain due to the antenna",default="0")
parser.add_argument("--band", type=str, help="Select band (a | b), a means 5Ghz, b means 2.4Ghz. Default is a",
choices=["a", "b", "abgn"])
parser.add_argument("--pf_dbm", type=str, help="Pass/Fail threshold. Default is 6",default="6" )
parser.add_argument("--pf_ignore_offset", type=str, help="Allow a chain to have lower tx-power and still pass. default 0 so disabled",default="0")
parser.add_argument("--wait_forever", action='store_true', help="Wait forever for station to associate, may aid debugging if STA cannot associate properly")
parser.add_argument("--adjust_nf", action='store_true', help="Adjust RSSI based on noise-floor. ath10k without the use-real-noise-floor fix needs this option")
parser.add_argument("--wlan", type=str, help="--wlan 9800, wlan identifier",required=True)
parser.add_argument("--wlanID", type=str, help="--wlanID 9800 , defaults to 1",default="1",required=True)
parser.add_argument("--wlanSSID", type=str, help="--wlan 9800, wlan SSID, this must match the -ssid , ssid for station",required=True)
parser.add_argument("--series", type=str, help="--series 9800 or 3504, defaults to 9800",default="9800")
parser.add_argument("--slot", type=str, help="--slot 1 , 9800 AP slot defaults to 1",default="1")
parser.add_argument("--create_station", type=str, help="create LANforge station at the beginning of the test")
parser.add_argument("--radio", type=str, help="radio to create LANforge station on at the beginning of the test")
parser.add_argument("--ssid", type=str, help="ssid, this must patch the wlan",required=True)
parser.add_argument("--ssidpw", type=str, help="ssidpw",required=True)
parser.add_argument("--security", type=str, help="security",required=True)
parser.add_argument("--cleanup", action='store_true',help="--cleanup , Clean up stations after test completes ")
parser.add_argument("--vht160", action='store_true',help="--vht160 , Enable VHT160 in lanforge ")
parser.add_argument('--verbose', action='store_true',help='--verbose , switch the cisco controller output will be captured')
parser.add_argument("--exit_on_fail", action='store_true',help="--exit_on_fail, exit on test failure")
parser.add_argument("--exit_on_error", action='store_true',help="--exit_on_error, exit on test error, test mechanics failed")
parser.add_argument('-e','--email', action='append', nargs=1, type=str, help="--email user==<from email> passwd==<email password> to==<to email> smtp==<smtp server> port==<smtp port> 465 (SSL)")
parser.add_argument('-ccp','--prompt', type=str,help="controller prompt",required=True)
parser.add_argument('--beacon_dbm_diff', type=str,help="--beacon_dbm_diff <value> is the delta that is allowed between the controller tx and the beacon measured",default="7")
parser.add_argument('--show_lf_portmod', action='store_true',help="--show_lf_portmod, show the output of lf_portmod after traffic to verify RSSI values measured by lanforge")
parser.add_argument('-api','--ap_info', action='append', nargs=1, type=str, help="--ap_info ap_scheme==<telnet,ssh or serial> ap_prompt==<ap_prompt> ap_ip==<ap ip> ap_port==<ap port number> ap_user==<ap user> ap_pw==<ap password>")
#current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "{:.3f}".format(time.time() - (math.floor(time.time())))[1:]
#print(current_time)
#usage()
args = None
try:
# Parcing the input parameters and assignment
args = parser.parse_args()
if (args.scheme != None):
scheme = args.scheme
#logfile = args.log
if (args.station != None):
lfstation = args.station
if (args.create_station != None):
lfstation = args.create_station
if (args.station != None):
print("NOTE: both station: {} and create_station: {} on command line, test will use create_station {} ".format(args.station, args.create_station, args.create_station))
if (args.upstream_port != None):
upstream_port = args.upstream_port
if (args.lfmgr != None):
lfmgr = args.lfmgr
if (args.lfresource != None):
lfresource = args.lfresource
if (args.lfresource2 != None):
lfresource2 = args.lfresource2
if (args.outfile != None):
outfile = args.outfile
full_outfile = "full-%s"%(outfile)
outfile_xlsx = "%s.xlsx"%(outfile)
if (args.band != None):
band = args.band
else:
band = "a"
if (args.pf_dbm != None):
pf_dbm = int(args.pf_dbm)
if (args.pf_ignore_offset != None):
pf_ignore_offset = int(args.pf_ignore_offset)
if (args.verbose):
# capture the controller output , thus won't go to stdout some output always present
cap_ctl_out = False
else:
cap_ctl_out = True
if (args.wlanSSID != args.ssid):
print("####### ERROR ################################")
print("wlanSSID: {} must equial the station ssid: {}".format(args.wlanSSID,args.ssid))
print("####### ERROR ################################")
exit(1)
# note: there would always be an args.outfile due to the default
current_time = time.strftime("%m_%d_%Y_%H_%M_%S", time.localtime())
outfile = "{}_{}.txt".format(args.outfile,current_time)
full_outfile = "{}_full_{}.txt".format(args.outfile,current_time)
outfile_xlsx = "{}_{}.xlsx".format(args.outfile,current_time)
print("output file: {}".format(outfile))
print("output file full: {}".format(full_outfile))
print("output file xlsx: {}".format(outfile_xlsx))
if args.log:
outfile_log = "{}_{}_output_log.log".format(args.outfile,current_time)
print("output file log: {}".format(outfile_log))
ap_dict = []
if args.ap_info:
ap_info = args.ap_info
for _ap_info in ap_info:
print("ap_info {}".format(_ap_info))
ap_keys = ['ap_scheme','ap_prompt','ap_ip','ap_port','ap_user','ap_pw']
ap_dict = dict(map(lambda x: x.split('=='), str(_ap_info).replace('[','').replace(']','').replace("'","").split()))
for key in ap_keys:
if key not in ap_dict:
print("missing ap config, for the {}, all these need to be set {} ".format(key,ap_keys))
exit(1)
print("ap_dict: {}".format(ap_dict))
email_dicts = []
if args.email:
emails = args.email
for _email in emails:
#print("email {}".format(_email))
email_keys = ['user','passwd','to','smtp','port']
_email_dict = dict(map(lambda x: x.split('=='), str(_email).replace('[','').replace(']','').replace("'","").split()))
#print("email_dict {}".format(_email_dict))
for key in email_keys:
if key not in _email_dict:
print("missing config, for the {}, all of the following need to be present {} ".format(key,email_keys))
exit(1)
email_dicts.append(_email_dict)
print("email_dicts: {}".format(email_dicts))
except Exception as e:
logging.exception(e)
usage()
exit(2)
console_handler = logging.StreamHandler()
formatter = logging.Formatter(FORMAT)
logg = logging.getLogger(__name__)
logg.setLevel(logging.DEBUG)
file_handler = None
# Setting up log file if specified
if args.log:
file_handler = logging.FileHandler(outfile_log, "w")
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
logg.addHandler(file_handler)
logg.addHandler(logging.StreamHandler(sys.stdout)) # allows to logging to file and stderr
#logging.basicConfig(format=FORMAT, handlers=[console_handler])
else:
#pass
# stdout logging
logging.basicConfig(format=FORMAT, handlers=[console_handler])
#logg.addHandler(logging.StreamHandler()) # allows to logging to file and stderr
if bool(ap_dict):
logg.info("ap_dict {}".format(ap_dict))
if bool(email_dicts):
logg.info("email_dicts {}".format(email_dicts))
if args.outfile != None:
logg.info("output file: {}".format(outfile))
logg.info("output file full: {}".format(full_outfile))
logg.info("output file xlsx: {}".format(outfile_xlsx))
if args.log:
logg.info("output file log: {}".format(outfile_log))
if (args.bandwidth == None):
usage()
logg.info("ERROR: Must specify bandwidths")
exit(1)
if (args.channel == None):
usage()
logg.info("ERROR: Must specify channels")
exit(1)
if (args.nss == None):
usage()
logg.info("ERROR: Must specify NSS")
exit(1)
if (args.txpower == None):
usage()
logg.info("ERROR: Must specify txpower")
exit(1)
if (args.pathloss == None):
logg.info("ERROR: Pathloss must be specified.")
exit(1)
if (args.antenna_gain == None):
usage()
logg.info("ERROR: Antenna gain must be specified.")
exit(1)
# Full spread-sheet data
csv = open(full_outfile, "w")
csv.write("Regulatory Domain\tCabling Pathloss\tAntenna Gain\tCfg-Channel\tCfg-NSS\tCfg-AP-BW\tTx Power\tBeacon-Signal\tCombined-Signal\tRSSI 1\tRSSI 2\tRSSI 3\tRSSI 4\tAP-BSSID\tRpt-BW\tRpt-Channel\tRpt-Mode\tRpt-NSS\tRpt-Noise\tRpt-Rxrate\tCtrl-AP-MAC\tCtrl-Channel\tCtrl-Power\tCtrl-dBm\tCalc-dBm-Combined\tDiff-dBm-Combined\tAnt-1\tAnt-2\tAnt-3\tAnt-4\tOffset-1\tOffset-2\tOffset-3\tOffset-4\tPASS/FAIL(+-%sdB)\tTimeStamp\tWarnings-and-Errors"%(pf_dbm))
csv.write("\n");
csv.flush()
# Summary spread-sheet data
csvs = open(outfile, "w")
csvs.write("Regulatory Domain\tCabling Pathloss\tAntenna Gain\tAP Channel\tNSS\tAP BW\tTx Power\tAllowed Per-Path\tRSSI 1\tRSSI 2\tRSSI 3\tRSSI 4\tAnt-1\tAnt-2\tAnt-3\tAnt-4\tOffset-1\tOffset-2\tOffset-3\tOffset-4\tPASS/FAIL(+-%sdB)\tTimeStamp\tWarnings-and-Errors"%(pf_dbm))
csvs.write("\n");
csvs.flush()
# XLSX file
workbook = xlsxwriter.Workbook(outfile_xlsx)
worksheet = workbook.add_worksheet()
#bold = workbook.add_format({'bold': True, 'align': 'center'})
dblue_bold = workbook.add_format({'bold': True, 'align': 'center'})
dblue_bold.set_bg_color("#b8cbe4")
dblue_bold.set_border(1)
dtan_bold = workbook.add_format({'bold': True, 'align': 'center'})
dtan_bold.set_bg_color("#dcd8c3")
dtan_bold.set_border(1)
dpeach_bold = workbook.add_format({'bold': True, 'align': 'center'})
dpeach_bold.set_bg_color("#ffd8bb")
dpeach_bold.set_border(1)
dpink_bold = workbook.add_format({'bold': True, 'align': 'center'})
dpink_bold.set_bg_color("#fcc8ca")
dpink_bold.set_border(1)
dyel_bold = workbook.add_format({'bold': True, 'align': 'center'})
dyel_bold.set_bg_color("#ffe699")
dyel_bold.set_border(1)
dgreen_bold = workbook.add_format({'bold': True, 'align': 'center'})
dgreen_bold.set_bg_color("#c6e0b4")
dgreen_bold.set_border(1)
dgreen_bold_left = workbook.add_format({'bold': True, 'align': 'left'})
dgreen_bold_left.set_bg_color("#c6e0b4")
dgreen_bold_left.set_border(1)
#center = workbook.add_format({'align': 'center'})
center_blue = workbook.add_format({'align': 'center'})
center_blue.set_bg_color("#dbe5f1")
center_blue.set_border(1)
center_tan = workbook.add_format({'align': 'center'})
center_tan.set_bg_color("#edede1")
center_tan.set_border(1)
center_peach = workbook.add_format({'align': 'center'})
center_peach.set_bg_color("#fce4d6")
center_peach.set_border(1)
center_yel = workbook.add_format({'align': 'center'})
center_yel.set_bg_color("#fdf2cc")
center_yel.set_border(1)
center_yel_red = workbook.add_format({'align': 'center', 'color': 'red'})
center_yel_red.set_bg_color("#fdf2cc")
center_yel_red.set_border(1)
center_pink = workbook.add_format({'align': 'center'})
center_pink.set_bg_color("ffd2d3")
center_pink.set_border(1)
red = workbook.add_format({'color': 'red', 'align': 'center'})
red.set_bg_color("#e0efda")
red.set_border(1)
red_left = workbook.add_format({'color': 'red', 'align': 'left'})
red_left.set_bg_color("#e0efda")
red_left.set_border(1)
green = workbook.add_format({'color': 'green', 'align': 'center'})
green.set_bg_color("#e0efda")
green.set_border(1)
green_left = workbook.add_format({'color': 'green', 'align': 'left'})
green_left.set_bg_color("#e0efda")
green_left.set_border(1)
orange_left = workbook.add_format({'color': 'orange', 'align': 'left'})
orange_left.set_bg_color("#e0efda")
orange_left.set_border(1)
worksheet.set_row(0, 45) # Set height
worksheet.set_column(0, 0, 10) # Set width
col = 0
row = 0
worksheet.write(row, col, 'Regulatory\nDomain', dblue_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Controller', dblue_bold); col += 1
worksheet.set_column(col, col, 12) # Set width
worksheet.write(row, col, 'Controller\nChannel', dblue_bold); col += 1
worksheet.write(row, col, 'AP\nChannel', dblue_bold); col += 1
worksheet.write(row, col, 'NSS', dblue_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Controller\nBW', dblue_bold); col += 1
worksheet.write(row, col, 'STA\nRpt\nBW', dblue_bold); col += 1
worksheet.write(row, col, 'Tx\nPower', dtan_bold); col += 1
worksheet.write(row, col, 'Allowed\nPer\nPath', dtan_bold); col += 1
worksheet.write(row, col, 'Cabling\nPathloss', dtan_bold); col += 1
worksheet.write(row, col, 'Antenna\nGain', dtan_bold); col += 1
worksheet.write(row, col, 'Noise\n', dpeach_bold); col += 1
if (args.adjust_nf):
worksheet.write(row, col, 'Noise\nAdjust\n(vs -105)', dpeach_bold); col += 1
worksheet.set_column(col, col, 15) # Set width
worksheet.write(row, col, 'Last\nMCS\n', dpeach_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Beacon\nRSSI\n', dpeach_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Combined\nRSSI\n', dpeach_bold); col += 1
worksheet.write(row, col, 'RSSI\n1', dpeach_bold); col += 1
worksheet.write(row, col, 'RSSI\n2', dpeach_bold); col += 1
worksheet.write(row, col, 'RSSI\n3', dpeach_bold); col += 1
worksheet.write(row, col, 'RSSI\n4', dpeach_bold); col += 1
worksheet.write(row, col, 'Ant\n1', dpink_bold); col += 1
worksheet.write(row, col, 'Ant\n2', dpink_bold); col += 1
worksheet.write(row, col, 'Ant\n3', dpink_bold); col += 1
worksheet.write(row, col, 'Ant\n4', dpink_bold); col += 1
worksheet.write(row, col, 'Offset\n1', dyel_bold); col += 1
worksheet.write(row, col, 'Offset\n2', dyel_bold); col += 1
worksheet.write(row, col, 'Offset\n3', dyel_bold); col += 1
worksheet.write(row, col, 'Offset\n4', dyel_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Controller\n dBm', dblue_bold); col += 1
worksheet.set_column(col, col, 10) # Set width
worksheet.write(row, col, 'Calculated\n dBm\n Beacon', dblue_bold); col += 1
worksheet.set_column(col, col, 18) # Set width
worksheet.write(row, col, 'Diff Controller dBm\n & Beacon dBm \n (+/- {} dBm)'.format(args.beacon_dbm_diff), dblue_bold); col += 1
worksheet.set_column(col, col, 14) # Set width
worksheet.write(row, col, 'Calculated\n dBm\n Combined', dblue_bold); col += 1
worksheet.set_column(col, col, 14) # Set width
worksheet.write(row, col, 'Diff\nController dBm\n & Combined', dblue_bold); col += 1
worksheet.set_column(col, col, 12) # Set width
worksheet.write(row, col, "PASS /\nFAIL\n( += %s dBm)"%(pf_dbm), dgreen_bold); col += 1
worksheet.set_column(col, col, 24) # Set width
worksheet.write(row, col, 'Time Stamp\n', dgreen_bold); col += 1
worksheet.set_column(col, col, 100) # Set width
worksheet.write(row, col, 'Information, Warnings, Errors', dgreen_bold_left); col += 1
row += 1
bandwidths = args.bandwidth.split()
channels = args.channel.split()
nss = args.nss.split()
txpowers = args.txpower.split()
# The script has the ability to create a station if one does not exist
if (args.create_station != None):
if (args.radio == None):
logg.info("WARNING --create needs a radio")
exit_test(workbook)
elif (args.vht160):
logg.info("creating station with VHT160 set: {} on radio {}".format(args.create_station,args.radio))
subprocess.run(["./lf_associate_ap.pl", "--radio", args.radio, "--ssid", args.ssid , "--passphrase", args.ssidpw,
"--security", args.security, "--upstream", args.upstream_port, "--first_ip", "DHCP",
"--first_sta",args.create_station,"--action","add","--xsec","ht160_enable"], timeout=20, capture_output=True)
sleep(3)
else:
logg.info("creating station: {} on radio {}".format(args.create_station,args.radio))
subprocess.run(["./lf_associate_ap.pl", "--radio", args.radio, "--ssid", args.ssid , "--passphrase", args.ssidpw,
"--security", args.security, "--upstream", args.upstream_port, "--first_ip", "DHCP",
"--first_sta",args.create_station,"--action","add"], timeout=20, capture_output=True)
sleep(3)
# Find LANforge station parent radio
parent = None
port_stats = subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, "--card", lfresource, "--port_name", lfstation,
"--show_port", "Parent/Peer"], capture_output=True);
pss = port_stats.stdout.decode('utf-8', 'ignore');
for line in pss.splitlines():
m = re.search('Parent/Peer:\s+(.*)', line)
if (m != None):
parent = m.group(1)
# Create downstream connection
# First, delete any old one
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource, "--action", "do_cmd",
"--cmd", "rm_cx all c-udp-power"], capture_output=True);
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource, "--action", "do_cmd",
"--cmd", "rm_endp c-udp-power-A"], capture_output=True);
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource2, "--action", "do_cmd",
"--cmd", "rm_endp c-udp-power-B"], capture_output=True);
# Now, create the new connection
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource, "--action", "create_endp", "--port_name", lfstation,
"--endp_type", "lf_udp", "--endp_name", "c-udp-power-A", "--speed", "0", "--report_timer", "1000"], capture_output=True);
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource2, "--action", "create_endp", "--port_name", upstream_port,
"--endp_type", "lf_udp", "--endp_name", "c-udp-power-B", "--speed", "1000000", "--report_timer", "1000"], capture_output=True);
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource, "--action", "create_cx", "--cx_name", "c-udp-power",
"--cx_endps", "c-udp-power-A,c-udp-power-B", "--report_timer", "1000"], capture_output=True);
myrd = ""
# The script supports both the 9800 series controller and the 3504 series controller , the controllers have different interfaces
if args.series == "9800":
try:
logg.info("9800 wifi_ctl_9800_3504.py: no_logging_console")
advanced = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "no_logging_console","--series",args.series,"--port",args.port,"--prompt",args.prompt], capture_output=True, check=True)
pss = advanced.stdout.decode('utf-8', 'ignore');
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("####################################################################################################")
logg.info("# CHECK IF CONTROLLER HAS TELNET CONNECTION ALREADY ACTIVE")
logg.info("####################################################################################################")
logg.info("####################################################################################################")
logg.info("# Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
logg.info("####################################################################################################")
exit_test(workbook)
try:
logg.info("9800 wifi_ctl_9800_3504.py: line_console_0")
advanced = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "line_console_0","--series",args.series,"--port",args.port,"--prompt",args.prompt], capture_output=True, check=True)
pss = advanced.stdout.decode('utf-8', 'ignore');
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
try:
logg.info("9800/3504 wifi_ctl_9800_3504.py: summary")
advanced = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "summary","--series",args.series,"--port",args.port,"--prompt",args.prompt], capture_output=True, check=True)
pss = advanced.stdout.decode('utf-8', 'ignore');
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
# Find our current regulatory domain so we can report it properly
searchap = False
for line in pss.splitlines():
if (line.startswith("---------")):
searchap = True
continue
# the summaries are different between the 9800 series controller and the 3504 series
# if the output changes then the following pattern/regular expression parcing needs to be changed
# this site may help: https://regex101.com/
# when using https://regex101.com/ for tool beginning of string begins with ^
if (searchap):
if args.series == "9800":
pat = "%s\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(\S+)"%(args.ap)
else:
pat = "%s\s+\S+\s+\S+\s+\S+\s+\S+.* (\S+)\s+\S+\s*\S+\s+\["%(args.ap)
m = re.search(pat, line)
if (m != None):
myrd = m.group(1)
# Loop through all iterations and run txpower tests.
# The is the main loop of loops: Channels, spatial streams (nss), bandwidth (bw), txpowers (tx)
# Note: supports 9800 and 3504 controllers
wlan_created = False
for ch in channels:
pathloss = args.pathloss
antenna_gain = args.antenna_gain
ch_colon = ch.count(":")
if (ch_colon == 1):
cha = ch.split(":")
pathloss = cha[1]
ch = cha[0]
for n in nss:
for bw in bandwidths:
if (n != "NA"):
ni = int(n)
if (parent == None):
logg.info("ERROR: Skipping setting the spatial streams because cannot find Parent radio for station: %s."%(lfstation))
else:
# Set nss on LANforge Station, not sure it can be done on AP
if (bw == "160"):
# 9984 hardware needs 2 chains to do one NSS at 160Mhz
if (ni > 2):
if(args.vht160):
ni = 2
logg.info("NOTE: --vht160 set will set ni : {}".format(ni))
# Set radio to 2x requested value
ni *=2
logg.info("NOTE: --vht160 set will set ni * 2 : {}".format(ni))
else:
logg.info("NOTE: Skipping NSS %s for 160Mhz, LANforge radios do not support more than 2NSS at 160Mhz currently."%(n))
logg.info("NOTE: use --vht160 to force 2NSS at 160Mhz")
continue
else:
# Set radio to 2x requested value for 160Mhz
ni *= 2
antset = 0 # all available
if (ni == 1):
antset = 1
if (ni == 2):
antset = 4
if (ni == 3):
antset = 7
set_cmd = "set_wifi_radio 1 %s %s NA NA NA NA NA NA NA NA NA %s"%(lfresource, parent, antset)
logg.info("Setting LANforge radio to %s NSS with command: %s"%(ni, set_cmd))
subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, "--card", lfresource, "--port_name", parent,
"--cli_cmd", set_cmd], capture_output=True)
# tx power 1 is the highest power , 2 power is 1/2 of 1 power etc till power 8 the lowest.
for tx in txpowers:
# e_tot is the errors, w_tot is the warning, i_tot is information
e_tot = ""
w_tot = ""
i_tot = ""
# Stop traffic , if traffic was running , this is on the lanforge side. Commands that start with lf_ are directed
# towards the lanforge
subprocess.run(["./lf_firemod.pl", "--manager", lfmgr, "--resource", lfresource, "--action", "do_cmd",
"--cmd", "set_cx_state all c-udp-power STOPPED"], capture_output=True);
# Down station
port_stats = subprocess.run(["./lf_portmod.pl", "--manager", lfmgr, "--card", lfresource, "--port_name", lfstation,
"--set_ifstate", "down"]);
# Disable AP, apply settings, enable AP
try:
logg.info("3504/9800 wifi_ctl_9800_3504.py: disable AP {}".format(args.ap))
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "disable","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("####################################################################################################")
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
logg.info("####################################################################################################")
logg.info("####################################################################################################")
logg.info("#CHECK IF CONTROLLER HAS TELNET CONNECTION ALREADY ACTIVE")
logg.info("####################################################################################################")
exit_test(workbook)
if args.series == "9800":
# 9800 series need to "Configure radio for manual channel assignment"
logg.info("9800 Configure radio for manual channel assignment")
try:
logg.info("9800 wifi_ctl_9800_3504.py: disable_wlan")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "disable_wlan","--wlan", args.wlan, "--wlanID", args.wlanID, "--wlanSSID", args.wlanSSID,
"--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
try:
logg.info("9800 wifi_ctl_9800_3504.py: disable_network_5ghz")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "disable_network_5ghz","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
try:
logg.info("9800 wifi_ctl_9800_3504.py: disable_network_24ghz")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "disable_network_24ghz","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
try:
logg.info("9800 wifi_ctl_9800_3504.py: manual")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "manual","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
else:
try:
logg.info("3504 wifi_ctl_9800_3504.py: config 802.11a disable network")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "cmd", "--value", "config 802.11a disable network","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
try:
logg.info("3504 wifi_ctl_9800_3504.py: config 802.11b disable network")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "cmd", "--value", "config 802.11b disable network","--series",args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
logg.info("9800/3504 test_parameters_summary: set : tx: {} ch: {} bw: {}".format(tx,ch,bw))
if (tx != "NA"):
logg.info("9800/3504 test_parameters: set txPower: {}".format(tx))
try:
logg.info("9800/3504 wifi_ctl_9800_3504.py: txPower {}".format(tx))
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "txPower", "--value", tx, "--series" , args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
if (bw != "NA"):
try:
logg.info("9800/3504 wifi_ctl_9800_3504.py: bandwidth 20 prior to setting channel, some channels only support 20")
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "bandwidth", "--value", "20", "--series" , args.series,"--port", args.port,"--prompt",args.prompt],capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
# NSS is set on the station earlier...
if (ch != "NA"):
logg.info("9800/3504 test_parameters set channel: {}".format(ch))
try:
logg.info("9800/3504 wifi_ctl_9800_3504.py: channel {}".format(ch))
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "channel", "--value", ch, "--series" , args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
if (bw != "NA"):
logg.info("9800/3504 test_parameters bandwidth: set : {}".format(bw))
try:
logg.info("9800/3504 wifi_ctl_9800_3504.py: bandwidth {}".format(bw))
ctl_output = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "bandwidth", "--value", bw, "--series" , args.series,"--port", args.port,"--prompt",args.prompt], capture_output=cap_ctl_out, check=True)
if cap_ctl_out:
pss = ctl_output.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
# only create the wlan the first time
if args.series == "9800":
if wlan_created:
logg.info("wlan already present, no need to create wlanID {} wlan {} wlanSSID {} port {}".format(args.wlanID, args.wlan, args.wlanSSID, args.port))
pass
else:
# Verify that a wlan does not exist on wlanID
# delete the wlan if already exists
try:
logg.info("9800 wifi_ctl_9800_3504.py: show_wlan_summary")
wlan_info = subprocess.run(["./wifi_ctl_9800_3504.py", "--scheme", scheme, "-d", args.dest, "-u", args.user, "-p", args.passwd, "-a", args.ap, "--band", band,
"--action", "show_wlan_summary","--series" , args.series,"--port", args.port,"--prompt",args.prompt], capture_output=True, check=True)
pss = wlan_info.stdout.decode('utf-8', 'ignore')
logg.info(pss)
except subprocess.CalledProcessError as process_error:
logg.info("Controller unable to commicate to AP or unable to communicate to controller error code: {} output {}".format(process_error.returncode, process_error.output))
exit_test(workbook)
# "number of WLANs:\s+(\S+)"
search_wlan = False
for line in pss.splitlines():
logg.info(line)
if (line.startswith("---------")):
search_wlan = True
continue
if (search_wlan):
pat = "{}\s+(\S+)\s+(\S+)".format(args.wlanID)
m = re.search(pat, line)
if (m != None):
cc_wlan = m.group(1)