예제 #1
0
class ISSSimIfaceLib:
    ROBOT_LIBRARY_SCOPE = "TEST SUITE"
    cmd_port    = 10000
    hs_port     = 11000
    telm_port   = 12000

    cmd_ip  = '127.0.0.1'
    hs_ip   = '127.0.0.1'
    telm_ip = '127.0.0.1' 

    hs_sock     = None
    telm_sock   = None
    txSeqCnt      = 0
     
    session = None

    def __init__(self, cmd_schema_filename, cmd_dict_filename, cmd_dict_sheet, \
            hs_dict_filename, hs_dict_sheet, \
            telm_schema_filename, \
            dbFilename="roboSCAT.db",byteSwap=False):
        logger.info("Loading ISS Sim Interface Library")
        self.dbFilename = dbFilename
        self.cmd_schema_filename = cmd_schema_filename
        self.cmd_dict_filename = cmd_dict_filename
        self.cmd_dict_sheet = cmd_dict_sheet
        self.hs_dict_filename = hs_dict_filename
        self.hs_dict_sheet = hs_dict_sheet
        self.telm_schema_filename = telm_schema_filename

        self.cmd_database = CmdDatabase(self.dbFilename)
        self.hs_database = HSDatabase(self.dbFilename)
        self.telm_database = TelmDatabase(self.dbFilename)
        self.byteSwap = byteSwap

        self.hsPacketSize = 1024
        self.telmPacketSize = 1024

        self.viewer = None

    def load_cmd_database(self,reload='False'):
        cmdDatabaseLoaded = self.cmd_database.is_valid_table(self.cmd_database.tableName)
        if (not cmdDatabaseLoaded) or reload=='RELOAD':
            self.cmd_database.drop_table()
            self.cmd_database.load_schema(self.cmd_schema_filename)
            self.cmd_database.create_table()
            self.cmd_database.load_cmds(self.cmd_dict_filename,self.cmd_dict_sheet,True)
        else:
            self.cmd_database.load_cmds(self.cmd_dict_filename,self.cmd_dict_sheet)
    
    def load_hs_database(self,reload='False'):
        hsDatabaseLoaded = self.hs_database.is_valid_table(self.hs_database.tableName)
        if (not hsDatabaseLoaded) or reload=='RELOAD':
            self.hs_database.drop_table()
            self.hs_database.load_schema(self.hs_dict_filename, self.hs_dict_sheet,True)
            self.hs_database.create_table()
        else:            
            self.hs_database.load_schema(self.hs_dict_filename, self.hs_dict_sheet)

    def load_telm_database(self,reload='False'):
        telmDatabaseLoaded = self.telm_database.is_valid_table(self.telm_database.tableName)
        if (not telmDatabaseLoaded) or reload=='RELOAD':
            self.telm_database.drop_table()
            self.telm_database.load_schema()
            self.telm_database.create_table()

    def set_byte_swap(self,byteSwapEnable):
        if byteSwapEnable == '1':
            logger.info("Enabling byte swapping")
            self.byteSwap = True

    def set_telm_packet_size(self,sizeInBytes):
        self.telmPacketSize = sizeInBytes

    def set_hs_packet_size(self,sizeInBytes):
        self.hsPackdetSize = sizeInBytes

    def drop_tables(self):
        logger.warn("Dropping tables!!!!!!!!!!!!!!!!!!!")
        self.cmd_database.drop_table()
        self.hs_database.drop_table()

    def set_cmd_port(self,cmd_port):
        self.cmd_port = int(cmd_port)
        logger.info("Setting command port to %d" % self.cmd_port)
        
    def set_hs_port(self,hs_port):
        self.hs_port = int(hs_port)
        logger.info("Setting health and status port to %d" % self.hs_port)

    def set_telm_port(self,telm_port):
        self.telm_port = int(telm_port)
        logger.info("Setting telemetry port to %d" % self.telm_port)

    def set_cmd_ip(self,cmd_ip):
        logger.info("Setting command port to %s" % cmd_ip)
        self.cmd_ip = cmd_ip

    def set_hs_ip(self,hs_ip):
        logger.info("Setting health and status port to %s" % hs_ip)
        self.hs_ip = hs_ip

    def set_telm_ip(self,telm_ip):
        logger.info("Setting telemetry port to %s" % telm_ip)
        self.telm_ip = telm_ip

    def corrupt_next_cmd(self,fieldToCorrupt):
        logger.info("Setting cmd packet %s to be corrupted")
        self.session.corrupt_next_cmd(fieldToCorrupt)

    def create_sock(self,ip,port,bind=False,connect=False):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            if bind:
                sock.bind((ip,port))
            elif connect:
                sock.connect((ip,port))
        except:
            raise RuntimeError("Can't open socket IP=%s port=%d" % (ip, port))
        return sock

    def set_viewer(self,viewerObj):
        self.viewer = viewerObj

    def start_session(self):
        logger.info("Starting session with the ISS sim")
       
        self.hs_sock = self.create_sock(self.hs_ip,self.hs_port,bind=True)
        self.telm_sock = self.create_sock(self.telm_ip,self.telm_port,bind=True)

        self.cmdQ = Queue.Queue()
        hsRecvEvent = threading.Event()
        telmRecvEvent = threading.Event()
        self.session = SessionThread(self.cmdQ,self.hs_sock,self.telm_sock,\
                                    self.dbFilename,hsRecvEvent,telmRecvEvent)
        self.session.set_cmd_addr(self.cmd_ip,self.cmd_port)
        self.session.set_packet_sizes(self.hsPacketSize,self.telmPacketSize)
        self.session.set_byte_swap(self.byteSwap)

        if self.viewer:
            self.viewer.start()

        self.session.start()
        logger.info("Session started")

    def stop_session(self):
        logger.info("Stopping session with the ISS sim")
        if self.session != None:
            self.session.stop()
            self.session.join()
        logger.info("Session stopped")

    def terminate_session(self):
        logger.info("Terminating session with the ISS sim")
        if self.session != None:
            self.session.stop()
            self.session.join()

        if self.hs_sock != None:
            self.hs_sock.close()

        if self.telm_sock != None:
            self.telm_sock.close()
        logger.info("Session terminated")

    def send_cmd(self,cmd_name,*args):
        cmdFormat = self.cmd_database.get_cmd_format(cmd_name)
        cmd  = self.cmd_database.build_cmd(cmdFormat,args)
        self.cmdQ.put(cmd)
        logger.info("Sending cmd %s" % cmd_name)
 
    def read_hs_field(self,field_name):
        ret = self.hs_database.read_hs_field(field_name)
        return ret

    def get_received_hs_packet_count(self):
        return self.session.recvdHsPackets

    def get_received_telm_packet_count(self):
        return self.session.recvdTelmPackets

    def get_hs_seq_count(self):
        return self.session.hsRxSeqCnt

    def get_telm_seq_count(self):
        return self.session.telmRxSeqCnt

    def get_cmd_seq_count(self):
        return self.session.txSeqCnt
    
    def get_cmd_opCode(self,cmdName):
        return self.cmd_database.get_opCode_from_cmdName(cmdName)
    
    def get_hs_APID(self):
        return self.session.hsAPID

    def get_telm_APID(self):
        return self.session.telmAPID

    def get_telm_data_rate(self):
        return self.session.telmDataRate

    def get_last_telm_packet(self):
        return self.telm_database.read_packet() 

    def wait_for_hs_packet(self,timeoutSecs=60):
        if not self.session.isAlive():
            logger.warn("Can't wait for packet if session not open!")
            raise RuntimeError("Session not open!")
        logger.info("Waiting for HS packet with a timeout of %d s" % timeoutSecs)
        if not self.session.wait_for_next_hs_packet(timeoutSecs):
            raise RuntimeError("Didn't recieve packet in %s secs" % timeoutSecs)
        return True

    def wait_for_telm_packet(self,timeoutSecs=60):
        if not self.session.isAlive():
            logger.warn("Can't wait for packet if session not open!")
            raise RuntimeError("Session not open!")
        logger.info("Waiting for HS packet with a timeout of %d s" % timeoutSecs)
        if not self.session.wait_for_next_telm_packet(timeoutSecs):
            raise RuntimeError("Didn't recieve packet in %s secs" % timeoutSecs)
        return True
   
    def convert_temp_to_celsius(self,value,calibration):
        value =  float(value)
        calibration = float(calibration)
        return convert_to_celsius(value,calibration)

    def convert_ccsds_time_to_unix(self,ccsdsTime):
        ccsdsTime = bytearray(ccsdsTime)
        timeFine,timeCoarse = unpack_ISS_time(ccsdsTime)
        timeUnix = convert_ISS_to_unix_time(timeFine,timeCoarse,leapSecs=0, 
                            gpsEpochStart=( 1970,1,1,0,0,0,3,6,-1))
        return timeUnix
예제 #2
0
class SessionThread(threading.Thread):
    
    ROBOT_LIBRARY_SCOPE = "TEST SUITE"
    def __init__(self,cmdQ,hs_sock,telm_sock,dbFilename,hsRecvEvent,telmRecvEvent):
        threading.Thread.__init__(self)
        self.cmdQ = cmdQ
        self.cmd_ip = '127.0.0.1'
        self.cmd_port = 2001
        self.hs_sock = hs_sock
        self.telm_sock = telm_sock
        self.rx_socks = [self.hs_sock,self.telm_sock]

        self.dbFilename=dbFilename       
        
        self._stop = threading.Event()
        self._hsRecvEvent = hsRecvEvent
        self._telmRecvEvent = telmRecvEvent
        self.byteSwap = False
        self.hsPacketSize = 1024
        self.telmPacketSize = 1024

        self.txSeqCnt = 0
        self.timeout = 0.1
        self.recvdHsPackets = 0
        self.recvdTelmPackets = 0
        
        self.hsRxSeqCnt = 0
        self.telmRxSeqCnt = 0
        self.hsAPID=0
        self.telmAPID=0
        
        self.telmDataRate = 0.0
        self.telmLastRxTime = 0.0

        self.enableCorruption = False
        self.fieldToCorrupt = ""

    #TODO these need mutexes....
    def set_packet_sizes(self,hsPacketSize,telmPacketSize):
        self.hsPacketSize = hsPacketSize
        self.telmPacketSize = telmPacketSize

    def set_byte_swap(self,byteSwap):
        self.byteSwap=byteSwap

    def set_cmd_addr(self,cmdIp,cmdPort):
        self.cmd_ip = cmdIp
        self.cmd_port = cmdPort

    def set_select_timeout(self,timeout):
        self.timeout = timeout

    def run(self):
        print "Starting thread" 
        self.cmdDatabase = CmdDatabase(self.dbFilename) 
        hsTableValid = self.cmdDatabase.is_valid_table(self.cmdDatabase.tableName)
        if not hsTableValid:
            raise RuntimeError("Table %s not found in %s " 
                                    % (self.cmdDatabase.tableName,self.dbFilename))
        
        self.hsDatabase = HSDatabase(self.dbFilename) 
        hsTableValid = self.hsDatabase.is_valid_table(self.hsDatabase.tableName)
        if not hsTableValid:
            raise RuntimeError("Table %s not found in %s " 
                                    % (self.hsDatabase.tableName,self.dbFilename))
        
        self.telm_database = TelmDatabase(self.dbFilename) 
        telmTableValid = self.telm_database.is_valid_table(self.telm_database.tableName)
        if not telmTableValid:
            raise RuntimeError("Table %s not found in %s!" 
                                    % (self.telm_database.tableName,self.dbFilename))

        while True:
            readable,writable,errord = select.select(self.rx_socks,[],[],self.timeout)
            currTime = time.time()
            
            if self.hs_sock in readable:
                buf,addr = self.hs_sock.recvfrom(self.hsPacketSize)
                buf = bytearray(buf)
                if self.byteSwap:
                    buf = byte_swap_bytearray(buf)
                packet = CCSDS.CCSDSPacket(buf)
                self.hsRxSeqCnt =  packet.get_seq_cnt()
                self.hsAPID = packet.get_APID()
                data = packet.get_data()
                
                self.hsDatabase.insert_packet(currTime,self.hsRxSeqCnt,data)
                
                self.recvdHsPackets+=1
                self._hsRecvEvent.set()

            if self.telm_sock in readable:
                buf,addr = self.telm_sock.recvfrom(self.telmPacketSize)
                buf = bytearray(buf)
                if self.byteSwap:
                    buf = byte_swap_bytearray(buf)
                packet = CCSDS.CCSDSPacket(buf)
                self.telmRxSeqCnt =  packet.get_seq_cnt()
                self.telmAPID = packet.get_APID()
                data = packet.get_data()
                crcRxd = packet.get_crc() 
                crcCalcd = packet.compute_crc_checksum()
                if crcRxd == crcCalcd: 
                    self.telm_database.insert_packet(currTime,self.telmRxSeqCnt,data)
                    
                    self.telmDataRate = 1/(currTime - self.telmLastRxTime)
                    self.telmLastRxTime =  currTime
                    self.recvdTelmPackets+=1
                    self._telmRecvEvent.set()
                else:
                    print "CRC ERROR"
                    logger.warn("CRC ERROR!")

            if self.cmdQ.empty() == False:
                currEpochTime = time.time()
                cmd = self.cmdQ.get()
                cmdPacket = CCSDS.CCSDSPacket(dataLength=len(cmd))

                if self.fieldToCorrupt == "Headers":
                    cmdPacket.set_primary_header(seqCnt=42,version=1,type=0,
                                                APID=1234,secHdrFlag=0,seqFlags=2,
                                                packetLen=10)
                    cmdPacket.set_secondary_header(timeUnix=currEpochTime,chkSumInd=0,spare=1)
                else:
                    cmdPacket.set_primary_header(self.txSeqCnt)
                    cmdPacket.set_secondary_header(timeUnix=currEpochTime)

                if self.fieldToCorrupt == "Data":
                    buf = bytearray("Phillip is a 133t H4x0r")
                    cmdPacket.set_data(buf)
                else:
                    buf = bytearray()
                    buf = zero_pad(4)
                    buf.extend(cmd)
                    cmdPacket.set_data(buf)
                
                if not self.fieldToCorrupt == "Checksum":
                    cmdPacket.compute_checksum()

                if self.enableCorruption:
                    self.fieldToCorrupt = ""

                if self.byteSwap:
                    cmdPacket.raw = byte_swap_bytearray(cmdPacket.raw)
                
                cmdPacket.raw = cmdPacket.raw.ljust(128,"\00")

                cmd_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                cmd_sock.sendto(cmdPacket.raw,(self.cmd_ip,self.cmd_port))
                cmd_sock.close()
                self.cmdQ.task_done()
                self.cmdDatabase.insert(currTime,self.txSeqCnt,cmd)
                self.txSeqCnt+=1

            if self._stop.isSet():
                break

        return

    def stop(self):
        self._stop.set()

    def corrupt_next_cmd(self,fieldToCorrupt):
        self.enableCorruption = True
        self.fieldToCorrupt = fieldToCorrupt


    def wait_for_next_hs_packet(self,timeoutSecs):
        self._hsRecvEvent.clear()
        self._hsRecvEvent.wait(timeoutSecs)
        ret = self._hsRecvEvent.is_set()
        self._hsRecvEvent.clear()
        return ret

    def wait_for_next_telm_packet(self,timeoutSecs):
        self._telmRecvEvent.clear()
        self._telmRecvEvent.wait(timeoutSecs)
        ret = self._hsRecvEvent.is_set()
        self._telmRecvEvent.clear()
        return ret