def collect_values_from_nodes(self, nodes, node_list, measurement_types, ucallback=None, sampling_time=0, reporting_period=0, iterations=1): """ Defines the function that is called when a bunch of measurements are received from nodes. Than, executes the UPI_R.getMonitorBounce function on nodes, passed by argument. :param nodes: list of WiFiNode. :param node_list: list of Node. :param measurement_types: list of measurements name. :param ucallback: user-defined callback to be called after any reporting period :param sampling_time: the sampling time in [us] which the measurement is taken in the NIC :param reporting_period: period in [us] between two consecutive measurement reporting :param iterations: number of consecutive measurement reporting """ res_measurements = [] def monitorCallback(json_message): """ Is called when a bunch of measurements are received from nodes. Extracts the ip address of the sender node and uses it to find appropriate object in WiFiNode list. Stores the bunch of measurements in last_bunch_measurement WiFinode attribute. :param json_message: message received from node every iterations. """ time_val = json_message['time'] peer_node = json_message['peer'] messagedata = json_message['msg'] callback_id = json_message['callbackId'] res_measurements.append(1) # add every response in a wifinode element for node in nodes: if node.getIpAddress() == callback_id.split('//')[1].split(':')[0] and messagedata != False: node.last_bunch_measurement.append(messagedata) # call user-defined callback (the controller logic) ucallback(messagedata) return self.log.info('CALL getMonitor bunch ....') now = get_now_full_second() UPIfunc = UPI_RN.getMonitorBounce UPIargs = {'measurements': measurement_types, 'slot_period': sampling_time, 'frame_period': reporting_period, 'interface': 'wlan0', 'iterator': iterations} print "UPIargs are ", UPIargs exec_time = now + timedelta(seconds=2) callback = monitorCallback try: self.mytestbed.global_mgr.runAt(node_list, UPIfunc, UPIargs, unix_time_as_tuple(exec_time), callback) except Exception as e: self.log.warning("An error occurred (e.g. scheduling events in the past): %s" % e) # plot data self.measurement_types = measurement_types return
def stop_local_controller(mytestbed): CtrlFuncImpl = UPI_RN.stopFunc CtrlFuncargs = {'INTERFACE' : ['wlan0']} now = get_now_full_second() # exec immediately exec_time = now + timedelta(seconds=3) log.info('Stop local WiSHFUL controller on all nodes - stop at : %s', str(exec_time)) #nodes = upi_hc.getNodes() nodes = mytestbed.nodes try: callback = partial(resultCollector, funcId=99) mytestbed.global_mgr.runAt(nodes, UPI_RN.stopFunc, CtrlFuncargs, unix_time_as_tuple(exec_time), callback) except Exception as e: log.fatal("An error occurred when stop the local WiSHFUL controller: %s" % e)
def collect_values_from_nodes(self, nodes, node_list, measurement_types, ucallback=None, sampling_time=0, reporting_period=0, iterations=1): """ Defines the function that is called when a bunch of measurements are received from nodes. Than, executes the UPI_R.getMonitorBounce function on nodes, passed by argument. :param nodes: list of WiFiNode. :param node_list: list of Node. :param measurement_types: list of measurements name. :param ucallback: user-defined callback to be called after any reporting period :param sampling_time: the sampling time in [us] which the measurement is taken in the NIC :param reporting_period: period in [us] between two consecutive measurement reporting :param iterations: number of consecutive measurement reporting """ res_measurements = [] def monitorCallback(json_message): """ Is called when a bunch of measurements are received from nodes. Extracts the ip address of the sender node and uses it to find appropriate object in WiFiNode list. Stores the bunch of measurements in last_bunch_measurement WiFinode attribute. :param json_message: message received from node every iterations. """ time_val = json_message['time'] peer_node = json_message['peer'] messagedata = json_message['msg'] callback_id = json_message['callbackId'] res_measurements.append(1) # add every response in a wifinode element for node in nodes: if node.getIpAddress() == callback_id.split('//')[1].split( ':')[0] and messagedata != False: node.last_bunch_measurement.append(messagedata) # call user-defined callback (the controller logic) ucallback(messagedata) return self.log.info('CALL getMonitor bunch ....') now = get_now_full_second() UPIfunc = UPI_RN.getMonitorBounce UPIargs = { 'measurements': measurement_types, 'slot_period': sampling_time, 'frame_period': reporting_period, 'interface': 'wlan0', 'iterator': iterations } print "UPIargs are ", UPIargs exec_time = now + timedelta(seconds=2) callback = monitorCallback try: self.mytestbed.global_mgr.runAt(node_list, UPIfunc, UPIargs, unix_time_as_tuple(exec_time), callback) except Exception as e: self.log.warning( "An error occurred (e.g. scheduling events in the past): %s" % e) # plot data self.measurement_types = measurement_types return
def run_local_controller(mytestbed, disable=0): """ Custom function used to implement local WiSHFUL controller """ def customLocalCtrlFunction(myargs): import time import logging # references to Wishful framework global upiRNImpl # interface to UPI_R/N implementation global upiHCImpl # interface used for communication with global controller and control runtime log = logging.getLogger() log.warning('*********** WISHFUL SC3 *************') log.warning('*********** starting local WiSHFUL controller **********************') last_freezing_number = 0 b = 0.1 a = 0.1 last_count_freezing = 0 CWMIN = 15 CWMAX = 1023 T = 0.5 #0.1 ipt = 0 cw_f = CWMIN cycle_update = 0 while not upiHCImpl.stopIsSet(): UPIargs = {'iface' : 'wlan0' } ip_address = upiRNImpl.getIfaceIpAddr(UPIargs) cycle_update += 1 #get freezing number #UPIfunc = UPI_RN.getMonitor UPIargs = {'KEY' : (UPI_RN.NUM_FREEZING_COUNT, 'wlan0' )} current_freezing_number = upiRNImpl.getMonitor(UPIargs) count_freezing = current_freezing_number[0] #Find/Compute CW good delta_freezing = count_freezing - last_count_freezing if delta_freezing < 0 : delta_freezing = 65535 - last_count_freezing + count_freezing last_count_freezing = count_freezing ipt = ipt + a * (delta_freezing - ipt) # #targetcw = -0.0131 * ipt ** 2 + 3.2180 * ipt + 13.9265; # determine the target CW for this IPT targetcw = -1.3539 * ipt ** 2 + 7.6655 * ipt + 15.4545; # determine the target CW for this IPT ver 25-11-2015 on TTILAB with 2,4,6 nodes samples. # calculate new smoothed CW cw_f = cw_f + b * (targetcw - cw_f); cw = round(cw_f); cw = int(cw) cw = max(cw,CWMIN); cw = min(cw,CWMAX); #cw = 50 #update CW value UPIargs = {'KEY' : (UPI_RN.CSMA_CW, UPI_RN.CSMA_CW_MIN, UPI_RN.CSMA_CW_MAX, 'wlan0' ), 'VALUE' : [cw, cw, cw ]} upiRNImpl.setParameterLowerLayer(UPIargs) if not(cycle_update % 10): #communicate with global controller by passing control message upiHCImpl.transmitCtrlMsgUpstream( { "MEASURE" : [[count_freezing, cw]], "IP_ADDRESS" : (ip_address) } ) log.info('current freezing number : %d' % (last_count_freezing)) #wait next update time time.sleep(T) return 'Local WiSHFUL Controller END' """ Custom callback function used to receive result values from scheduled calls, i.e. if you schedule the execution of a particular UPI_R/N function in the future this callback allows you to be informed about any function return values. """ numCBs = {} numCBs['res'] = 0 # use in while to lern if the local logic stopped e.g. # while numCBs['res'] < 2: def resultCollector(json_message, funcId): log.info('json: %s' % json_message) time_val = json_message['time'] peer_node = json_message['peer'] messagedata = json_message['msg'] log.info('Callback %d: Local controller receives data msg at %s from %s : %s' % (funcId, str(time_val), peer_node, messagedata)) numCBs['res'] = numCBs['res'] + 1 """ Custom callback function used to receive control feedback results from local controllers. """ def ctrlMsgCollector(json_message): time_val = json_message['time'] peer_node = json_message['peer'] msg_data = json_message['msg'] remote_wlan_ipAddress = msg_data['IP_ADDRESS'] measurement_types = 'MEASURE' measurement = msg_data['MEASURE'] log.info('Global controller receives ctrl msg at %s from %s : %s' % (str(time_val), peer_node, str(msg_data) )) # add measurement on nodes element for node in mytestbed.wifinodes: if node.wlan_ipAddress == remote_wlan_ipAddress and measurement != False: node.last_bunch_measurement.append(measurement) #log.debug('Append measurements at node %s : %s' % (str(remote_wlan_ipAddress), str(measurement) )) """ Stop function used to send stop function to local controllers. """ def stop_local_controller(mytestbed): CtrlFuncImpl = UPI_RN.stopFunc CtrlFuncargs = {'INTERFACE' : ['wlan0']} now = get_now_full_second() # exec immediately exec_time = now + timedelta(seconds=3) log.info('Stop local WiSHFUL controller on all nodes - stop at : %s', str(exec_time)) #nodes = upi_hc.getNodes() nodes = mytestbed.nodes try: callback = partial(resultCollector, funcId=99) mytestbed.global_mgr.runAt(nodes, UPI_RN.stopFunc, CtrlFuncargs, unix_time_as_tuple(exec_time), callback) except Exception as e: log.fatal("An error occurred when stop the local WiSHFUL controller: %s" % e) # START MAIN PART if disable: stop_local_controller(mytestbed) return # register callback function for collecting results mytestbed.global_mgr.setCtrlCollector(ctrlMsgCollector) # deploy a custom control program on each node CtrlFuncImpl = customLocalCtrlFunction CtrlFuncargs = {'INTERFACE' : ['wlan0']} # get current time now = get_now_full_second() # exec immediately exec_time = now + timedelta(seconds=3) log.info('Sending local WiSHFUL controller on all nodes - start at : %s', str(exec_time)) #nodes = upi_hc.getNodes() for node in mytestbed.wifinodes: node.measurement_types.append('FREEZING_NUMBER') node.measurement_types.append('CW') nodes = mytestbed.nodes try: # this is a non-blocking call callback = partial(resultCollector, funcId=99) #isOntheflyReconfig = True mytestbed.global_mgr.runAt(nodes, CtrlFuncImpl, CtrlFuncargs, unix_time_as_tuple(exec_time), callback ) except Exception as e: log.fatal("An error occurred in local controller WiSHFUL sending and running : %s" % e) log.info("Local logic STARTED") return