def __init__(self, config="track_server.cfg"): # Logging logging.basicConfig(filename=self.log_file, level=self.log_level, filemode='w', format='%(asctime)s %(levelname)s: %(message)s') self.logger = logging.getLogger("trackserver") # Configuration file self.config = None if os.path.exists(config): self.config = ConfigParser.ConfigParser() self.config.read(config) if self.config.has_option("Database", "db_user"): self.db_user = self.config.get("Database", "db_user") if self.config.has_option("Database", "db_pass"): self.db_pass = self.config.get("Database", "db_pass") if self.config.has_option("Database", "db_host"): self.db_host = self.config.get("Database", "db_host") if self.config.has_option("Database", "db_name"): self.db_name = self.config.get("Database", "db_name") # DB connection with general purposes self.db = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # DB connection specific for thread _process_msg() self.db_process = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # DB connection specific for thread _update() self.db_update = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # Emane service self.service = EventService(('224.1.2.8', 45703, self.net_iface)) # Queue of unprocessed messages from track generator self.msg_queue = deque([]) # List of NEMs available in the simulation self.nems = []
def setpathloss(self, numnodes): """ Send EMANE pathloss events to connect all NEMs in a chain. """ if self.session.emane.version < self.session.emane.EMANE091: service = emaneeventservice.EventService() e = emaneeventpathloss.EventPathloss(1) old = True else: if self.session.emane.version == self.session.emane.EMANE091: dev = "lo" else: dev = self.session.obj("ctrlnet").brname service = EventService(eventchannel=("224.1.2.8", 45703, dev), otachannel=None) old = False for i in range(1, numnodes + 1): rxnem = i # inform rxnem that it can hear node to the left with 10dB noise txnem = rxnem - 1 if txnem > 0: if old: e.set(0, txnem, 10.0, 10.0) service.publish(emaneeventpathloss.EVENT_ID, emaneeventservice.PLATFORMID_ANY, rxnem, emaneeventservice.COMPONENTID_ANY, e.export()) else: e = PathlossEvent() e.append(txnem, forward=10.0, reverse=10.0) service.publish(rxnem, e) # inform rxnem that it can hear node to the right with 10dB noise txnem = rxnem + 1 if txnem > numnodes: continue if old: e.set(0, txnem, 10.0, 10.0) service.publish(emaneeventpathloss.EVENT_ID, emaneeventservice.PLATFORMID_ANY, rxnem, emaneeventservice.COMPONENTID_ANY, e.export()) else: e = PathlossEvent() e.append(txnem, forward=10.0, reverse=10.0) service.publish(rxnem, e)
def init_nodes(service): if __name__ == "__main__": with open_tdma(): time.sleep(5) esh = EMANEShell('localhost', 47000) # Debug level #esh.do_loglevel('4') # haifa airport, Naharia, Tiberias, Haifa airport 33.013 35.05 service = EventService(('224.1.2.8', 45703, 'emanenode0')) init_nodes(service) raw_input("Press Enter to continue...") print "Done"
def setpathloss(self, numnodes): """ Send EMANE pathloss events to connect all NEMs in a chain. """ if self.session.emane.version < self.session.emane.EMANE091: service = emaneeventservice.EventService() e = emaneeventpathloss.EventPathloss(1) old = True else: if self.session.emane.version == self.session.emane.EMANE091: dev = "lo" else: dev = self.session.obj("ctrlnet").brname service = EventService(eventchannel=("224.1.2.8", 45703, dev), otachannel=None) old = False for i in xrange(1, numnodes + 1): rxnem = i # inform rxnem that it can hear node to the left with 10dB noise txnem = rxnem - 1 if txnem > 0: if old: e.set(0, txnem, 10.0, 10.0) service.publish(emaneeventpathloss.EVENT_ID, emaneeventservice.PLATFORMID_ANY, rxnem, emaneeventservice.COMPONENTID_ANY, e.export()) else: e = PathlossEvent() e.append(txnem, forward=10.0, reverse=10.0) service.publish(rxnem, e) # inform rxnem that it can hear node to the right with 10dB noise txnem = rxnem + 1 if txnem > numnodes: continue if old: e.set(0, txnem, 10.0, 10.0) service.publish(emaneeventpathloss.EVENT_ID, emaneeventservice.PLATFORMID_ANY, rxnem, emaneeventservice.COMPONENTID_ANY, e.export()) else: e = PathlossEvent() e.append(txnem, forward=10.0, reverse=10.0) service.publish(rxnem, e)
if i == 0: continue for counter in range(0, 2000): counter = float(counter) / 2000 lon = coordinates[i - 1][0] + counter * (coordinates[i][0] - coordinates[i - 1][0]) lat = coordinates[i - 1][1] + counter * (coordinates[i][1] - coordinates[i - 1][1]) os.system(sdtcmd_path + " " + "node node-02 position" + " " + str(lon)[0:7] + "," + str(lat)[0:7]) os.system(sdtcmd_path + " " + "wait 50.0") # create an event setting plane position event = LocationEvent() event.append(12, latitude=lat, longitude=lon, altitude=500.000000) service.publish(0, event) event = LocationEvent() event.append(7, latitude=lat, longitude=lon, altitude=500.000000) service.publish(0, event) time.sleep(0.01) time.sleep(20) if __name__ == "__main__": #haifa airport, Naharia, Tiberias, Haifa airport coordinates = [(35.0433, 32.8119), (35.121314, 33.017947), (35.532089, 32.794592), (35.0433, 32.8119)] service = EventService(('224.1.2.8', 45703, 'emanenode0')) init_nodes(service) move_node(service, coordinates) print "Done"
#!/usr/bin/env python from emanesh.events import EventService from emanesh.events import LocationEvent # create the event service service = EventService(('224.1.2.8',45703,'emanenode0')) # create an event setting 10's position event = LocationEvent() event.append(10,latitude=40.031290,longitude=-74.523095,altitude=3.000000) # publish the event service.publish(0,event)
#!/usr/bin/env python from emanesh.events import EventService from emanesh.events import PathlossEvent # # create the event service service = EventService(('224.1.2.8', 45703, 'emanenode0')) # # create an event setting the pathloss between 1 & 10 event = PathlossEvent() event.append(9, forward=900) event.append(7, forward=900) # # publish the event service.publish(9, event) service.publish(7, event) # # create an event setting the pathloss between 9 & 10 event = PathlossEvent() event.append(9, forward=90) event.append(10, forward=90) # # publish the event service.publish(9, event) service.publish(10, event)
action="append", type="int", dest="target", help="Only send an event to the target") optionParser.add_option("-r", "--reference", action="append", type="int", dest="reference", help="Send events to targeted NEMs but only include information for the reference NEM.") (options, args) = optionParser.parse_args() service = EventService((options.group,options.port,options.device)) if len(args) < 2: print >>sys.stderr,"missing arguments" exit(1) nems = args[0].split(':') if len(nems) == 0 or len(nems) > 2: print >>sys.stderr,"invalid NEMID format:",args[0] exit(1) try: nems = [int(x) for x in nems] except: print >>sys.stderr,"invalid NEMID format:",args[0]
dest="target", help="Only send an event to the target") optionParser.add_option( "-r", "--reference", action="append", type="int", dest="reference", help= "Send events to NEMs in the range but only include information for the reference NEM." ) (options, args) = optionParser.parse_args() service = EventService((options.group, options.port, options.device)) if len(args) < 2: print >> sys.stderr, "missing arguments" exit(1) nems = args[0].split(':') if len(nems) == 0 or len(nems) > 2: print >> sys.stderr, "invalid NEMID format:", args[0] exit(1) try: nems = [int(x) for x in nems] except: print >> sys.stderr, "invalid NEMID format:", args[0]
class TrackServer: """Read ptracks data through a multicast address and update the position of aircraft nodes on a MySQL database. """ update_interval = 1.0 log_file = "track_server.log" log_level = logging.DEBUG net_tracks = "235.12.2.4" net_iface = "ctrl0" db_name = 'atn_sim' db_user = '******' db_pass = '******' db_host = '172.17.255.254' tracks = {} def __init__(self, config="track_server.cfg"): # Logging logging.basicConfig(filename=self.log_file, level=self.log_level, filemode='w', format='%(asctime)s %(levelname)s: %(message)s') self.logger = logging.getLogger("trackserver") # Configuration file self.config = None if os.path.exists(config): self.config = ConfigParser.ConfigParser() self.config.read(config) if self.config.has_option("Database", "db_user"): self.db_user = self.config.get("Database", "db_user") if self.config.has_option("Database", "db_pass"): self.db_pass = self.config.get("Database", "db_pass") if self.config.has_option("Database", "db_host"): self.db_host = self.config.get("Database", "db_host") if self.config.has_option("Database", "db_name"): self.db_name = self.config.get("Database", "db_name") # DB connection with general purposes self.db = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # DB connection specific for thread _process_msg() self.db_process = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # DB connection specific for thread _update() self.db_update = MySQLdb.connect(self.db_host, self.db_user, self.db_pass, self.db_name) # Emane service self.service = EventService(('224.1.2.8', 45703, self.net_iface)) # Queue of unprocessed messages from track generator self.msg_queue = deque([]) # List of NEMs available in the simulation self.nems = [] def start(self): self.logger.info("Initiating server") self._init_nodes_table() self._init_nems_table() self._init_mapings() # t1 = threading.Thread(target=self._update_from_emane, args=()) t1 = threading.Thread(target=self._update_from_tracks, args=()) t2 = threading.Thread(target=self.listen, args=()) t3 = threading.Thread(target=self._process_queue, args=()) t1.start() t2.start() t3.start() self.db.close() def stop(self): pass def listen(self): # Retrieving list of nodes nodes = emane_utils.get_all_locations() for n in nodes: self.nems.append(n["nem"]) if len(nodes) == 0: self.logger.error("Cannot read nodes' positions from Emane") # IP address of incoming messages ip = ni.ifaddresses(self.net_iface)[2][0]['addr'] sock = mcast_socket.McastSocket(local_port=1970, reuse=True) sock.mcast_add(self.net_tracks, ip) self.logger.info("Waiting for track messages on %s:%d" % (self.net_tracks, 1970)) while True: data, sender_addr = sock.recvfrom(1024) # Inserting received messages in the queue self.msg_queue.append(data) def _process_queue(self): while True: if len(self.msg_queue) == 0: time.sleep(0.5) continue else: self._process_msg(self.msg_queue.popleft()) def _process_msg(self, data): FT_TO_M = 0.3048 KT_TO_MPS = 0.51444444444 message = data.split("#") # ex: 101#114#1#7003#-1#4656.1#-16.48614#-47.947058#210.8#9.7#353.9#TAM6543#B737#21653.3006492 msg_ver = int(message[0]) msg_typ = int(message[1]) if msg_typ != 114: return msg_num = int(message[2]) # node id msg_ssr = message[3] msg_spi = int(message[4]) # if spi > 0, SPI=ON, otherwise SPI=OFF msg_alt = float(message[5]) # altitude (feet) msg_lat = float(message[6]) # latitude (degrees) msg_lon = float(message[7]) # longitude (degrees) msg_vel = float(message[8]) # velocity (knots) msg_cbr = float(message[9]) # climb rate (m/s) msg_azm = float(message[10]) # azimuth (degrees) msg_csg = message[11] # callsign msg_per = message[12] # aircraft performance type msg_tim = float(message[13]) # timestamp (see "hora de inicio") if msg_num in self.track2nem: nemid = self.track2nem[msg_num] else: nemid = msg_num if nemid not in self.nems: # Current track does not exists in the simulation return # # Update node's physical parameters using Emane API # event = LocationEvent() event.append(nemid, latitude=msg_lat, longitude=msg_lon, altitude=msg_alt * FT_TO_M, azimuth=msg_azm, magnitude=msg_vel * KT_TO_MPS, elevation=0.0) self.service.publish(0, event) # # Update local variables # obj = { 'latitude': msg_lat, 'longitude': msg_lon, 'altitude': msg_alt * FT_TO_M, 'pitch': 0.0, 'roll': 0.0, 'yaw': 0.0, 'azimuth': msg_azm, 'elevation': 0.0, 'magnitude': msg_vel * KT_TO_MPS, } self.tracks[nemid] = obj # # Update transponder's parameters using database shared memory # try: cursor = self.db_process.cursor() cursor.execute( "SELECT callsign, performance_type, ssr_squawk FROM transponder WHERE nem_id=%d" % nemid) result = cursor.fetchone() if result is None: return db_callsign = result[0] db_perftype = result[1] db_squawk = result[2] if db_callsign[ 0] != msg_csg or db_perftype != msg_per or db_squawk != msg_ssr: sql = "UPDATE transponder SET callsign='%s', performance_type='%s', ssr_squawk='%s' " \ "WHERE nem_id=%d" % (msg_csg, msg_per, msg_ssr, nemid) cursor.execute(sql) self.db_process.commit() cursor.close() except MySQLdb.Error, e: logging.warn("listen(): MySQL Error [%d]: %s" % (e.args[0], e.args[1]))
dest="device", help="Event channel multicast device") (options, args) = optionParser.parse_args() if len(args) == 1: if os.path.isfile(args[0]): schedule = TDMASchedule(args[0]) else: print >>sys.stderr, "unable to open:",args[0] exit(1) else: print >>sys.stderr, "invalid number of arguments" exit(1) eventService = EventService((options.group,options.port,options.device)) info = schedule.info() structure = schedule.structure() frameDefaults = schedule.defaultsFrame(); for nodeId in info: event = TDMAScheduleEvent(**schedule.defaults()) for frameIndex in info[nodeId]: for slotIndex,args in info[nodeId][frameIndex].items(): defaults = args for key,value in frameDefaults[frameIndex].items(): defaults["frame." + key] = value event.append(frameIndex,slotIndex,**defaults)
def main(): global conf_file global node_conf_file global ENABLE_TIMEKEEPER global max_tdf global topo_size os.system("sudo chmod -R 777 /tmp") os.system("sudo rm -rf /tmp/emane") if is_root() == 0: print "Must be run as root" sys.exit(-1) arg_list = sys.argv if len(arg_list) == 1: conf_file = cwd + "/conf/emane.conf" node_conf_file = cwd + "/conf/node.conf" else: i = 1 while i < len(arg_list): if arg_list[i] == "-D": ENABLE_TIMEKEEPER = 0 else: ENABLE_TIMEKEEPER = 1 conf_files_dir = arg_list[1] if os.path.isdir(conf_files_dir) == True: conf_file = conf_files_dir + "/emane.conf" node_conf_file = conf_files_dir + "/node.conf" if os.path.exists(conf_file) == False or os.path.exists( node_conf_file) == False: print "Config files do not exist" sys.exit(-1) else: print "Config directory specified is incorrect" sys.exit(-1) i = i + 1 Node, run_time, n_nodes, eventmanagergroup, timeslice = configure() topo_size = n_nodes # create experiment-data directory with open(cwd + "/experiment-data/exp-info.txt", "w") as f: f.write("Conf file path : " + conf_file + "\n") f.write("Node Conf file : " + node_conf_file + "\n") f.write("Run time : " + str(run_time) + "\n") f.write("N_nodes : " + str(n_nodes) + "\n") # copy node_config file and emane_conf file os.system("mkdir -p " + cwd + "/experiment-data") start_LXCs() print "Timeslice = ", timeslice print "Setting initial location values to all lxcs ..." nemid = 1 temp_list = eventmanagergroup.split(":") eventmanagergroupaddress = temp_list[0] eventmanagergroupport = int(temp_list[1]) service = EventService( (eventmanagergroupaddress, eventmanagergroupport, 'br0')) event = LocationEvent() i = 1 while i <= n_nodes: pathlossevt = PathlossEvent() j = 1 while j <= n_nodes: if i != j: pathlossevt.append(j, forward=90, reverse=90) j = j + 1 i = i + 1 while nemid <= n_nodes: event.append(nemid, latitude=Node[nemid]["lattitude"], longitude=Node[nemid]["longitude"], altitude=Node[nemid]["altitude"]) nemid = nemid + 1 service.publish(0, event) time.sleep(2) print "Location events published. All nodes set to initial positions. Waiting for 30 sec for routing updates to stabilize" time.sleep(50) # Timekeeper portion freeze_quantum = 1000000 # in nano seconds nemid = 1 while nemid <= n_nodes: pid = int(getpidfromname("node-" + str(nemid))) print "PID of node ", nemid, " = ", pid, " TDF = ", Node[nemid]["tdf"] if pid != -1 and ENABLE_TIMEKEEPER == 1: dilate_all(pid, Node[nemid]["tdf"]) addToExp(pid) if max_tdf < Node[nemid]["tdf"]: max_tdf = Node[nemid]["tdf"] nemid += 1 lxc_pid = int(getpidfromname("node-1")) if os.path.exists(cwd + "/exp_finished.txt"): os.unlink(cwd + "/exp_finished.txt") # send commands to execute to each LXC nemid = 1 while nemid <= n_nodes: if nemid % 2 == 0: process = subprocess.Popen([ "python", "lxc_command_dispatcher.py", str(0), str(nemid), Node[nemid]["cmd"] ]) else: process = subprocess.Popen([ "python", "lxc_command_dispatcher.py", str(1), str(nemid), Node[nemid]["cmd"] ]) nemid += 1 print "Set freeze_quantum = ", freeze_quantum * max_tdf if ENABLE_TIMEKEEPER == 1 and max_tdf >= 1: set_cpu_affinity(int(os.getpid())) set_cbe_experiment_timeslice(freeze_quantum * max_tdf) print "Timekeeper synchronizing ..." synchronizeAndFreeze() startExp() print "Synchronized CBE experiment started ..." start_time = int(get_current_virtual_time_pid(int(lxc_pid))) prev_time = start_time print "Experiment start time", start_time, " local Time = " + str( datetime.now()) sys.stdout.flush() else: print "Experiment Started with TimeKeeper disabled - Ignoring TDF settings" try: k = 0 while True: if ENABLE_TIMEKEEPER == 1: curr_time = int(get_current_virtual_time_pid(int(lxc_pid))) if curr_time - start_time >= run_time: break else: if curr_time - prev_time >= 1: k = k + (curr_time - prev_time) print k, " secs of virtual time elapsed" prev_time = curr_time else: if k >= run_time: break k = k + 1 print k, " secs of real time elapsed" # sleep until runtime expires time.sleep(1) except KeyboardInterrupt: pass # stop Exp print "Stopping Synchronized experiment, local time = " + str( datetime.now()) if ENABLE_TIMEKEEPER == 1: stopExp() time.sleep(10) stop_LXCs(max_tdf)
dest="device", help="Event channel multicast device") (options, args) = optionParser.parse_args() if len(args) == 1: if os.path.isfile(args[0]): schedule = TDMASchedule(args[0]) else: print >> sys.stderr, "unable to open:", args[0] exit(1) else: print >> sys.stderr, "invalid number of arguments" exit(1) eventService = EventService((options.group, options.port, options.device)) info = schedule.info() structure = schedule.structure() frameDefaults = schedule.defaultsFrame() for nodeId in info: event = TDMAScheduleEvent(**schedule.defaults()) for frameIndex in info[nodeId]: for slotIndex, args in info[nodeId][frameIndex].items(): defaults = args for key, value in frameDefaults[frameIndex].items(): defaults["frame." + key] = value event.append(frameIndex, slotIndex, **defaults)
#!/usr/bin/env python from emanesh.events import EventService from emanesh.events import PathlossEvent # create the event service service = EventService(('224.1.2.8',45703,'emanenode0')) # create an event setting the pathloss between 1 & 10 event = PathlossEvent() event.append(1,forward=90) event.append(10,forward=90) # publish the event service.publish(1,event) service.publish(10,event) # create an event setting the pathloss between 9 & 10 event = PathlossEvent() event.append(9,forward=90) event.append(10,forward=90) # publish the event service.publish(9,event) service.publish(10,event)