00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 __facility__ = "Online"
00017 __abstract__ = "File tools for ScriptEngine classes"
00018 __author__ = "J. Panetta <panetta@SLAC.Stanford.edu> SLAC - GLAST LAT I&T/Online"
00019 __date__ = "2005/11/1 00:08:27"
00020 __updated__ = "$Date: 2006/04/27 02:06:03 $"
00021 __version__ = "$Revision: 1.5 $"
00022 __release__ = "$Name: HEAD $"
00023 __credits__ = "SLAC"
00024
00025 import LICOS.copyright_SLAC
00026
00027 from LICOS.lib.cmdTlmDb.LCATcmdDb import LCATcmdDb
00028 from LICOS.lib.cmdTlmDb.LCATtlmDb import LCATtlmDb
00029 from LICOS.lib.cmdTlmDb.TelemetryEvent import TelemetryEvent
00030 from LICOS.lib.LATfunctions import utcfromtimestamp
00031
00032 import array
00033 import logging as log
00034 import os
00035 import struct
00036 import tempfile
00037 import time
00038
00039
00040
00041 FSW_DEVICE_BOOT = 0
00042 FSW_DEVICE_RAM = 1
00043 FSW_DEVICE_EE0 = 2
00044 FSW_DEVICE_EE1 = 3
00045 FSW_DEVICE_TMP = 4
00046 FSW_DEVICE_USR0 = 5
00047 FSW_DEVICE_USR1 = 6
00048 FSW_DEVICE_NAMES = ["boot", "ram", "ee0", "ee1", "tmp", "usr0", "usr1" ]
00049
00050 FSW_UNIT_SIU = 0
00051 FSW_UNIT_EPU0 = 1
00052 FSW_UNIT_EPU1 = 2
00053 FSW_UNIT_EPU2 = 3
00054 FSW_UNIT_EPU3 = 4
00055 FSW_UNIT_NAMES = [ 'SIU ', 'EPU0', 'EPU1', 'EPU2', 'EPU3' ]
00056
00057
00058
00059
00060 INT_DIR_LATC = 10
00061 INT_DIR_LCI = 11
00062
00063 FILETOOL_STANDARD_TIMEOUT = 60
00064
00065
00066 if os.name == 'posix':
00067 FILETOOL_TMP_PATH = "/tmp"
00068 else:
00069 FILETOOL_TMP_PATH = os.path.normpath(os.path.join('C:/', 'TEMP'))
00070
00071
00072 if os.name == 'posix':
00073 FILETOOL_HDR_ALLOW = True
00074 FSW_ADD_HEADER_CMD = 'file_hdr_prefix'
00075 FSW_COMPRESS_CMD = 'zcompress'
00076 else:
00077 FILETOOL_HDR_ALLOW = False
00078 FSW_ADD_HEADER_CMD = None
00079 FSW_COMPRESS_CMD = None
00080
00081
00082 FILETOOL_ARBITRARY_FILENUMBER = 0
00083
00084 FILETOOL_ARBITRARY_FMXID = 0x20000000L
00085
00086
00087 def arbitraryFileID(seed=None):
00088 """!\brief Retrieve a semi-arbitrary FSW file Number to be used as input for FswFileID()
00089
00090 \return an integer
00091 """
00092 global FILETOOL_ARBITRARY_FILENUMBER
00093 if seed is not None:
00094 FILETOOL_ARBITRARY_FILENUMBER = seed
00095
00096 if FILETOOL_ARBITRARY_FILENUMBER > FswFileID.MASK_FILENUM:
00097 FILETOOL_ARBITRARY_FILENUMBER = 0
00098 id = FILETOOL_ARBITRARY_FILENUMBER
00099 FILETOOL_ARBITRARY_FILENUMBER += 1
00100 return id
00101
00102 def arbitraryFmxID(seed=None):
00103 """!\brief Retrieve a semi-arbitrary FMX id to be used in creating an FMX header on the fly
00104
00105 \return an integer
00106 """
00107 global FILETOOL_ARBITRARY_FMXID
00108 if seed is not None:
00109 FILETOOL_ARBITRARY_FMXID = seed
00110 id = FILETOOL_ARBITRARY_FMXID
00111 FILETOOL_ARBITRARY_FMXID += 1
00112 return id
00113
00114 class FswFile(object):
00115 """!\brief Functional interface to a generic file in FSW
00116 """
00117 def __init__(self, fid, bin, uploaded=False):
00118 """!\brief Constructor
00119
00120 \param fid FswFileID for this file
00121 \param bin Raw binary representation of file
00122 \param uploaded True if file has been uploaded
00123 """
00124 self.__fid = fid
00125 self.__bin = bin
00126 self.__uploaded = False
00127
00128 def fileID(self):
00129 """!\brief retrieve file ID
00130
00131 \return a FswFileID object
00132 """
00133 return self.__fid
00134
00135 def binary(self):
00136 """!\brief retrieve file data
00137
00138 \return a raw binary string
00139 """
00140 return self.__bin
00141
00142 def uploaded(self):
00143 """!\brief retrieve file upload status
00144
00145 \return True if uploaded
00146 """
00147 return self.__uploaded
00148
00149 def setUploaded(self, bool):
00150 """!\brief Set file upload status
00151
00152 \param bool True if file is uploaded
00153 """
00154 self.__uploaded = bool
00155
00156 def write(self, stream):
00157 """!\brief write file to stream (file descriptor)
00158
00159 \param stream Any writable file descriptor
00160 """
00161 stream.write(self.__bin)
00162 stream.flush()
00163
00164 class FswFileFromData(FswFile):
00165 """!\brief A memory resident FSW file interface
00166 """
00167 def __init__(self, fileID, fileDat, uploaded=False):
00168 """!\brief Constructor
00169
00170 \param fileID FswFileID for this file
00171 \param fileDat The file's raw data
00172 \param uploaded True if file has been uploaded
00173 """
00174 try:
00175 FswFile.__init__(self, fileID, fileDat, uploaded)
00176 except:
00177 raise
00178
00179 class FswFileFromDisk(FswFile):
00180 """!\brief A disk resident FSW file interface
00181 """
00182 def __init__(self, fileID, fileName, uploaded=False):
00183 """!\brief Constructor
00184
00185 \param fileID FswFileID for this file
00186 \param fileName A fully qualified file name to open
00187 \param uploaded True if file has been uploaded
00188 """
00189 self.name = fileName
00190 try:
00191 self.file = open(fileName, 'rb')
00192 bin = self.file.read()
00193
00194
00195 FswFile.__init__(self, fileID, bin, uploaded)
00196 except Exception, e:
00197 raise
00198
00199 class FswFileID(object):
00200 """!\brief Define a Flight Software File ID
00201
00202 Defines the FSW file id, as specified in the FILE FSW traveler document
00203 """
00204 MASK_DEVICE = 0x7
00205 MASK_DIRECTORY = 0x7F
00206 MASK_FILENUM = 0x3FFFFF
00207 SHFT_DEVICE = 29
00208 SHFT_DIRECTORY = 22
00209 SHFT_FILENUM = 0
00210 def __init__(self, *argv, **argd):
00211 """!\brief Polymorphic constructor
00212
00213 Takes 1 or 3 arguments {fileID} or {device,directory,fileNumber}
00214 Arguments can be either named or not. A mix of both named and unnamed
00215 args is verboten.
00216
00217 \param fileID A LAT file ID (32 bit packed)
00218
00219 \param device Device to store file to [0..7]
00220 \param directory Directory to store file to [0..0x7F]
00221 \param fileNumber File Number [0..0x3FFFFF]
00222 """
00223 if len(argv) == 1:
00224 self.__fid = argv[0]
00225 elif len(argv) == 3:
00226 self.__fid = self.__computeFileID(argv[0], argv[1], argv[2])
00227 elif len(argd) == 1:
00228 self.__fid = argd['fileID']
00229 elif len(argd) == 3:
00230 self.__fid = self.__computeFileID( argd['device'], argd['directory'], argd['fileNumber'] )
00231 else:
00232 raise SyntaxError( "Incorrect arguments for FswFileID constructor: argv=%s, argd=%d" % (str(argv), str(argd)) )
00233
00234 def __computeFileID(self, device, directory, filNum):
00235 """!\brief Compute the 32 bit FSW destination from component parts
00236 """
00237 if device & self.MASK_DEVICE != device:
00238 raise "Selected device number 0x%x is greater than the maximum of 0x7" % device
00239 if directory & self.MASK_DIRECTORY != directory:
00240 raise "Selected directory number 0x%x is greater than the maximum of 0x7F" % directory
00241 if filNum & self.MASK_FILENUM != filNum:
00242 raise "Selected file number 0x%x is greater than the maximum of 0x3fffff" % filNum
00243
00244 dest = (device << self.SHFT_DEVICE) + \
00245 (directory << self.SHFT_DIRECTORY) + \
00246 (filNum << self.SHFT_FILENUM)
00247 return dest
00248
00249 def id(self):
00250 """!\brief retrieve file ID
00251
00252 \return 32 bit file ID
00253 """
00254 return self.__fid
00255
00256 def device(self):
00257 """!\brief retrieve device
00258
00259 \return 3 bit device
00260 """
00261 return (self.__fid >> self.SHFT_DEVICE ) & self.MASK_DEVICE
00262
00263 def directory(self):
00264 """!\brief retrieve file ID
00265
00266 \return 7 bit directory
00267 """
00268 return (self.__fid >> self.SHFT_DIRECTORY ) & self.MASK_DIRECTORY
00269
00270 def fileNumber(self):
00271 """!\brief retrieve file ID
00272
00273 \return 22 bit file Number
00274 """
00275 return (self.__fid >> self.SHFT_FILENUM ) & self.MASK_FILENUM
00276
00277 def __str__(self):
00278 return '/%s/d%03d/f%07d' % \
00279 ( FSW_DEVICE_NAMES[self.device()], self.directory(), self.fileNumber())
00280
00281
00282 class FswDirectoryItem(object):
00283 """!\brief Representation of an item in an FSW directory
00284
00285 REVISIT: Make the members private and member functions?
00286 """
00287 __isdirTxt = [ '-', 'd' ]
00288 __roTxt = [ 'w', '-' ]
00289 def __init__(self, fileID, ro, size, isdir, time, unit, blocks):
00290 """!\ Constructor
00291
00292 \param fileID A FswFileID object
00293 \param ro file is ReadOnly flag (True/False)
00294 \param size File size in bytes
00295 \param isdir file is a directory flag (True/False)
00296 \param time File modification time in LAT epoch
00297 \param unit File unit (i.e. FSW_UNIT_SIU)
00298 \param blocks REVISIT:: file blocks, maybe unused?
00299 """
00300 self.id = fileID
00301 self.ro = ro
00302 self.size = size
00303 self.isdir = isdir
00304 self.time = time
00305 self.unit = unit
00306 self.blocks = blocks
00307
00308 def dump(self, stream):
00309 """!\brief dump a directoryItem to a file descriptor.
00310
00311 \param stream Any file descriptor (ie. sys.stdout)
00312 """
00313 msg = ""
00314 msg += self.__isdirTxt[self.isdir]
00315 msg += 'r' # always readable
00316 msg += self.__roTxt[self.ro]
00317 msg += ' %4s' % FSW_UNIT_NAMES[self.unit]
00318 msg += ' %10d' % self.size
00319 msg += ' %s' % utcfromtimestamp(int(self.time), 0).ctime()
00320 strid = str(self.id)
00321 if self.isdir: strid = strid[:-8]
00322 msg += ' %s' % strid
00323 print >> stream, msg
00324
00325
00326 class FswDirectory(object):
00327 """!\brief Representation of a FSW directory
00328
00329 """
00330 def __init__(self, dirID):
00331 """!\ Constructor
00332
00333 \param dirID A FswFileID object
00334 """
00335 self.__id = dirID
00336 self.__files = []
00337
00338 def addItem(self, f):
00339 """!\brief Add a file to this representation
00340
00341 \param f An FswDirectoryItem
00342 """
00343 if f not in self.__files:
00344 self.__files.append(f)
00345
00346 def files(self):
00347 """!\brief return a list of all files in this directory rep
00348 """
00349 return self.__files
00350
00351 def id(self):
00352 """!\brief retrieve file ID
00353
00354 \return a FswFileID object
00355 """
00356 return self.__id
00357
00358 def setId(self, id):
00359 """!\brief set the ID for this directory
00360
00361 \param id A FswFileID object
00362 """
00363 self.__id = id
00364
00365 def dump(self, stream):
00366 """!\brief dump a directory to a file descriptor
00367
00368 \param stream Any file descriptor (ie. sys.stdout)
00369 """
00370 msg = '/%s/d%03d' % ( FSW_DEVICE_NAMES[self.id().device()], self.id().directory())
00371 print >> stream, msg
00372 for item in self.__files:
00373 item.dump(stream)
00374
00375 def addFmxHeader(inFile, doCompress=False, preCompressed=False, name=None,
00376 type=None, key=None, timestamp=None):
00377 """!\brief Add an fmx header to a file. compressing on the fly if requested
00378
00379 \param inFile An FswFile object
00380 \param doCompress True/False to compress on fly/not
00381 \param preCompressed True/False if already compressed
00382 \param name
00383 \param type
00384 \param key
00385 \param timestamp
00386
00387 \return An FswFile object with proper headers for upload
00388 """
00389 if not FILETOOL_HDR_ALLOW:
00390 raise RuntimeError('Adding an FMX header is not possible on non-unix systems')
00391
00392 hdrCmd = FSW_ADD_HEADER_CMD
00393 if hasattr(inFile, 'name'):
00394 rawFile = inFile
00395 else:
00396 rawFile = tempfile.NamedTemporaryFile(mode='w+b')
00397 inFile.write(rawFile.file)
00398 hdrFile = tempfile.NamedTemporaryFile(mode='w+b')
00399
00400
00401 if doCompress:
00402
00403 cmpFile = tempfile.NamedTemporaryFile(mode='w+b')
00404
00405 cmd = FSW_COMPRESS_CMD
00406 cmd += ' %s' % rawFile.name
00407 cmd += ' %s' % cmpFile.name
00408 rc = os.system(cmd)
00409 rawFile = cmpFile
00410 if doCompress or preCompressed:
00411 hdrCmd += ' -c'
00412
00413
00414 if name is not None:
00415 hdrCmd += ' -n=%s' % name
00416 if type is not None:
00417 hdrCmd += ' -t=%s' % str(type)
00418 if key is not None:
00419 hdrCmd += ' -k=%s' % str(key)
00420 if timestamp is not None:
00421 hdrCmd += ' -s=%s' % str(timestamp)
00422
00423 hdrCmd += ' %s' % rawFile.name
00424 hdrCmd += ' %s' % hdrFile.name
00425 rc = os.system(hdrCmd)
00426
00427 retFile = FswFileFromDisk(inFile.fileID(), hdrFile.name)
00428
00429 return retFile
00430
00431
00432
00433
00434
00435
00436
00437 def downloadFile(app, unit, fileID):
00438 """!\brief Download a file from the LAT
00439
00440 \param app A testAppBase object (your user application...)
00441 \param unit LAT unit id to upload to
00442 \param fileID An FswFileID object
00443 \return An FswFile object containing the data uploaded
00444 """
00445 class FileDump(object):
00446 def __init__(self, app):
00447 self.__app = app
00448 self.__fragments = {}
00449 self.__dumpSizes = {}
00450 self.__expectedID = None
00451 self.__dumpCTDBtelem = TelemetryEvent(app.getDiagHandler(),
00452 [app.lcatTlm.getApidFromName('LLFSDUMPCTDB')],
00453 self.dumpCTDB)
00454 def dumpCTDB(self, telemetry):
00455
00456
00457 pkt = self.__app.lcatTlm.decodeTelemetry(telemetry)
00458 offset = pkt.get_payload("LFSFDMPOFFSET")
00459 dumpSize = pkt.get_payload("LFSFDMPSIZE")
00460
00461 dumpDev = pkt.get_payload("LFSDMPDEV")
00462 dumpDir = pkt.get_payload("LFSDMPDIR")
00463 dumpFile = pkt.get_payload("LFSDMPFILE")
00464 if dumpDev != self.__expectedID.device() or \
00465 dumpDir != self.__expectedID.directory() or \
00466 dumpFile != self.__expectedID.dumpFile():
00467 msg = "CTDB dump resulted in unexpected file: %s, expected %s" % \
00468 ( str(FswFileID(dumpDev, dumpDir, dumpFile)), self.__expectedID )
00469 raise RuntimeError(msg)
00470
00471
00472 dataMnems = ['LFSFDMPDATA%d' % i for i in xrange(390)]
00473 self.__fragments[offset] = ''.join(map(chr, map(pkt.get_payload, dataMnems)))
00474 self.__dumpSizes[offset] = dumpSize
00475
00476 def dump(self, unit, fileID):
00477 self.__expectedID = fileID
00478 self.__dumpCTDBtelem.enable()
00479 LFS = self.__app.lcat.LFS
00480 LFS.LFSFILEDUMPC( LFSFILEID=fileID.id(), LFSUNIT=unit, LFSPAD16=0 )
00481 self.__app.waitForConfirmation(timeout = FILETOOL_STANDARD_TIMEOUT)
00482 offsets = self.__fragments.keys()
00483 offsets.sort()
00484 binary = ""
00485 for o in offsets:
00486 binary += self.__fragments[o][:self.__dumpSizes[o]]
00487
00488 self.__dumpCTDBtelem.disable()
00489
00490 return FswFileFromData(fileID, binary, uploaded=True)
00491
00492 fd = FileDump(app)
00493
00494 fswFile = fd.dump(unit, fileID)
00495
00496 return fswFile
00497
00498 def downloadFileToSSR(app, unit, fileID):
00499 """!\brief Download a file from the LAT
00500
00501 \param app A testAppBase object (your user application...)
00502 \param unit LAT unit id to upload to
00503 \param fileID An FswFileID object
00504 \return status
00505 """
00506 LFS.LFSFILEDUMPS( LFSFILEID=fileID.id(), LFSunit=unit, LFSPAD16=0 )
00507 status = __checkLastCommandStatus(app)
00508 return status
00509
00510
00511 def uploadFileFromDisk(app, fileName, unit, fileID):
00512 """!\brief Upload a disk resident file with an FMX header
00513
00514 \param app A testAppBase object (your user application...)
00515 \param fileName Fully qualified file name
00516 \param unit LAT unit id to upload to
00517 \param fileID An FswFileID object
00518 \return An FswFile object containing the data uploaded
00519 """
00520 uplFile = None
00521 try:
00522 uplFile = FswFileFromDisk(fileID, fileName)
00523 except:
00524 raise
00525 else:
00526 uploadFile(app, uplFile, unit)
00527 return uplFile
00528
00529 def uploadFileFromData(app, fileData, unit, fileID):
00530 """!\brief Upload a memory resident file with an FMX header (Typically received from MOOT)
00531
00532 \param app A testAppBase object (your user application...)
00533 \param fileData Binary representation of an FMX file
00534 \param unit LAT unit id to upload to
00535 \param fileID An FswFileID object
00536 \return An FswFile object containing the data uploaded
00537 """
00538 uplFile = None
00539 try:
00540 uplFile = FswFileFromData(fileID, fileData)
00541 except:
00542 raise
00543 else:
00544 uploadFile(app, uplFile, unit)
00545 return uplFile
00546
00547 def cancelUpload(app, unit):
00548 """!\brief cancel any in process uploads
00549
00550 \param app A testAppBase object (your user application...)
00551 \param fswFile FswFile object
00552 \param unit LAT unit id to upload to
00553 \return status
00554 """
00555 app.lcat.FILE.LFILUPLCANCEL(LFILEUNIT=unit)
00556 status = __checkLastCommandStatus(app)
00557 return status
00558
00559 def uploadFile(app, fswFile, unit):
00560 """!\brief Upload a memory resident fsw file object
00561
00562 \param app A testAppBase object (your user application...)
00563 \param fswFile FswFile object
00564 \param unit LAT unit id to upload to
00565 """
00566
00567
00568
00569
00570
00571
00572
00573 fileID = fswFile.fileID()
00574 uplStr = fswFile.binary()
00575
00576
00577 status = cancelUpload(app, unit)
00578 if not status:
00579 raise RuntimeError("Recieved bad status from cancelUpload. Check previous warning.")
00580
00581
00582
00583
00584
00585 dumpSize = len(fswFile.binary())
00586 d,m = divmod(dumpSize, 48)
00587 if m != 0:
00588 d += 1
00589 app.lcat.FILE.LFILUPLSTART(LFILESIZE=d*48)
00590 status = __checkLastCommandStatus(app)
00591 if not status:
00592 raise RuntimeError("Recieved bad status from upload start. Check previous warning.")
00593
00594
00595 nDataBytes = 48
00596 chunk = 0
00597 offset = 0
00598 lastpacket = dumpSize // nDataBytes - 1
00599 while True:
00600 offset = chunk*nDataBytes
00601 if offset >= dumpSize:
00602 break
00603 if lastpacket > 0:
00604 if chunk == 0:
00605 seqFlags = 0x1
00606 elif chunk == lastpacket:
00607 seqFlags = 0x2
00608 else:
00609 seqFlags = 0x0
00610 else:
00611 seqFlags = 0x3
00612 app.lcat.FILE.getCmdObj('LFILUPLDATA').seqFlags = seqFlags
00613 __uploadChunk(app, uplStr[offset:offset+nDataBytes], offset, nDataBytes)
00614 chunk += 1
00615
00616 app.lcat.FILE.LFILUPLCOMMIT(LFILEUNIT=unit,
00617 LFILEFLAGS=0,
00618 LFILEID=fileID.id())
00619 status = __checkLastCommandStatus(app)
00620 if not status:
00621 raise RuntimeError("Received bad status from File Upload Commit. Check previous warning")
00622
00623
00624
00625 fswFile.setUploaded(True)
00626 return status
00627
00628
00629 def __uploadChunk(app, uplChunk, offset, nDataBytes):
00630 lChunk = len(uplChunk)
00631 if lChunk > nDataBytes:
00632 raise ValueError, "Length of a chunk can't be greater than %d bytes" % nDataBytes
00633
00634 uplChunk = uplChunk + ( chr(0) * (nDataBytes-lChunk) )
00635 app.lcat.FILE.LFILUPLDATA(offset, *array.array('B',uplChunk).tolist())
00636
00637
00638
00639
00640
00641 def dumpDirectory(app, unit, directoryID, root=False):
00642 """!\brief Download a directory listing from the LAT
00643
00644 \param app A testAppBase object (your user application...)
00645 \param unit LAT unit id to upload to
00646 \param fileID An FswFileID object with the correct directory set.
00647 \return An FswFile object containing the data uploaded
00648 """
00649 class DirDump(object):
00650 def __init__(self, app, root):
00651 self.__app = app
00652 self.__root = root
00653 self.__rep = None
00654 self.__dumpSizes = {}
00655 if self.__root:
00656 wantedPacket = "LLFSROOTLIST"
00657 else:
00658 wantedPacket = "LLFSDIRLIST"
00659
00660
00661 self.__dumpDirTelem = TelemetryEvent(app.getDiagHandler(),
00662 [app.lcatTlm.getApidFromName(wantedPacket)],
00663 self.getPackets)
00664 def getPackets(self, telemetry):
00665 try:
00666 pkt = self.__app.lcatTlm.decodeTelemetry(telemetry)
00667 if self.__root:
00668 prefix = 'LFSRDMPF'
00669 else:
00670 prefix = 'LFSDDMP'
00671
00672 device = pkt.get_payload( prefix + "DEV" )
00673 directory = pkt.get_payload( prefix + "DIR" )
00674 fileNum = pkt.get_payload( prefix + "FILE" )
00675
00676 if self.__root:
00677 prefix = prefix[:-1]
00678
00679 ro = pkt.get_payload( prefix + "ROFLG")
00680 size = pkt.get_payload( prefix + "SIZE")
00681 isdir = pkt.get_payload( prefix + "DIRFLG")
00682 t = pkt.get_payload( prefix + "TIME")
00683 u = pkt.get_payload( prefix + "UNIT")
00684 blocks = 0
00685
00686 self.__rep.addItem( FswDirectoryItem(FswFileID(device, directory, fileNum),
00687 ro, size, isdir, t, u, blocks) )
00688
00689 except Exception, e:
00690 print e
00691 raise
00692
00693 def dump(self, unit, dirID):
00694 self.__rep = FswDirectory( dirID=dirID )
00695 self.__dumpDirTelem.enable()
00696 self.__app.lcat.LFS.LFSDIRDUMP(LFSFILEID=dirID.id(),
00697 LFSUNIT=unit,
00698 LFSPAD16=0)
00699 self.__app.waitForConfirmation(timeout = FILETOOL_STANDARD_TIMEOUT)
00700 self.__dumpDirTelem.disable()
00701
00702 return self.__rep
00703
00704 dd = DirDump(app, root)
00705 dirRep = dd.dump(unit, directoryID)
00706 return dirRep
00707
00708 def createDirectory(app, unit, directoryID):
00709 """!\brief create a directory on a LAT file system
00710
00711 \param app A testAppBase object (your user application...)
00712 \param unit LAT unit id
00713 \param fileID An FswFileID object with the correct directory set.
00714 \return status True if it worked, False if not.
00715 """
00716 app.lcat.LFS.LFSDIRCREATE(LFSUNIT=unit,
00717 LFSFILEID=directoryID.id(),
00718 LFSPAD16=0)
00719 status = app.waitForConfirmation(timeout = FILETOOL_STANDARD_TIMEOUT)
00720 return status
00721
00722 def deleteDirectory(app, unit, directoryID, force=False):
00723 """!\brief Delete a directory on a LAT filesystem
00724
00725 \param app A testAppBase object (your user application...)
00726 \param unit LAT unit id to upload to
00727 \param directoryID An FswFileID object with the correct directory set.
00728 \return status True if success, False if failure
00729 """
00730 status = True
00731 if force:
00732
00733 dirRep = dumpDirectory(app, unit, directoryID)
00734 for f in dirRep.files():
00735 status = deleteFile(app, unit, f.id)
00736 if not status:
00737 break
00738 if status:
00739
00740 app.lcat.LFS.LFSDIRDELETE(LFSUNIT=unit,
00741 LFSFILEID=directoryID.id(),
00742 LFSPAD16=0)
00743 status = __checkLastCommandStatus(app)
00744 return status
00745
00746 def deleteFile(app, unit, fileID):
00747 """!\brief Delete a file on a LAT filesystem
00748
00749 \param app A testAppBase object (your user application...)
00750 \param unit LAT unit id to upload to
00751 \param fileID An FswFileID object
00752 \return status True if success, False if failure
00753 """
00754 app.lcat.LFS.LFSFILEDELETE(LFSUNIT=unit,
00755 LFSFILEID=fileID.id(),
00756 LFSPAD16=0)
00757 status = __checkLastCommandStatus(app)
00758 return status
00759
00760 def copyFile(app, unit, source, dest):
00761 """!\brief Copy a file on any LAT unit
00762
00763 \param app A testAppBase object (your user application...)
00764 \param unit LAT unit id to upload to
00765 \param source An FswFileID object corresponding to the source file
00766 \param dest An FswFileID object corresponding to the destination file
00767 \return status True if success, False if failure
00768 """
00769 status = True
00770 app.lcat.LFS.LFSFILECOPY(LFSUNIT=unit,
00771 LFSSRCFILEID=source.id(),
00772 LFSDESTFILEID=dest.id(),
00773 LFSPAD16=0)
00774 status = __checkLastCommandStatus(app)
00775
00776 return status
00777
00778 def __checkLastCommandStatus(app):
00779
00780
00781 status = True
00782 status = app.waitForConfirmation(timeout = FILETOOL_STANDARD_TIMEOUT)
00783 statusMsg = app.getConfirmationMsg()
00784 if not app.lcatTlm.msgIsSuccess(statusMsg):
00785 log.warning(app.lcatTlm.msgByValue(statusMsg))
00786 status=False
00787 return status
00788