def deserialize(self, buf): super(BSSInfo, self).deserialize(buf) if (False): msg = "BSS Info Data buffer:\n" msg += util.buffer_to_str(buf) print(msg) # Clean up the values # - Remove extra characters in the SSID # - Convert the BSS ID to a colon delimited string for storage # # A BSSID is a 48-bit integer and can be treated like a MAC # address in the wlan_exp framework (ie all the MAC address # utility functions can be used on it.) # import ctypes self['ssid'] = ctypes.c_char_p(self['ssid']).value # If the SSID is not a string already (which happens in Python3) # then decode the bytes class assuming a UTF-8 encoding if type(self['ssid']) is not str: self['ssid'] = self['ssid'].decode('utf-8') self['bssid'] = util.byte_str_to_mac_addr(self['bssid']) self['bssid'] = util.mac_addr_to_str(self['bssid'])
def __str__(self): """Pretty print WlanExpNodeAp object""" msg = "" if self.serial_number is not None: from wlan_exp.util import mac_addr_to_str msg += "AP Node:\n" msg += " WLAN MAC addr : {0}\n".format(mac_addr_to_str(self.wlan_mac_address)) msg += " Node ID : {0}\n".format(self.node_id) msg += " Serial # : {0}\n".format(self.sn_str) msg += " HW version : WARP v{0}\n".format(self.hw_ver) try: import wlan_exp.defaults as defaults cpu_low_type = defaults.WLAN_EXP_LOW_TYPES[(self.node_type & defaults.WLAN_EXP_LOW_MASK)] msg += " CPU Low Type : {0}\n".format(cpu_low_type) except: pass else: msg += "Node not initialized." if self.transport is not None: msg += "wlan_exp " msg += str(self.transport) return msg
def __str__(self): """Pretty print WlanExpNodeSta object""" msg = "" if self.serial_number is not None: from wlan_exp.util import mac_addr_to_str msg += "STA Node:\n" msg += " WLAN MAC addr : {0}\n".format( mac_addr_to_str(self.wlan_mac_address)) msg += " Node ID : {0}\n".format(self.node_id) msg += " Serial # : {0}\n".format(self.sn_str) msg += " HW version : WARP v{0}\n".format(self.hw_ver) try: import wlan_exp.defaults as defaults cpu_low_type = defaults.WLAN_EXP_LOW_TYPES[( self.node_type & defaults.WLAN_EXP_LOW_MASK)] msg += " CPU Low Type : {0}\n".format(cpu_low_type) except: pass else: msg += "Node not initialized." if self.transport is not None: msg += "wlan_exp " msg += str(self.transport) return msg
def print_counts(node, counts, station_info=None): """Helper method to print the counts.""" print( "-------------------- ----------------------------------- ----------------------------------- " ) print( " Tx/Rx Counts from Node {0}". format(node.sn_str)) print( " Number of Packets Number of Bytes " ) print( "ID Tx Data Tx Mgmt Rx Data Rx Mgmt Tx Data Tx Mgmt Rx Data Rx Mgmt " ) print( "-------------------- -------- -------- -------- -------- -------- -------- -------- -------- " ) msg = "" for count in counts: count_id = util.mac_addr_to_str(count['mac_addr']) if not station_info is None: for station in station_info: if (count['mac_addr'] == station['mac_addr']): count_id = station['host_name'] try: count_id = count_id.strip('\x00') except: pass if ((count_id == '') or (count_id == b'')): count_id = util.mac_addr_to_str(count['mac_addr']) msg += "{0:<20} ".format(count_id) msg += "{0:8d} ".format(count['data_num_tx_packets_success']) msg += "{0:8d} ".format(count['mgmt_num_tx_packets_success']) msg += "{0:8d} ".format(count['data_num_rx_packets']) msg += "{0:8d} ".format(count['mgmt_num_rx_packets']) msg += "{0:8d} ".format(count['data_num_tx_bytes_success']) msg += "{0:8d} ".format(count['mgmt_num_tx_bytes_success']) msg += "{0:8d} ".format(count['data_num_rx_bytes']) msg += "{0:8d} ".format(count['mgmt_num_rx_bytes']) msg += "\n" print(msg)
def __repr__(self): """Return device description""" msg = "" if self.wlan_mac_address is not None: from wlan_exp.util import mac_addr_to_str msg += "WLAN Device '{0}'".format(mac_addr_to_str(self.wlan_mac_address)) if self.name is not None: msg += " ({0})".format(self.name) else: msg += "Node not initialized." return msg
def __str__(self): """Pretty print WlanExpNodeSta object""" msg = "" if self.serial_number is not None: from wlan_exp.util import mac_addr_to_str msg += "WLAN EXP STA Node:\n" msg += " WLAN MAC addr : {0}\n".format(mac_addr_to_str(self.wlan_mac_address)) msg += " Node ID : {0}\n".format(self.node_id) msg += " Serial # : {0}\n".format(self.sn_str) msg += " HW version : WARP v{0}\n".format(self.hw_ver) else: msg += "Node not initialized." if self.transport is not None: msg += "WLAN EXP " msg += str(self.transport) return msg
def __init__(self, bssid=None, ssid=None, channel=None, ibss_status=None, beacon_interval=None): super(BSSInfo, self).__init__(field_name='BSS_INFO') # Only initialize the BSSInfo() if one of the fields is provided. init_fields = False if ((bssid is not None) or (ssid is not None) or (channel is not None) or (ibss_status is not None) or (beacon_interval is not None)): init_fields = True # Default values used if initializing fields but value not provided: # bssid - No default value - Error # ssid - "" # channel - No default value - Error # ibss_status - False # beacon_interval - 100 # # This is done so there is no issue during serialization when instantiating # a BSSInfo() with initialized fields. # if init_fields: # Set default values for fields not set by this method self['timestamp'] = 0 self['latest_beacon_rx_time'] = 0 self['state'] = self._consts.state.UNAUTHENTICATED self['latest_beacon_rx_power'] = 0 self['flags'] = 0 # Set SSID if ssid is not None: # Check SSID if type(ssid) is not str: raise ValueError("The SSID must be a string.") if len(ssid) > 32: ssid = ssid[:32] print("WARNING: SSID must be 32 characters or less. Truncating to {0}".format(ssid)) try: self['ssid'] = bytes(ssid, "UTF8") except: self['ssid'] = ssid else: self['ssid'] = bytes() # Set Channel if channel is not None: # Check Channel # - Make sure it is a valid channel if channel not in util.wlan_channels: msg = "The channel must be a valid channel number. See util.py wlan_channels." raise ValueError(msg) self['channel'] = channel self['channel_type'] = self._consts.channel_type.BW20 else: raise AttributeError("Channel must be provided when initializing BSSInfo() fields") # Set the beacon interval if beacon_interval is not None: # Check beacon interval if type(beacon_interval) is not int: beacon_interval = int(beacon_interval) print("WARNING: Beacon interval must be an interger number of time units. Rounding to {0}".format(beacon_interval)) if not ((beacon_interval > 0) and (beacon_interval < (2**16 - 1))): msg = "The beacon interval must be in [1, 65534] (ie 16-bit positive integer)." raise ValueError(msg) self['beacon_interval'] = beacon_interval else: self['beacon_interval'] = 100 # Set the BSSID if bssid is not None: if ibss_status is None: ibss_status = False else: # Check IBSS status value provided if type(ibss_status) is not bool: raise ValueError("The ibss_status must be a boolean.") # Set BSSID, capabilities # - If this is an IBSS, then set local bit to '1' and mcast bit to '0' # - Set the appropriate capabilities (The 802.11 reference design only supports short timeslots (ie short = 9us)) if ibss_status: self['bssid'] = util.create_locally_administered_bssid(bssid) self['capabilities'] = (self._consts.capabilities.IBSS | self._consts.capabilities.SHORT_TIMESLOT) else: self['bssid'] = bssid self['capabilities'] = (self._consts.capabilities.ESS | self._consts.capabilities.SHORT_TIMESLOT) # Convert BSSID to colon delimited string for internal storage if type(bssid) in [int, long]: self['bssid'] = util.mac_addr_to_str(self['bssid']) else: raise AttributeError("BSSID must be provided when initializing BSSInfo() fields")
('length', np.mean, 'avg_len'), ('length', sum, 'tot_len'), ('time_to_done', np.mean, 'avg_time')) # Calculate the aggregate statistics tx_stats = mlab.rec_groupby(tx_recs, group_fields, stat_calc) # Display the results print('\nTx Statistics for {0}:\n'.format(LOGFILE)) print('{0:^18} | {1:^8} | {2:^10} | {3:^14} | {4:^11} | {5:^5}'.format( 'Dest Addr', 'Num MPDUs', 'Avg Length', 'Total Tx Bytes', 'Avg Tx Time', 'Avg Num Tx')) for ii in range(len(tx_stats)): print('{0:<18} | {1:8d} | {2:10.1f} | {3:14} | {4:11.3f} | {5:5.1f}'.format( wlan_exp_util.mac_addr_to_str(tx_stats['addr1'][ii]), tx_stats['num_pkts'][ii], tx_stats['avg_len'][ii], tx_stats['tot_len'][ii], tx_stats['avg_time'][ii], tx_stats['avg_num_tx'][ii])) print('') log_util.debug_here()
# Unpack the log into numpy structured arrays # log_data_to_np_arrays returns a dictionary with one key-value pair per # entry type included in the log_index argument. The log_index keys are reused # as the output dictionary keys. Each output dictionary value is a numpy record array # Refer to wlan_exp_log.log_entries.py for the definition of each record array datatype log_np = log_util.log_data_to_np_arrays(log_data, log_index) ############################################################################### # Example 0: Print node info / Time info log_node_info = log_np['NODE_INFO'][0] print("Node Info:") print(" Node Type : {0}".format( wlan_exp_util.node_type_to_str(log_node_info['node_type']))) print(" MAC Address : {0}".format( wlan_exp_util.mac_addr_to_str(log_node_info['wlan_mac_addr']))) print(" Serial Number: {0}".format( wlan_exp_util.sn_to_str(log_node_info['platform_id'], log_node_info['serial_num']))) print(" WLAN Exp Ver : {0}".format( wlan_exp_util.ver_code_to_str(log_node_info['version']))) print("") if (len(log_np['TIME_INFO']) > 0): log_time_info = log_np['TIME_INFO'][0] print("Experiment Started at: {0}".format( time.ctime(float(log_time_info['host_timestamp'] / 1E6)))) print("") ###############################################################################
log_np = log_util.log_data_to_np_arrays(log_data, log_index) exp_info = log_np['EXP_INFO'] for info in exp_info: print("Timestamp = {0}".format(info['timestamp'])) print("Info Type = {0}".format(info['info_type'])) print("Length = {0}".format(info['length'])) ############################################################################### # Example 0: Print node info / Time info log_node_info = log_np['NODE_INFO'][0] print("Node Info:") print(" Node Type : {0}".format(wlan_exp_util.node_type_to_str(log_node_info['node_type']))) print(" MAC Address : {0}".format(wlan_exp_util.mac_addr_to_str(log_node_info['wlan_mac_addr']))) print(" Serial Number: {0}".format(wlan_exp_util.sn_to_str(log_node_info['hw_generation'], log_node_info['serial_num']))) print(" WLAN Exp Ver : {0}".format(wlan_exp_util.ver_code_to_str(log_node_info['wlan_exp_ver']))) print("") if(len(log_np['TIME_INFO']) > 0): log_time_info = log_np['TIME_INFO'][0] print("Experiment Started at: {0}".format(time.ctime(float(log_time_info['abs_time'] / 1E6)))) print("") ################################################################################################# # Example 3: Calculate total number of packets and bytes received from each distinct MAC address # Here distinction between data, management and control packets could be carried out. # Skip this example if the log doesn't contain RX events
def configure_bss(self, bssid=False, ssid=None, channel=None, beacon_interval=False, ht_capable=None): """Configure the BSS information of the node Each node is either a member of no BSS (colloquially "unassociated") or a member of one BSS. A node requires a minimum valid set of BSS information to be a member of a BSS. The minimum valid set of BSS information for an STA is: #. BSSID: 48-bit MAC address #. Channel: Logical channel for Tx/Rx by BSS members #. SSID: Variable length string (ie the name of the network) If a node is not a member of a BSS (i.e. ``n.get_bss_info()`` returns ``None``), then the node requires all parameters of a minimum valid set of BSS information be specified (i.e. BSSID, Channel, and SSID). See https://warpproject.org/trac/wiki/802.11/wlan_exp/bss for more documentation on BSS information / configuration. Args: bssid (int, str): 48-bit ID of the BSS either as a integer or colon delimited string of the form ``'01:23:45:67:89:ab'`` ssid (str): SSID string (Must be 32 characters or less) channel (int): Channel number on which the BSS operates beacon_interval (int): Integer number of beacon Time Units in [10, 65534] (http://en.wikipedia.org/wiki/TU_(Time_Unit); a TU is 1024 microseconds); A value of None will disable beacons; A value of False will not update the current beacon interval. ht_capable (bool): Is the PHY mode HTMF (True) or NONHT (False)? """ resp_args = self.send_cmd( cmds.NodeConfigBSS(bssid=bssid, ssid=ssid, channel=channel, beacon_interval=beacon_interval, ht_capable=ht_capable)) # Process response arguments if (resp_args is not False): status = resp_args[0] msg = "ERROR: Invalid response from node:\n" ret_val = True # Check status if (status & cmds.ERROR_CONFIG_BSS_BSSID_INVALID): if type(self.bssid) in [int, long]: import wlan_exp.util as util self.bssid = util.mac_addr_to_str(self.bssid) msg += " BSSID {0} was invalid.\n".format(self.bssid) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BSSID_INSUFFICIENT_ARGUMENTS): msg += " Insufficient arguments to create BSS. Must provide:\n" if (bssid is False): msg += " BSSID\n" if (ssid is None): msg += " SSID\n" if (channel is None): msg += " CHANNEL\n" ret_val = False if (status & cmds.ERROR_CONFIG_BSS_CHANNEL_INVALID): msg += " Channel {0} was invalid.\n".format(self.channel) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BEACON_INTERVAL_INVALID): msg += " Beacon interval {0} was invalid.\n".format( self.beacon_interval) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_HT_CAPABLE_INVALID): msg += " HT capable {0} was invalid.\n".format( self.ht_capable) ret_val = False if not ret_val: print(msg)
tx_counts[addr] = (tx_pkts_to_addr, tx_bytes_to_addr) # Print the results if (tx == 'TX'): print("\nExample 2: Tx Counts (CPU High):") else: print( "\nExample 2: Tx Counts (CPU Low - includes retransmissions):") print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format("Dest Addr", "# Pkts", "# Bytes", "MAC Addr Type")) for k in sorted(tx_counts.keys()): # Use the string version of the MAC address as the key for readability print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format( wlan_exp_util.mac_addr_to_str(k), tx_counts[k][0], tx_counts[k][1], wlan_exp_util.mac_addr_desc(k))) ################################################################################################# # Example 3: Calculate total number of packets and bytes received from each distinct MAC address # Skip this example if the log doesn't contain RX events if ('RX_OFDM' in log_np.keys()): # For this experiment, only look at Good = 0 or Bad = 1 receptions FCS_GOOD = 0 # Extract all receptions log_rx = log_np['RX_OFDM'] # Extract only Rx entries with good checksum (FCS = good) rx_good_fcs = log_rx[log_rx['fcs_result'] == FCS_GOOD]
log_util.print_log_index_summary(log_index, "Filtered Log Index:") # Unpack the log into numpy structured arrays # log_data_to_np_arrays returns a dictionary with one key-value pair per # entry type included in the log_index argument. The log_index keys are reused # as the output dictionary keys. Each output dictionary value is a numpy record array # Refer to wlan_exp_log.log_entries.py for the definition of each record array datatype log_np = log_util.log_data_to_np_arrays(log_data, log_index) ############################################################################### # Example 0: Print node info / Time info log_node_info = log_np['NODE_INFO'][0] print("Node Info:") print(" Node Type : {0}".format(wlan_exp_util.node_type_to_str(log_node_info['node_type']))) print(" MAC Address : {0}".format(wlan_exp_util.mac_addr_to_str(log_node_info['wlan_mac_addr']))) print(" Serial Number: {0}".format(wlan_exp_util.sn_to_str(log_node_info['hw_generation'], log_node_info['serial_num']))) print(" WLAN Exp Ver : {0}".format(wlan_exp_util.ver_code_to_str(log_node_info['wlan_exp_ver']))) print("") if(len(log_np['TIME_INFO']) > 0): log_time_info = log_np['TIME_INFO'][0] print("Experiment Started at: {0}".format(time.ctime(float(log_time_info['abs_time'] / 1E6)))) print("") ############################################################################### # Example 1: Count the number of receptions per PHY rate # NOTE: Since there are only loops, this example can deal with RX_OFDM being an # empty list and does not need a try / except. #
# Find the source address for which we have the most receptions #Extract unique values for address 2 (transmitting address in received MAC headers) uniq_addrs = np.unique(log_rx_ofdm['addr2']) #Count the number of receptions per source address num_rx = list() for ii, ua in enumerate(uniq_addrs): num_rx.append(np.sum(log_rx_ofdm['addr2'] == ua)) #Find the source address responsible for the most receptions most_rx = max(num_rx) most_common_addr = uniq_addrs[num_rx.index(most_rx)] print("Found {0} receptions from {1}".format( most_rx, wlan_exp_util.mac_addr_to_str(most_common_addr))) #Create new numpy array of all receptions from most-common source arr_rx_one_src = np.empty(most_rx, dtype=log_rx_ofdm.dtype) arr_rx_one_src[:] = log_rx_ofdm[(log_rx_ofdm['addr2'] == most_common_addr)] #Create some strings to use as attributes in the HDF5 file # attributes are only for convenience - they aren't required for writing or reading HDF5 files root_desc = 'Source Log file: {0}\n'.format(LOGFILE) root_desc += 'HDF5 file written at {0}\n'.format(datetime.datetime.now()) ds_desc = 'All Rx OFDM entries from addr {0}\n'.format( wlan_exp_util.mac_addr_to_str(most_common_addr)) #Construct dictionaries to feed the HDF5 exporter # The dict key names are used as HDF5 dataset names
def configure_bss(self, bssid=False, ssid=None, channel=None, beacon_interval=False, dtim_period=None, ht_capable=None): """Configure the BSS information of the node Each node is either a member of no BSS (colloquially "unassociated") or a member of one BSS. A node requires a minimum valid set of BSS information to be a member of a BSS. The minimum valid set of BSS information for an AP is: #. BSSID: 48-bit MAC address #. Channel: Logical channel for Tx/Rx by BSS members #. SSID: Variable length string (ie the name of the network) #. Beacon Interval: Interval (in TUs) for beacons If a node is not a member of a BSS (i.e. ``n.get_network_info()`` returns ``None``), then the node requires all parameters of a minimum valid set of BSS information be specified (i.e. Channel, SSID, and Beacon Interval). For an AP, if BSSID is not specified, then it is assumed to be the wlan_mac_address of the node. See https://warpproject.org/trac/wiki/802.11/wlan_exp/bss for more documentation on BSS information / configuration. Args: bssid (int, str): 48-bit ID of the BSS either None or the wlan_mac_address of the node. If not specified, it is by default the wlan_mac_address of the node. ssid (str): SSID string (Must be 32 characters or less) channel (int): Channel number on which the BSS operates beacon_interval (int): Integer number of beacon Time Units in [10, 65534] (http://en.wikipedia.org/wiki/TU_(Time_Unit); a TU is 1024 microseconds); A value of None will disable beacons; A value of False will not update the current beacon interval. dtim_period (int): Integer number of beacon intervals between DTIMs ht_capable (bool): Is the PHY mode HTMF (True) or NONHT (False)? """ if bssid is not None: if bssid is not False: # User supplied a not-None BSSID argument error = False if type(bssid) in [int, long]: if (bssid != self.wlan_mac_address): error = True elif type(bssid) is str: import wlan_exp.util as util try: if (util.str_to_mac_addr(bssid) != self.wlan_mac_address): error = True except: error = True if (error): raise AttributeError("BSSID must be either None or the wlan_mac_address of the node.") else: # User did not provide a BSSID argument - use the AP's MAC address bssid = self.wlan_mac_address resp_args = self.send_cmd(cmds.NodeConfigBSS(bssid=bssid, ssid=ssid, channel=channel, beacon_interval=beacon_interval, dtim_period=dtim_period, ht_capable=ht_capable)) # Process response arguments if (resp_args is not False): status = resp_args[0] msg = "ERROR:\n" ret_val = True # Check status if (status & cmds.ERROR_CONFIG_BSS_BSSID_INVALID): if type(self.bssid) in [int, long]: import wlan_exp.util as util self.bssid = util.mac_addr_to_str(self.bssid) msg += " BSSID {0} was invalid.\n".format(self.bssid) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BSSID_INSUFFICIENT_ARGUMENTS): msg += " Insufficient arguments to create BSS. Must provide:\n" if (bssid is False): msg += " BSSID\n" if (ssid is None): msg += " SSID\n" if (channel is None): msg += " CHANNEL\n" if (beacon_interval is False): msg += " BEACON_INTERVAL\n" ret_val = False if (status & cmds.ERROR_CONFIG_BSS_CHANNEL_INVALID): msg += " Channel {0} was invalid.\n".format(channel) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BEACON_INTERVAL_INVALID): msg += " Beacon interval {0} was invalid.\n".format(beacon_interval) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_HT_CAPABLE_INVALID): msg += " HT capable {0} was invalid.\n".format(ht_capable) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_DTIM_PERIOD_INVALID): msg += " DTIM period {0} was invalid.\n".format(dtim_period) ret_val = False if not ret_val: print(msg)
def __init__(self, bssid=False, ssid=None, channel=None, beacon_interval=False, ht_capable=None): super(BSSConfig, self).__init__(field_name='BSS_CONFIG') # Default values used if value not provided: # bssid - 00:00:00:00:00:00 # ssid - "" # channel - 0 # beacon_interval - 0xFFFF # ht_capable - 0xFF # Initialize update mask self['update_mask'] = 0 # Set the BSSID field if bssid is not False: if bssid is not None: self['bssid'] = bssid # Convert BSSID to colon delimited string for internal storage if type(bssid) in [int, long]: self['bssid'] = util.mac_addr_to_str(self['bssid']) else: self['bssid'] = "00:00:00:00:00:00" # Set update mask self['update_mask'] |= self._consts.update_mask.BSSID else: # Remove current BSS on the node self['bssid'] = "00:00:00:00:00:00" # Set SSID field if ssid is not None: # Check SSID if type(ssid) is not str: raise ValueError("The SSID type was {0}".format(type(ssid))) if len(ssid) > 32: ssid = ssid[:32] print("WARNING: SSID must be 32 characters or less. Truncating to {0}".format(ssid)) try: self['ssid'] = bytes(ssid, "UTF8") except: self['ssid'] = ssid # Set update mask self['update_mask'] |= self._consts.update_mask.SSID else: self['ssid'] = bytes() # Set Channel field if channel is not None: # Check Channel # - Make sure it is a valid channel; only store channel if channel not in util.wlan_channels: msg = "The channel must be a valid channel number. See util.py wlan_channels." raise ValueError(msg) self['channel'] = channel # Set update mask self['update_mask'] |= self._consts.update_mask.CHANNEL else: self['channel'] = 0 self['channel_type'] = self._consts.channel_type.BW20 # Set the beacon interval field if beacon_interval is not False: if beacon_interval is not None: # Check beacon interval if type(beacon_interval) is not int: beacon_interval = int(beacon_interval) print("WARNING: Beacon interval must be an interger number of time units. Rounding to {0}".format(beacon_interval)) if not ((beacon_interval > 9) and (beacon_interval < (2**16 - 1))): msg = "The beacon interval must be in [10, 65534] (ie 16-bit positive integer)." raise ValueError(msg) self['beacon_interval'] = beacon_interval else: # Disable beacons self['beacon_interval'] = 0 # Set update mask self['update_mask'] |= self._consts.update_mask.BEACON_INTERVAL else: self['beacon_interval'] = 0xFFFF # Set the HT capable field if ht_capable is not None: # Check HT capable if type(ht_capable) is not bool: msg = "ht_capable must be a boolean." raise ValueError(msg) self['ht_capable'] = ht_capable # Set update mask self['update_mask'] |= self._consts.update_mask.HT_CAPABLE else: self['ht_capable'] = 0xFF
# Print the results if (tx == 'TX_HIGH'): print("\nExample 2: Tx Counts (CPU High):"); else: print("\nExample 2: Tx Counts (CPU Low - includes retransmissions):"); print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format( "Dest Addr", "# Pkts", "# Bytes", "MAC Addr Type")) for k in sorted(tx_counts.keys()): # Use the string version of the MAC address as the key for readability print("{0:18}\t{1:>7}\t{2:>10}\t{3}".format( wlan_exp_util.mac_addr_to_str(k), tx_counts[k][0], tx_counts[k][1], wlan_exp_util.mac_addr_desc(k))) ################################################################################################# # Example 3: Calculate total number of packets and bytes received from each distinct MAC address # Skip this example if the log doesn't contain RX events if('RX_OFDM' in log_np.keys()): # Extract all receptions log_rx = log_np['RX_OFDM'] # Get RX_OFDM entry constants RX_CONSTS = log_util.get_entry_constants('RX_OFDM')
# Filter the OFDM Rx Entries # Find the source address for which we have the most receptions #Extract unique values for address 2 (transmitting address in received MAC headers) uniq_addrs = np.unique(log_rx_ofdm['addr2']) #Count the number of receptions per source address num_rx = list() for ii,ua in enumerate(uniq_addrs): num_rx.append(np.sum(log_rx_ofdm['addr2'] == ua)) #Find the source address responsible for the most receptions most_rx = max(num_rx) most_common_addr = uniq_addrs[num_rx.index(most_rx)] print("Found {0} receptions from {1}".format(most_rx, wlan_exp_util.mac_addr_to_str(most_common_addr))) #Create new numpy array of all receptions from most-common source arr_rx_one_src = np.empty(most_rx, dtype=log_rx_ofdm.dtype) arr_rx_one_src[:] = log_rx_ofdm[(log_rx_ofdm['addr2'] == most_common_addr)] #Create some strings to use as attributes in the HDF5 file # attributes are only for convenience - they aren't required for writing or reading HDF5 files root_desc = 'Source Log file: {0}\n'.format(LOGFILE) root_desc += 'HDF5 file written at {0}\n'.format(datetime.datetime.now()) ds_desc = 'All Rx OFDM entries from addr {0}\n'.format(wlan_exp_util.mac_addr_to_str(most_common_addr)) #Construct dictionaries to feed the HDF5 exporter # The dict key names are used as HDF5 dataset names log_dict = {'RX_OFDM': arr_rx_one_src}
def configure_bss(self, bssid=False, ssid=None, channel=None, beacon_interval=False, ht_capable=None): """Configure the BSS information of the node Each node is either a member of no BSS (colloquially "unassociated") or a member of one BSS. A node requires a minimum valid set of BSS information to be a member of a BSS. The minimum valid set of BSS information for an IBSS node is: #. BSSID: 48-bit MAC address #. Channel: Logical channel for Tx/Rx by BSS members #. SSID: Variable length string (ie the name of the network) #. Beacon Interval: Interval (in TUs) for beacons If a node is not a member of a BSS (i.e. ``n.get_bss_info()`` returns ``None``), then the node requires all parameters of a minimum valid set of BSS information be specified (i.e. BSSID, Channel, SSID, and Beacon Interval). For an IBSS node, the BSSID must be locally administered. To create a locally administered BSSID, a utility method is provided in util.py: ``bssid = util.create_locally_administered_bssid(node.wlan_mac_address)`` See https://warpproject.org/trac/wiki/802.11/wlan_exp/bss for more documentation on BSS information / configuration. Args: bssid (int, str): 48-bit ID of the BSS either as a integer or colon delimited string of the form ``'01:23:45:67:89:ab'``. The ``bssid`` must be a valid locally administered BSSID. Use wlan_exp.util.create_locally_administered_bssid() to generate a valid locally administered BSSID based on the node's MAC address. ssid (str): SSID string (Must be 32 characters or less) channel (int): Channel number on which the BSS operates beacon_interval (int): Integer number of beacon Time Units in [10, 65534] (http://en.wikipedia.org/wiki/TU_(Time_Unit); a TU is 1024 microseconds); A value of None will disable beacons; A value of False will not update the current beacon interval. ht_capable (bool): Is the PHY mode HTMF (True) or NONHT (False)? """ import wlan_exp.util as util if bssid is not False: if bssid is not None: if not util.is_locally_administered_bssid(bssid): msg = "IBSS BSSIDs must be 'locally administered'. Use \n" msg += " util.create_locally_administered_bssid() to \n" msg += " create a 'locally adminstered' BSSID." raise AttributeError(msg) resp_args = self.send_cmd(cmds.NodeConfigBSS(bssid=bssid, ssid=ssid, channel=channel, beacon_interval=beacon_interval, ht_capable=ht_capable)) # Process response arguments if (resp_args is not False): status = resp_args[0] msg = "ERROR: Invalid response from node:\n" ret_val = True # Check status if (status & cmds.ERROR_CONFIG_BSS_BSSID_INVALID): if type(self.bssid) in [int, long]: import wlan_exp.util as util self.bssid = util.mac_addr_to_str(self.bssid) msg += " BSSID {0} was invalid.\n".format(self.bssid) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BSSID_INSUFFICIENT_ARGUMENTS): msg += " Insufficient arguments to create BSS. Must provide:\n" if (bssid is False): msg += " BSSID\n" if (ssid is None): msg += " SSID\n" if (channel is None): msg += " CHANNEL\n" if (beacon_interval is False): msg += " BEACON_INTERVAL\n" ret_val = False if (status & cmds.ERROR_CONFIG_BSS_CHANNEL_INVALID): msg += " Channel {0} was invalid.\n".format(self.channel) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BEACON_INTERVAL_INVALID): msg += " Beacon interval {0} was invalid.\n".format(self.beacon_interval) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_HT_CAPABLE_INVALID): msg += " HT capable {0} was invalid.\n".format(self.ht_capable) ret_val = False if not ret_val: print(msg)
def configure_bss(self, bssid=False, ssid=None, channel=None, beacon_interval=False, ht_capable=None): """Configure the BSS information of the node Each node is either a member of no BSS (colloquially "unassociated") or a member of one BSS. A node requires a minimum valid set of BSS information to be a member of a BSS. The minimum valid set of BSS information for an AP is: #. BSSID: 48-bit MAC address #. Channel: Logical channel for Tx/Rx by BSS members #. SSID: Variable length string (ie the name of the network) #. Beacon Interval: Interval (in TUs) for beacons If a node is not a member of a BSS (i.e. ``n.get_bss_info()`` returns ``None``), then the node requires all parameters of a minimum valid set of BSS information be specified (i.e. Channel, SSID, and Beacon Interval). For an AP, if BSSID is not specified, then it is assumed to be the wlan_mac_address of the node. See https://warpproject.org/trac/wiki/802.11/wlan_exp/bss for more documentation on BSS information / configuration. Args: bssid (int, str): 48-bit ID of the BSS either None or the wlan_mac_address of the node. If not specified, it is by default the wlan_mac_address of the node. ssid (str): SSID string (Must be 32 characters or less) channel (int): Channel number on which the BSS operates beacon_interval (int): Integer number of beacon Time Units in [10, 65534] (http://en.wikipedia.org/wiki/TU_(Time_Unit); a TU is 1024 microseconds); A value of None will disable beacons; A value of False will not update the current beacon interval. ht_capable (bool): Is the PHY mode HTMF (True) or NONHT (False)? """ if bssid is not None: if bssid is not False: # User supplied a not-None BSSID argument error = False if type(bssid) in [int, long]: if (bssid != self.wlan_mac_address): error = True elif type(bssid) is str: import wlan_exp.util as util try: if (util.str_to_mac_addr(bssid) != self.wlan_mac_address): error = True except: error = True if (error): raise AttributeError("BSSID must be either None or the wlan_mac_address of the node.") else: # User did not provide a BSSID argument - use the AP's MAC address bssid = self.wlan_mac_address resp_args = self.send_cmd(cmds.NodeConfigBSS(bssid=bssid, ssid=ssid, channel=channel, beacon_interval=beacon_interval, ht_capable=ht_capable)) # Process response arguments if (resp_args is not False): status = resp_args[0] msg = "ERROR: Invalid response from node:\n" ret_val = True # Check status if (status & cmds.ERROR_CONFIG_BSS_BSSID_INVALID): if type(self.bssid) in [int, long]: import wlan_exp.util as util self.bssid = util.mac_addr_to_str(self.bssid) msg += " BSSID {0} was invalid.\n".format(self.bssid) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BSSID_INSUFFICIENT_ARGUMENTS): msg += " Insufficient arguments to create BSS. Must provide:\n" if (bssid is False): msg += " BSSID\n" if (ssid is None): msg += " SSID\n" if (channel is None): msg += " CHANNEL\n" if (beacon_interval is False): msg += " BEACON_INTERVAL\n" ret_val = False if (status & cmds.ERROR_CONFIG_BSS_CHANNEL_INVALID): msg += " Channel {0} was invalid.\n".format(self.channel) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_BEACON_INTERVAL_INVALID): msg += " Beacon interval {0} was invalid.\n".format(self.beacon_interval) ret_val = False if (status & cmds.ERROR_CONFIG_BSS_HT_CAPABLE_INVALID): msg += " HT capable {0} was invalid.\n".format(self.ht_capable) ret_val = False if not ret_val: print(msg)