VscProxyTools.py

Go to the documentation of this file.
00001 #!/usr/local/bin/python
00002 #
00003 #                               Copyright 2005
00004 #                                     by
00005 #                        The Board of Trustees of the
00006 #                     Leland Stanford Junior University.
00007 #                            All rights reserved.
00008 #
00009 
00010 __facility__ = "Online"
00011 __abstract__ = "Tools for VSC packet handling"
00012 __author__   = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00013 __date__     = "2005/07/23 00:08:27"
00014 __updated__  = "$Date: 2006/04/19 02:56:08 $"
00015 __version__  = "$Revision: 1.10 $"
00016 __release__  = "$Name: HEAD $"
00017 __credits__  = "SLAC"
00018 
00019 import LICOS.copyright_SLAC
00020 
00021 from LICOS.lib.cmdTlmDb.LCATtlmDb           import LICOS_VscTlmPacketFactory
00022 
00023 from binascii import hexlify
00024 
00025 from VSC import VscHandling
00026 import socket
00027 import threading
00028 import struct
00029 import sys
00030 import time
00031 import logging as log
00032 
00033 
00034 class PacketDispatcher(object):
00035   """!\brief PacketDispatcher class
00036 
00037   Class used to define a dispatch system for VSC packets
00038   """
00039 # Implementation notes:
00040 #
00041 #  Note the use of super() in PacketDispatcher, TelemetryDispatcher
00042 #  and ScienceDispatcher.  This usage allows us to use the mixin
00043 #  class PacketDispatcher to replace the process method of
00044 #  the various packet handlers with something a bit more useful.
00045 #
00046 #  Important:  The order of classes in multiple inheritance situations
00047 #  is critical when using super().  The first call to super() will
00048 #  call the first in the chain.  Thus, the call to super.__init
00049 #  in TelemetryDispatcher calls the __init__ of PacketDispatcher.
00050 #  In that function, the call to super.__init__ will call
00051 #  the __init__ method of the *next* class in the MI chain.
00052 #  A good tutorial on super() is at
00053 #  http://wiki.osafoundation.org/bin/view/Projects/UsingSuper
00054   def __init__(self):
00055     super(PacketDispatcher, self).__init__()
00056     self.__handlerList = []
00057     self.__lock = threading.Lock()
00058 
00059   def process(self, dat):
00060     """!\brief process method
00061 
00062     Loops over the registered handlers and calls their process() methods.
00063     If a packet isn't handled by any of the handlers, the catchall()
00064     method is called.
00065 
00066     \param dat A VSC packet (any type)
00067     """
00068     # print "pktdis.process", dat, dat.apid()
00069     self.__lock.acquire()
00070     try:
00071       caught=False
00072       # print self.__handlerList
00073       for handler in self.__handlerList:
00074         # print handler.catchable(dat)
00075         if handler.catchable(dat):
00076           handler.process(dat)
00077           caught=True
00078       if not caught:
00079         self.catchall(dat)
00080     except Exception, e:
00081       print e
00082       self.__lock.release()
00083       raise
00084     else:
00085       self.__lock.release()
00086 
00087   # def catchable(self, dat):
00088     # print "catchable"
00089     # self.__lock.acquire()
00090     # catch = False
00091     # for handler in self.__handlerList:
00092       # if handler.catchable(dat):
00093         # print "setting catch=True for apid %x" % dat.apid()
00094         # catch = True
00095         # break
00096     # self.__lock.release()
00097     # return catch
00098 
00099   def register(self, handler):
00100     """!\brief register method
00101 
00102     register a handler with the dispatcher.
00103 
00104     \param handler A VSC Handler object
00105     """
00106     self.__lock.acquire()
00107     if handler not in self.__handlerList:
00108       self.__handlerList.append(handler)
00109       self.__ranOnce = False
00110     self.__lock.release()
00111 
00112   def unregister(self, handler):
00113     """!\brief unregister method
00114 
00115     remove a handler from the dispatcher's registry.
00116 
00117     \param handler A VSC Handler object
00118     """
00119     self.__lock.acquire()
00120     if handler in self.__handlerList:
00121       self.__handlerList.remove(handler)
00122       self.__ranOnce = False
00123     self.__lock.release()
00124 
00125   def catchall(self, dat):
00126     """!\brief catchall method
00127 
00128     process all packets that are not processed by one of the registered handlers.
00129 
00130     \param dat A VSC packet (any type)
00131     """
00132     log.debug("catchall called for apid %d=0x%03x"%(dat.apid(), dat.apid()))
00133 
00134 class TelemetryDispatcher(PacketDispatcher, VscHandling.TelemetryHandler):
00135   """!\brief TelemetryDispatcher class
00136 
00137   A dispatcher for VSC telemetry data.
00138   """
00139   def __init__(self, apidRange=[0x200,0x25f]):
00140     super(TelemetryDispatcher, self).__init__()
00141     self.handle(apidRange[0], apidRange[1])
00142 
00143   def process(self, dat):
00144     # print "TelemetryDispatcher.process()"
00145     super(TelemetryDispatcher, self).process(dat)
00146 
00147   # def catchable(self, dat):
00148     # print "catch22"
00149     # super(TelemetryDispatcher, self).catchable(dat)
00150 
00151 class ScienceDispatcher(PacketDispatcher, VscHandling.ScienceHandler):
00152   """!\brief ScienceDispatcher class
00153 
00154   A dispatcher for VSC science data.
00155   """
00156   def __init__(self):
00157     super(ScienceDispatcher, self).__init__()
00158     self.handle(0x0,0xffff)
00159 
00160   def process(self, dat):
00161     super(ScienceDispatcher, self).process(dat)
00162 
00163 #  def catchable(self, dat):
00164 #    super(ScienceDispatcher, self).catchable(dat)
00165 
00166 class TestTelemetryHandler(VscHandling.TelemetryHandler):
00167   def __init__(self):
00168     VscHandling.TelemetryHandler.__init__(self)
00169 
00170     self.handle(0x0,0xffff)
00171 
00172   def process(self, dat):
00173     packet = LICOS_VscTlmPacketFactory(dat)
00174     print "packet: %x" % packet.apid, packet.name  #, hexlify(packet.encode_packet())
00175 
00176 class SocketTelemetrySender(VscHandling.TelemetryHandler):
00177   """Send CCSDS packets over a socket to the Current Value Table
00178   """
00179   TIMEOUT=10
00180   CONNECT_MSG  = "ok CCSDS\n"
00181   def __init__(self, destSocket, apidLow, apidHigh):
00182     VscHandling.TelemetryHandler.__init__(self)
00183     self.handle(apidLow, apidHigh)
00184 
00185     self.__sock = destSocket
00186 
00187   def process(self, pkt):
00188     # print "STS: pkt"
00189     if self.__sock.isConnected():
00190       data = encodePacket(pkt)
00191       sendStr = struct.pack("!H", len(data)) + data
00192 
00193       try:
00194         self.__sock.send(sendStr)
00195       except:
00196         self.__sock.disconnect()
00197     else:
00198       log.debug("no connection, dumping packet on floor")
00199 
00200 
00201 def getip(hostname):
00202   """!\brief getip method.
00203 
00204   \param hostname Host name
00205 
00206   \return IP address
00207   """
00208   (name, alias, ipaddr_list) = socket.gethostbyname_ex(hostname)
00209   ipdotted = ipaddr_list[0]
00210   ips = socket.inet_aton(ipdotted)
00211   (ip,) = struct.unpack('!i', ips)
00212   return ip
00213 
00214 def encodePacket(pkt):
00215     # may want to move this to an external function.  **REVISIT** --JHP
00216     # create the packet header
00217     pkthdr = 0L
00218     pkthdr = pkthdr << 3
00219     pkthdr = pkthdr | pkt.version()
00220     pkthdr = pkthdr << 1
00221 #    pkthdr = pkthdr | pkt.isTelecommand()
00222     pkthdr = pkthdr << 1
00223     pkthdr = pkthdr | 0x1                  # secondary header
00224     pkthdr = pkthdr << 11
00225     pkthdr = pkthdr | pkt.apid()
00226     pkthdr = pkthdr << 2
00227     pkthdr = pkthdr | pkt.seqFlags()
00228     pkthdr = pkthdr << 14
00229     pkthdr = pkthdr | pkt.seqNum()
00230     pkthdr = pkthdr << 16
00231     pkthdr = pkthdr | pkt.length()
00232     pkthdr = pkthdr << 32
00233     pkthdr = pkthdr | pkt.secs()
00234     pkthdr = pkthdr << 32
00235     pkthdr = pkthdr | pkt.usecs()
00236 
00237     # marshall the packet header into a binary string
00238     pktstr = ''
00239     bitsleft = 112
00240     while bitsleft > 0:
00241       pktstr = struct.pack( 'B', pkthdr & 0xFF ) + pktstr
00242       pkthdr = pkthdr >> 8
00243       bitsleft = bitsleft - 8
00244 
00245     # append the packet payload data
00246     pktstr = pktstr + str( pkt.payload() )
00247     return pktstr
00248 
00249 class VscProxyLogger(object):
00250   def __init__(self, name):
00251     self.__name = name
00252 
00253   def write(self, buffer):
00254     if buffer == '\n': return
00255     t = time.strftime('%Y.%m.%d %H:%M:%S ', time.localtime())
00256     sys.__stdout__.write(t + self.__name + buffer + '\n')
00257 
00258   def flush(self):
00259     sys.__stdout__.flush()

Generated on Thu Apr 27 20:52:44 2006 for LICOS L02-01-00 by doxygen 1.4.6-NO