source: ReferenceDesigns/w3_802.11/python/examples/log/log_process_summarize.py

Last change on this file was 6320, checked in by chunter, 5 years ago

1.8.0 release wlan-exp

File size: 11.1 KB
Line 
1"""
2------------------------------------------------------------------------------
3Mango 802.11 Reference Design - Experiments Framework - Log File Details
4------------------------------------------------------------------------------
5License:   Copyright 2014-2019, Mango Communications. All rights reserved.
6           Distributed under the WARP license (http://warpproject.org/license)
7------------------------------------------------------------------------------
8This script uses the WLAN Exp Log utilities to prase raw log data and print
9details about the Tx and Rx events at the two nodes.
10
11Hardware Setup:
12    - None.  Parsing log data can be done off-line
13
14Required Script Changes:
15    - Set LOGFILE to the file name of your WLAN Exp log HDF5 file
16
17Description:
18    This script parses the log file and generates numpy arrays of for all Tx
19    and Rx events in the logs.
20------------------------------------------------------------------------------
21"""
22import os
23import sys
24import numpy as np
25import time
26
27import wlan_exp.util as wlan_exp_util
28
29import wlan_exp.log.util as log_util
30import wlan_exp.log.util_hdf as hdf_util
31import wlan_exp.log.util_sample_data as sample_data_util
32
33
34#-----------------------------------------------------------------------------
35# Process command line arguments
36#-----------------------------------------------------------------------------
37
38DEFAULT_LOGFILE = 'ap_two_node_two_flow_capture.hdf5'
39logfile_error   = False
40
41# Use log file given as command line argument, if present
42if(len(sys.argv) != 1):
43    LOGFILE = str(sys.argv[1])
44
45    # Check if the string argument matchs a local file
46    if not os.path.isfile(LOGFILE):
47        # User specified non-existant file - give up and exit
48        logfile_error = True
49
50else:
51    # No command line argument - check if default file name exists locally
52    LOGFILE = DEFAULT_LOGFILE
53
54    if not os.path.isfile(LOGFILE):
55        # No local file specified or found - check for matching sample data file
56        try:
57            LOGFILE = sample_data_util.get_sample_data_file(DEFAULT_LOGFILE)
58            print("Local log file not found - Using sample data file!")
59        except IOError as e:
60            logfile_error = True
61
62if logfile_error:
63    print("ERROR: Logfile {0} not found".format(LOGFILE))
64    sys.exit()
65else:
66    print("Reading log file '{0}' ({1:5.1f} MB)\n".format(LOGFILE, (os.path.getsize(LOGFILE)/2**20)))
67
68
69#-----------------------------------------------------------------------------
70# Main script
71#-----------------------------------------------------------------------------
72
73# Get the log_data from the file
74log_data      = hdf_util.hdf5_to_log_data(filename=LOGFILE)
75
76# Get the raw_log_index from the file
77raw_log_index = hdf_util.hdf5_to_log_index(filename=LOGFILE)
78
79# Describe the raw_log_index
80log_util.print_log_index_summary(raw_log_index, "Log Index Contents:")
81
82# Filter log index to include all Rx entries and all Tx entries
83log_index = log_util.filter_log_index(raw_log_index,
84                                      include_only=['NODE_INFO', 'TIME_INFO', 'RX_OFDM', 'TX_HIGH', 'TX_LOW'],
85                                      merge={'RX_OFDM': ['RX_OFDM', 'RX_OFDM_LTG'],                                             
86                                             'TX_HIGH' : ['TX_HIGH', 'TX_HIGH_LTG'],
87                                             'TX_LOW' : ['TX_LOW', 'TX_LOW_LTG']})
88
89log_util.print_log_index_summary(log_index, "Filtered Log Index:")
90
91# Unpack the log into numpy structured arrays
92#   log_data_to_np_arrays returns a dictionary with one key-value pair per
93#    entry type included in the log_index argument. The log_index keys are reused
94#    as the output dictionary keys. Each output dictionary value is a numpy record array
95#    Refer to wlan_exp_log.log_entries.py for the definition of each record array datatype
96log_np = log_util.log_data_to_np_arrays(log_data, log_index)
97
98
99###############################################################################
100# Example 0: Print node info / Time info
101log_node_info = log_np['NODE_INFO'][0]
102
103print("Node Info:")
104print("  Node Type    : {0}".format(wlan_exp_util.node_type_to_str(log_node_info['node_type'])))
105print("  MAC Address  : {0}".format(wlan_exp_util.mac_addr_to_str(log_node_info['wlan_mac_addr'])))
106print("  Serial Number: {0}".format(wlan_exp_util.sn_to_str(log_node_info['platform_id'], log_node_info['serial_num'])))
107print("  WLAN Exp Ver : {0}".format(wlan_exp_util.ver_code_to_str(log_node_info['version'])))
108print("")
109
110if(len(log_np['TIME_INFO']) > 0):
111    log_time_info = log_np['TIME_INFO'][0]
112
113    print("Experiment Started at: {0}".format(time.ctime(float(log_time_info['host_timestamp'] / 1E6))))
114    print("")
115
116###############################################################################
117# Example 1: Gather some Tx information from the log
118#     - Since there are only loops, this example can deal with TX_HIGH / TX_LOW
119#       being an empty list and does not need a try / except.
120#
121
122# Initialize variables
123TX_CONSTS     = log_util.get_entry_constants('TX_LOW')
124log_tx_low    = log_np['TX_LOW']
125total_retrans = 0
126
127# Print header
128print("\nExample 1: Tx Information per Rate:")
129print("{0:^35} {1:^32}".format("Rate", "# Tx Pkts"))
130print("{0:^30} {1:>15} {2:>15}".format("", "CPU Low", "Re-trans"))
131
132# For each PHY mode, process the MCS index counts
133for phy_mode in wlan_exp_util.phy_modes.keys():
134    # Calculate the average time to send a packet for each rate
135    for mcs in range(0, 8):
136        # Create an index into the tx_Low array based on the following criteria:
137        #  - the PHY mode matches phy_mode in the above loop
138        #  - the MCS matches the mcs in the above loop
139        tx_low_idx         = ((log_tx_low['phy_mode'] == TX_CONSTS.phy_mode[phy_mode]) &
140                              (log_tx_low['mcs'] == mcs))
141                             
142   
143        # Extract arrays for each PHY mode   
144        tx_low_entries  = log_tx_low[tx_low_idx]
145                   
146        # Calculate retransmissions
147        #    Any packet whose "attempt_number" is larger than 1 is a retransmission
148        retrans = np.sum(tx_low_entries['attempt_number']>1)
149        total_retrans  += retrans
150
151        # Print info
152        try:
153            rate_info = wlan_exp_util.get_rate_info(mcs, phy_mode)
154            rate_str  = wlan_exp_util.rate_info_to_str(rate_info)
155            print("{0:30} {1:15} {2:15}".format(
156                rate_str,
157                len(tx_low_entries),
158                retrans))
159        except:
160            # Do nothing with unsupported PHY modes
161            pass
162
163print("\nTotal Retransmissions: {0:d}".format(total_retrans))
164
165
166
167###############################################################################
168# Example 2: Calculate total number of packets and bytes transmitted to each
169#            distinct MAC address for each of the MAC addresses in the header
170#
171
172# Skip this example if the log doesn't contain TX events
173for tx in ['TX_HIGH', 'TX_LOW']:
174    if(tx in log_np.keys()):
175        # Extract all OFDM transmissions
176        log_tx = log_np[tx]
177
178        # Count number of packets transmitted to each unique address in the 'addr1' field
179        tx_addrs_1 = log_tx['addr1']
180        tx_counts = dict()
181
182        for addr in np.unique(tx_addrs_1):
183            # Find indexes of all instances where addresses match
184            addr_idx = tx_addrs_1 == addr
185
186            # Count the number of packets (True values in index array) to this address
187            tx_pkts_to_addr  = np.sum(addr_idx)
188
189            # Count the number of bytes to this address
190            tx_bytes_to_addr = np.sum(log_tx['length'][addr_idx])
191
192            # Record the results in the output dictionary
193            tx_counts[addr] = (tx_pkts_to_addr, tx_bytes_to_addr)
194
195        # Print the results
196        if (tx == 'TX_HIGH'):
197            print("\nExample 2: Tx Counts (CPU High):")
198        else:
199            print("\nExample 2: Tx Counts (CPU Low - includes retransmissions):")
200        print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format(
201            "Dest Addr",
202            "# Pkts",
203            "# Bytes",
204            "MAC Addr Type"))
205
206        for k in sorted(tx_counts.keys()):
207            # Use the string version of the MAC address as the key for readability
208            print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format(
209                wlan_exp_util.mac_addr_to_str(k),
210                tx_counts[k][0],
211                tx_counts[k][1],
212                wlan_exp_util.mac_addr_desc(k)))
213
214#################################################################################################
215# Example 3: Calculate total number of packets and bytes received from each distinct MAC address
216
217# Skip this example if the log doesn't contain RX events
218if('RX_OFDM' in log_np.keys()):
219
220    # Extract all receptions
221    log_rx = log_np['RX_OFDM']
222
223    # Get RX_OFDM entry constants
224    RX_CONSTS = log_util.get_entry_constants('RX_OFDM')
225
226    # Extract only Rx entries with:
227    #   - Good checksum (FCS = good)
228    #   - Data / Management packets
229    #
230    rx_idx       = (((log_rx['flags'] & RX_CONSTS.flags.FCS_GOOD) != 0) & 
231                    ((log_rx['pkt_type'] == RX_CONSTS.pkt_type.DATA) | 
232                     (log_rx['pkt_type'] == RX_CONSTS.pkt_type.QOSDATA) | 
233                     (log_rx['pkt_type'] == RX_CONSTS.pkt_type.NULLDATA) | 
234                     (log_rx['pkt_type'] == RX_CONSTS.pkt_type.BEACON) | 
235                     (log_rx['pkt_type'] == RX_CONSTS.pkt_type.PROBE_RESP)))
236
237    rx_good_data_mgmt = log_rx[rx_idx]
238   
239    # Extract addr2 field from all good packets
240    rx_addrs_2 = rx_good_data_mgmt['addr2']
241
242    # Build a dictionary using unique MAC addresses as keys
243    rx_counts = dict()
244    for addr in np.unique(rx_addrs_2):
245        # Find indexes of all instances where addresses match
246        addr_idx = rx_addrs_2 == addr
247
248        # Count the number of packets (True values in index array) from this address
249        rx_pkts_from_addr  = np.sum(addr_idx)
250
251        # Count the number of bytes from this address
252        try:
253            # If addr_idx is greater than 1
254            rx_bytes_from_addr = np.sum(rx_good_data_mgmt['length'][addr_idx])
255        except:
256            # If addr_idx is one
257            rx_bytes_from_addr = np.sum(rx_good_data_mgmt['length'])
258
259        # Add the information about the address to the dictionary
260        rx_counts[addr] = (rx_pkts_from_addr, rx_bytes_from_addr)
261
262    # Print the results
263    if (len(rx_counts) > 0):
264        print("\nExample 3: Rx Counts (including duplicates):")
265        print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format(
266            "Dest Addr",
267            "# Pkts",
268            "# Bytes",
269            "MAC Addr Type"))
270   
271        for k in sorted(rx_counts.keys()):
272            # Use the string version of the MAC address as the key for readability
273            print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format(
274                wlan_exp_util.mac_addr_to_str(k),
275                rx_counts[k][0],
276                rx_counts[k][1],
277                wlan_exp_util.mac_addr_desc(k)))
278    else:
279        print("\nExample 3: Rx Counts (including duplicates):")
280        print("\nNo Data or Management frames recevied with good FCS.")
281
282
283print('')
284
285# Uncomment this line to open an interactive console after the script runs
286#   This console will have access to all variables defined above
287# wlan_exp_util.debug_here()
Note: See TracBrowser for help on using the repository browser.