[6320] | 1 | # -*- coding: utf-8 -*- |
---|
| 2 | """ |
---|
| 3 | ------------------------------------------------------------------------------ |
---|
| 4 | Mango 802.11 Reference Design Experiments Framework - Ad hoc (IBSS) Node |
---|
| 5 | ------------------------------------------------------------------------------ |
---|
| 6 | License: Copyright 2019 Mango Communications, Inc. All rights reserved. |
---|
| 7 | Use and distribution subject to terms in LICENSE.txt |
---|
| 8 | ------------------------------------------------------------------------------ |
---|
| 9 | |
---|
| 10 | """ |
---|
| 11 | |
---|
| 12 | import wlan_exp.node as node |
---|
| 13 | import wlan_exp.cmds as cmds |
---|
| 14 | |
---|
| 15 | |
---|
| 16 | __all__ = ['WlanExpNodeIBSS'] |
---|
| 17 | |
---|
| 18 | |
---|
| 19 | class WlanExpNodeIBSS(node.WlanExpNode): |
---|
| 20 | """wlan_exp Node class for the 802.11 Reference Design IBSS MAC project |
---|
| 21 | |
---|
| 22 | Args: |
---|
| 23 | network_config (transport.NetworkConfiguration) : Network configuration of the node |
---|
| 24 | """ |
---|
| 25 | |
---|
| 26 | #------------------------------------------------------------------------- |
---|
| 27 | # Node Commands |
---|
| 28 | #------------------------------------------------------------------------- |
---|
| 29 | |
---|
| 30 | def get_txrx_counts(self, device_list=None): |
---|
| 31 | """Get the counts from the node. |
---|
| 32 | |
---|
| 33 | .. note:: This function has the same implementation as WlanExpNode but |
---|
| 34 | different default values. |
---|
| 35 | |
---|
| 36 | Args: |
---|
| 37 | device_list (list of WlanExpNode, WlanExpNode, WlanDevice, optional): List of devices |
---|
| 38 | for which to get counts. See note below for more information. |
---|
| 39 | return_zeroed_counts_if_none(bool, optional): If no counts exist on the node for |
---|
| 40 | the specified device(s), return a zeroed counts dictionary with proper timestamps |
---|
| 41 | instead of None. |
---|
| 42 | |
---|
| 43 | Returns: |
---|
| 44 | counts_dictionary (list of dictionaries, dictionary): Counts for the device(s) specified. |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | The dictionaries returned by this method have the following fields: |
---|
| 48 | |
---|
| 49 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 50 | | Field | Description | |
---|
| 51 | +=============================+=====================================================================================================+ |
---|
| 52 | | retrieval_timestamp | Value of System Time in microseconds when structure retrieved from the node | |
---|
| 53 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 54 | | mac_addr | MAC address of remote node whose statics are recorded here | |
---|
| 55 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 56 | | associated | Boolean indicating whether remote node is currently associated with this node | |
---|
| 57 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 58 | | data_num_rx_bytes | Total number of bytes received in DATA packets from remote node | |
---|
| 59 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 60 | | data_num_tx_bytes_success | Total number of bytes successfully transmitted in DATA packets to remote node | |
---|
| 61 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 62 | | data_num_tx_bytes_total | Total number of bytes transmitted (successfully or not) in DATA packets to remote node | |
---|
| 63 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 64 | | data_num_rx_packets | Total number of DATA packets received from remote node | |
---|
| 65 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 66 | | data_num_tx_packets_success | Total number of DATA packets successfully transmitted to remote node | |
---|
| 67 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 68 | | data_num_tx_packets_total | Total number of DATA packets transmitted (successfully or not) to remote node | |
---|
| 69 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 70 | | data_num_tx_attempts | Total number of low-level attempts of DATA packets to remote node (includes re-transmissions) | |
---|
| 71 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 72 | | mgmt_num_rx_bytes | Total number of bytes received in management packets from remote node | |
---|
| 73 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 74 | | mgmt_num_tx_bytes_success | Total number of bytes successfully transmitted in management packets to remote node | |
---|
| 75 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 76 | | mgmt_num_tx_bytes_total | Total number of bytes transmitted (successfully or not) in management packets to remote node | |
---|
| 77 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 78 | | mgmt_num_rx_packets | Total number of management packets received from remote node | |
---|
| 79 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 80 | | mgmt_num_tx_packets_success | Total number of management packets successfully transmitted to remote node | |
---|
| 81 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 82 | | mgmt_num_tx_packets_total | Total number of management packets transmitted (successfully or not) to remote node | |
---|
| 83 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 84 | | mgmt_num_tx_attempts | Total number of low-level attempts of management packets to remote node (includes re-transmissions)| |
---|
| 85 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 86 | | latest_txrx_timestamp | System Time value of last transmission / reception | |
---|
| 87 | +-----------------------------+-----------------------------------------------------------------------------------------------------+ |
---|
| 88 | |
---|
| 89 | |
---|
| 90 | If the device_list is a single device, then a single dictionary or |
---|
| 91 | None is returned. If the device_list is a list of devices, then a |
---|
| 92 | list of dictionaries will be returned in the same order as the devices |
---|
| 93 | in the list. If any of the staistics are not there, None will be |
---|
| 94 | inserted in the list. If the device_list is not specified, then all |
---|
| 95 | the counts on the node will be returned. |
---|
| 96 | """ |
---|
| 97 | return super(WlanExpNodeIBSS, self).get_txrx_counts(device_list) |
---|
| 98 | |
---|
| 99 | |
---|
| 100 | def configure_bss(self, bssid=False, ssid=None, channel=None, beacon_interval=False, ht_capable=None): |
---|
| 101 | """Configure the BSS information of the node |
---|
| 102 | |
---|
| 103 | Each node is either a member of no BSS (colloquially "unassociated") |
---|
| 104 | or a member of one BSS. A node requires a minimum valid set of BSS |
---|
| 105 | information to be a member of a BSS. The minimum valid set of BSS |
---|
| 106 | information for an IBSS node is: |
---|
| 107 | |
---|
| 108 | #. BSSID: 48-bit MAC address |
---|
| 109 | #. Channel: Logical channel for Tx/Rx by BSS members |
---|
| 110 | #. SSID: Variable length string (ie the name of the network) |
---|
| 111 | #. Beacon Interval: Interval (in TUs) for beacons |
---|
| 112 | |
---|
| 113 | If a node is not a member of a BSS (i.e. ``n.get_network_info()`` returns |
---|
| 114 | ``None``), then the node requires all parameters of a minimum valid |
---|
| 115 | set of BSS information be specified (i.e. BSSID, Channel, SSID, and |
---|
| 116 | Beacon Interval). |
---|
| 117 | |
---|
| 118 | For an IBSS node, the BSSID must be locally administered. To create a |
---|
| 119 | locally administered BSSID, a utility method is provided in util.py: |
---|
| 120 | |
---|
| 121 | ``bssid = util.create_locally_administered_bssid(node.wlan_mac_address)`` |
---|
| 122 | |
---|
| 123 | See https://warpproject.org/trac/wiki/802.11/wlan_exp/bss |
---|
| 124 | for more documentation on BSS information / configuration. |
---|
| 125 | |
---|
| 126 | |
---|
| 127 | Args: |
---|
| 128 | bssid (int, str): 48-bit ID of the BSS either as a integer or |
---|
| 129 | colon delimited string of the form ``'01:23:45:67:89:ab'``. The |
---|
| 130 | ``bssid`` must be a valid locally administered BSSID. Use |
---|
| 131 | wlan_exp.util.create_locally_administered_bssid() to generate a valid |
---|
| 132 | locally administered BSSID based on the node's MAC address. |
---|
| 133 | ssid (str): SSID string (Must be 32 characters or less) |
---|
| 134 | channel (int): Channel number on which the BSS operates |
---|
| 135 | beacon_interval (int): Integer number of beacon Time Units in [10, 65534] |
---|
| 136 | (http://en.wikipedia.org/wiki/TU_(Time_Unit); a TU is 1024 microseconds); |
---|
| 137 | A value of None will disable beacons; A value of False will not |
---|
| 138 | update the current beacon interval. |
---|
| 139 | ht_capable (bool): Is the PHY mode HTMF (True) or NONHT (False)? |
---|
| 140 | """ |
---|
| 141 | import wlan_exp.util as util |
---|
| 142 | |
---|
| 143 | if (self.is_scanning() is True) and (bssid is None): |
---|
| 144 | print('Warning: network scan is still running when BSS was set to None. Use stop_active_scan if needed.') |
---|
| 145 | |
---|
| 146 | if bssid is not False: |
---|
| 147 | if bssid is not None: |
---|
| 148 | # Remeber the bssid argument, used in error checking below |
---|
| 149 | self.bssid = bssid |
---|
| 150 | if not util.is_locally_administered_bssid(bssid): |
---|
| 151 | msg = "IBSS BSSIDs must be 'locally administered'. Use \n" |
---|
| 152 | msg += " util.create_locally_administered_bssid() to \n" |
---|
| 153 | msg += " create a 'locally adminstered' BSSID." |
---|
| 154 | raise AttributeError(msg) |
---|
| 155 | |
---|
| 156 | resp_args = self.send_cmd(cmds.NodeConfigBSS(bssid=bssid, ssid=ssid, channel=channel, |
---|
| 157 | beacon_interval=beacon_interval, ht_capable=ht_capable)) |
---|
| 158 | |
---|
| 159 | # Process response arguments |
---|
| 160 | if (resp_args is not False): |
---|
| 161 | status = resp_args[0] |
---|
| 162 | msg = "ERROR:\n" |
---|
| 163 | ret_val = True |
---|
| 164 | |
---|
| 165 | # Check status |
---|
| 166 | if (status & cmds.ERROR_CONFIG_BSS_BSSID_INVALID): |
---|
| 167 | if type(self.bssid) in [int, long]: |
---|
| 168 | import wlan_exp.util as util |
---|
| 169 | self.bssid = util.mac_addr_to_str(self.bssid) |
---|
| 170 | msg += " BSSID {0} was invalid.\n".format(self.bssid) |
---|
| 171 | ret_val = False |
---|
| 172 | |
---|
| 173 | if (status & cmds.ERROR_CONFIG_BSS_BSSID_INSUFFICIENT_ARGUMENTS): |
---|
| 174 | msg += " Insufficient arguments to create BSS. Must provide:\n" |
---|
| 175 | if (bssid is False): |
---|
| 176 | msg += " BSSID\n" |
---|
| 177 | if (ssid is None): |
---|
| 178 | msg += " SSID\n" |
---|
| 179 | if (channel is None): |
---|
| 180 | msg += " CHANNEL\n" |
---|
| 181 | if (beacon_interval is False): |
---|
| 182 | msg += " BEACON_INTERVAL\n" |
---|
| 183 | ret_val = False |
---|
| 184 | |
---|
| 185 | if (status & cmds.ERROR_CONFIG_BSS_CHANNEL_INVALID): |
---|
| 186 | msg += " Channel {0} was invalid.\n".format(channel) |
---|
| 187 | ret_val = False |
---|
| 188 | |
---|
| 189 | if (status & cmds.ERROR_CONFIG_BSS_BEACON_INTERVAL_INVALID): |
---|
| 190 | msg += " Beacon interval {0} was invalid.\n".format(beacon_interval) |
---|
| 191 | ret_val = False |
---|
| 192 | |
---|
| 193 | if (status & cmds.ERROR_CONFIG_BSS_HT_CAPABLE_INVALID): |
---|
| 194 | msg += " HT capable {0} was invalid.\n".format(ht_capable) |
---|
| 195 | ret_val = False |
---|
| 196 | |
---|
| 197 | if not ret_val: |
---|
| 198 | print(msg) |
---|
| 199 | |
---|
| 200 | |
---|
| 201 | #------------------------------------------------------------------------- |
---|
| 202 | # Internal Node methods |
---|
| 203 | #------------------------------------------------------------------------- |
---|
| 204 | def _check_allowed_rate(self, mcs, phy_mode, verbose=False): |
---|
| 205 | """Check that rate parameters are allowed |
---|
| 206 | |
---|
| 207 | Args: |
---|
| 208 | mcs (int): Modulation and coding scheme (MCS) index |
---|
| 209 | phy_mode (str, int): PHY mode (from util.phy_modes) |
---|
| 210 | |
---|
| 211 | Returns: |
---|
| 212 | valid (bool): Are all parameters valid? |
---|
| 213 | """ |
---|
| 214 | # TODO: implement IBSS-specific rate checking here |
---|
| 215 | # Allow all supported rates for now |
---|
| 216 | |
---|
| 217 | return self._check_supported_rate(mcs, phy_mode, verbose) |
---|
| 218 | |
---|
| 219 | |
---|
| 220 | # End class |
---|