Example #1
0
    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 = []
Example #2
0
    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)
Example #3
0
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"
Example #4
0
    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)
Example #5
0
        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"
Example #6
0
#!/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)

Example #7
0
#!/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)
Example #8
0
                            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]
Example #9
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]
Example #10
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]))
Example #11
0
                            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)
Example #12
0
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)
Example #13
0
                            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)
Example #14
0
#!/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)