def main(): log.info('Starting testing excpetions') log.info('%s' % str(dir())) try: raise exceptions.AgentNotAvailable(id='123') except exceptions.UniFlexException as we: print(we) try: raise exceptions.InvalidArgumentException(func_name='radio.get_noise') except exceptions.UniFlexException as we: print(we) try: raise exceptions.UnsupportedFunctionException( func_name='radio.get_noise', conn_module='wifi_ath9k') except exceptions.UniFlexException as we: print(we) try: raise exceptions.SchedulingFunctionCallsInThePastException( func_name='radio.get_noise') except exceptions.UniFlexException as we: print(we) try: raise exceptions.FunctionExecutionFailedException( func_name='radio.get_noise', err_msg='wrong iw version') except exceptions.UniFlexException as we: print(we)
def set_modulation_rate(self, ifaceName, is5Ghzband, isLegacy, rate_Mbps_or_ht_mcs): ''' Sets a fix PHY modulation rate: - legacy: bitrate - 11n/ac: ht_mcs ''' try: if isLegacy: arg = 'legacy' else: arg = 'ht-mcs' if is5Ghzband: arg = arg + '-5' else: arg = arg + '-2.4' arg = arg + ' ' + rate_Mbps_or_ht_mcs [rcode, sout, serr] = self.run_command('iw dev ' + ifaceName + ' set bitrates ' + arg) except Exception as e: self.log.fatal("Failed to set bitrate: %s" % str(e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg=str(e))
def configure_radio_sensitivity(self, ani_mode): """ Configuring the carrier receiving sensitivity of the radio. Req.: modprobe ath5k/9k debug=0xffffffff Supported ani modes: - 0 - disable ANI - tbd :param ani_mode: The ANI mode, 0=disable, other=tbd :return: True if successful """ self.log.info('Setting ANI sensitivity w/ = %s' % str(ani_mode)) try: myfile = open( '/sys/kernel/debug/ieee80211/' + self.phyName + '/' + self.prefix + '/ani', 'w') myfile.write(ani_mode) myfile.close() except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e)) return True
def get_iface_hw_addr(self, iface): """Return the MAC address of a particular network interface """ try: self.log.info('get_iface_hw_addr() called {}'.format(iface)) retVal = ni.ifaddresses(iface)[ni.AF_LINK][0]['addr'] return retVal except Exception as e: self.log.fatal( "Failed to get HW address for {}, err_msg: {}".format( iface, str(e))) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to get HW addr: ' + str(e))
def connect_to_network(self, iface, ssid): self.log.info('Connecting via to AP with SSID: %s->%s' % (str(iface), str(ssid))) cmd_str = 'sudo iwconfig ' + iface + ' essid ' + str(ssid) try: [rcode, sout, serr] = self.run_command(cmd_str) except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e)) return True
def set_ARP_entry(self, iface, mac_addr, ip_addr): """ Adds an entry to the local ARP cache. TODO: use Netlink API """ try: [rcode, sout, serr] = self.run_command('sudo arp -s ' + ip_addr + ' -i ' + iface + ' ' + mac_addr) return sout except Exception as e: self.log.fatal("Failed to set ARP entry for iface:%s, err_msg:%s" % str(e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to set ARP entry: ' + str(e))
def get_iface_ip_addr(self, iface): """Interfaces may have multiple IP addresses, return a list with all IP addresses """ try: self.log.info('get_iface_ip_addr() called {}'.format(iface)) ipList = [ inetaddr['addr'] for inetaddr in ni.ifaddresses(iface)[ni.AF_INET] ] return ipList except Exception as e: self.log.fatal("Failed to get IP address for %s, err_msg:%s" % (iface, str(e))) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to get IP addr: ' + str(e))
def deactivate_radio_program(self, hmac_name, do_pause=False): """ Stops running hMAC configuration, i.e. standard CSMA/CA is used afterwards. :param hmac_name: the name of the HMAC to be deactivated; the last loaded in case of None :param do_pause: just pause or terminate :return: True if successful """ self.log.info('Function: deactivate_radio_program') try: if self.active_hmac_conf == None: self.log.warn('No hMAC was activated before; ignoring.') return # set allow all configuration string conf_str = self.active_hmac_conf.createAllowAllConfString() # command string terminate_str = 'TERMINATE' if self.hmac_ctrl_socket is None: context = zmq.Context() self.hmac_ctrl_socket = context.socket(zmq.REQ) self.hmac_ctrl_socket.connect( "tcp://localhost:" + str(self.local_mac_processor_port)) # update MAC processor configuration self.log.info("Send ctrl req message to HMAC: %s" % conf_str) self.hmac_ctrl_socket.send(conf_str.encode('ascii')) message = self.hmac_ctrl_socket.recv() self.log.info("Received ctrl reply from HMAC: %s" % message) # give one second to settle down time.sleep(1) # send termination signal to MAC self.hmac_ctrl_socket.send(terminate_str) message = self.hmac_ctrl_socket.recv() self.log.info("Received ctrl reply from HMAC: %s" % message) self.active_hmac_conf = None return True except zmq.ZMQError as e: self.log.fatal("Failed to uninstall MAC processor %s" % str(e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to uninstall MAC processor: ' + str(e))
def get_info_of_connected_devices(self, ifaceName): ''' Returns information about associated STAs for a node running in AP mode tbd: use Netlink API ''' self.log.info("WIFI Module get info on assoc clients on iface: %s" % str(ifaceName)) try: [rcode, sout, serr] = self.run_command('iw dev ' + ifaceName + ' station dump') # mac_addr -> stat_key -> list of (value, unit) res = {} sout_arr = sout.split("\n") for line in sout_arr: s = line.strip() if s == '': continue if "Station" in s: arr = s.split() mac_addr = arr[1].strip() res[mac_addr] = {} else: arr = s.split(":") key = arr[0].strip() val = arr[1].strip() arr2 = val.split() val2 = arr2[0].strip() if len(arr2) > 1: unit = arr2[1].strip() else: unit = None res[mac_addr][key] = (val2, unit) return res except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def get_entry_of_connected_devices(self, key, iface): try: res = self.get_info_of_connected_devices(iface) rv = {} for mac_addr in res: value = res[mac_addr][key] self.log.info('%s -> %s' % (mac_addr, value)) rv[mac_addr] = value # dict of mac_addr -> value return rv except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def activate_radio_program(self, hmac_name=None, hmac_conf=None, interface=None): """ Installs hMAC configuration and activates hMAC :param hmac_name: name of the HMAC conf; used as ID internally :param hmac_conf: the hMAC configuration :param iface: the name of interface :return: True if successful """ self.log.info('Function: activate_radio_program') try: if interface == None: self.log.warn('Iface is required') return # create configuration string conf_str = hmac_conf.createConfString() processArgs = str(self.exec_file) + " -d 0 " + " -i" +str(interface) \ + " -f" + str(hmac_conf.getSlotDuration()) + " -n" + str(hmac_conf.getNumSlots()) \ + " -c" + conf_str self.log.info('Install hMAC executable w/ = %s' % str(processArgs)) # run as background process subprocess.Popen(processArgs.split(), shell=False) self.active_hmac_conf = hmac_conf self.hmac_ctrl_socket = None return True except Exception as e: self.log.fatal( "Failed to install MAC processor on %s: err_msg: %s" % (interface, e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg= 'Failed to install MAC processor; check HMAC installation.: ' + str(e))
def update_radio_program(self, hmac_name=None, hmac_conf=None, interface=None): """ Updates a running hMAC configuration on-the-fly :param hmac_name: hmac name/ID :param hmac_conf: the hMac configuration :param interface: the name of interface :return: True if successful """ self.log.info('Function: update_radio_program') try: if interface == None: self.log.warn('Iface is required') return # create configuration string conf_str = hmac_conf.createConfString() if self.hmac_ctrl_socket is None: context = zmq.Context() self.hmac_ctrl_socket = context.socket(zmq.REQ) self.hmac_ctrl_socket.connect( "tcp://localhost:" + str(self.local_mac_processor_port)) # update MAC processor configuration self.log.info("Send ctrl req message to HMAC: %s" % conf_str) self.hmac_ctrl_socket.send(conf_str.encode('ascii')) message = self.hmac_ctrl_socket.recv() self.log.info("Received ctrl reply message from HMAC: %s" % message) self.active_hmac_conf = hmac_conf return True except zmq.ZMQError as e: self.log.fatal("Update MAC processor failed: %s" % (e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Update MAC processor failed: ' + str(e))
def play_waveform(self, iface, freq, power_lvl, **kwargs): self.log.debug('playWaveform()') try: # set the center frequency exec_file = 'rs_siggen_etherraw' args = iface + ' \"FREQ ' + freq + 'MHz\"' command = exec_file + ' ' + args self.log.debug('playWaveform on iface %s ... set frequency' % (iface)) self.log.info('exec %s' % command) [rcode, sout, serr] = self._run_command(command) # set power level args = iface + ' \":POW ' + str(power_lvl) + '\"' command = exec_file + ' ' + args self.log.debug( 'playWaveform on iface %s ... set power level to %s' % (iface, str(power_lvl))) self.log.info('exec %s' % command) [rcode, sout, serr] = self._run_command(command) # power on args = iface + ' \"OUTP ON\"' command = exec_file + ' ' + args self.log.debug('playWaveform on iface %s ... power on' % (iface)) self.log.info('exec %s' % command) [rcode, sout, serr] = self._run_command(command) return True except Exception as e: self.log.fatal("Failed to play waveform, err_msg:%s" % (str(e))) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to play waveform: ' + str(e))
def stop_waveform(self, iface, **kwargs): self.log.debug('stopWaveform()') try: exec_file = str(os.path.join( self.getPlatformPath())) + '/rs_siggen_etherraw' # power off args = iface + '\"OUTP OFF\"' command = exec_file + ' ' + args self.log.debug('stopWaveform on iface %s ... power off' % (iface)) self.log.debug('exec %s' % command) [rcode, sout, serr] = self._run_command(command) return True except Exception as e: self.log.fatal("Failed to stop waveform, err_msg:%s" % (str(e))) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to stop waveform: ' + str(e))
def change_routing(self, serving_gw_ip_addr, target_gw_ip_addr, dst_ip_addr): ''' Adds entry to routing table. IPDB has a simple yet useful routing management interface. To add a route, one can use almost any syntax:: pass spec as is r = self.ip.routes.get('192.168.5.0/24') ''' try: ip = IPDB(mode='direct') r = ip.routes.get(dst_ip_addr + '/32') if not r.gateway: self.log.info("Currently no gateway found, creating it...") ip.routes.add(dst=dst_ip_addr + '/32', gateway=target_gw_ip_addr).commit() else: self.log.info("Old gateway = %s for %s" % (r.gateway, dst_ip_addr)) if (r.gateway.startswith(serving_gw_ip_addr) or r.gateway.startswith(target_gw_ip_addr)): r.remove() ip.routes.add(dst=dst_ip_addr + '/32', gateway=target_gw_ip_addr).commit() r = ip.routes.get(dst_ip_addr + '/32') self.log.info("New gateway = %s for %s" % (r.gateway, dst_ip_addr)) ip.release() return True except Exception as e: self.log.fatal("Failed to change routing, err_msg:%s" % str(e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to change routing: ' + str(e))
def add_device_to_blacklist(self, iface, sta_mac_addr): """ Blacklist a given STA in the AP, i.e. any request for association by the STA will be ignored by the AP. tbd: what is -p ?? Please simplify """ exec_file = 'sudo hostapd_cli' args = '-p /tmp/hostapd-' + iface + ' blacklist_sta' command = exec_file + ' ' + args + ' ' + sta_mac_addr self.log.debug('Blacklist node %s on iface %s' % (sta_mac_addr, iface)) self.log.debug('exec %s' % command) try: [rcode, sout, serr] = self.run_command(command) return sout except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def register_new_device(self, iface, sta_mac_addr): """ Register a new STA within the AP, i.e. afterwards the STA is able to exchange data frames. tbd: consider client capabilities """ self.log.debug('Add new STA %s on iface %s' % (sta_mac_addr, iface)) exec_file = 'sudo hostapd_cli' self.log.debug('exec path: %s' % exec_file) try: cmd = "{} -p /tmp/hostapd-{} new_sta {}".format( exec_file, iface, sta_mac_addr) [rcode, sout, serr] = self.run_command(cmd) return sout except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def remove_device_from_blacklist(self, iface, sta_mac_addr): """ Unblacklist a given STA in the AP, i.e. the STA is able to associate with this AP afterwards. tbd: what is -p ?? Please simplify """ exec_file = 'sudo hostapd_cli' args = '-p /tmp/hostapd-' + iface + ' unblacklist_sta' command = exec_file + ' ' + args + ' ' + sta_mac_addr self.log.debug('exe: %s' % command) self.log.debug('Unblacklist node %s on iface %s' % (sta_mac_addr, iface)) try: [rcode, sout, serr] = self.run_command(command) return sout except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def disconnect_device(self, iface, sta_mac_addr): """ Send a disaccociation request frame to a client STA associated with this AP. tbd: what is -p ?? Please simplify """ exec_file = 'sudo hostapd_cli' args = '-p /tmp/hostapd-' + iface + ' disassociate' command = exec_file + ' ' + args + ' ' + sta_mac_addr self.log.debug('Disassociate STA %s on iface %s' % (sta_mac_addr, iface)) self.log.debug('exe: %s' % command) try: [rcode, sout, serr] = self.run_command(command) return sout except Exception as e: fname = inspect.currentframe().f_code.co_name self.log.fatal("An error occurred in %s: %s" % (fname, e)) raise exceptions.FunctionExecutionFailedException(func_name=fname, err_msg=str(e))
def get_csi(self, num_samples, withMetaData=False): """ Reads the next csi values. :param num_samples: the number of samples to read :return: for withMetaData=True: tbd ELSE: the csi values as numpy matrix of dimension: num_samples x Ntx x Nrx x Nsc """ try: tempfile = '/tmp/out' # 1. userland netlink cmd = 'log_to_file_max ' + tempfile + ' ' + str(num_samples) [rcode, sout, serr] = self.run_command(cmd) # 2. read from file csi_trace = self.eng.read_bf_file(tempfile) num_samples = len(csi_trace) print('no. samples: %d' % num_samples) if withMetaData: all = [] for s in range(num_samples): csi_entry = csi_trace[s] csi = self.eng.get_scaled_csi(csi_entry) csi_np = np.zeros(csi.size, dtype=np.complex_) for ii in range(csi.size[0]): for jj in range(csi.size[1]): for zz in range(csi.size[2]): csi_np[ii][jj][zz] = csi[ii][jj][zz] res = {} res['csi_scaled'] = csi_np for k in csi_entry.keys(): res[k] = csi_entry[k] all.append(res) return all else: Ntx = 3 Nrx = 3 Nsc = 30 csi_np = np.zeros((num_samples, Ntx, Nrx, Nsc), dtype=np.complex_) for s in range(num_samples): csi_entry = csi_trace[s] csi = self.eng.get_scaled_csi(csi_entry) for ii in range(csi.size[0]): for jj in range(csi.size[1]): for zz in range(csi.size[2]): csi_np[s][ii][jj][zz] = csi[ii][jj][zz] return csi_np except Exception as e: self.log.fatal("Failed to get CSI: %s" % str(e)) raise exceptions.FunctionExecutionFailedException( func_name=inspect.currentframe().f_code.co_name, err_msg='Failed to get CSI: ' + str(e)) return None