Package ais :: Module ais_msg_10
[hide private]
[frames] | no frames]

Source Code for Module ais.ais_msg_10

  1  #!/usr/bin/env python 
  2   
  3  __version__ = '$Revision: 4791 $'.split()[1] 
  4  __date__ = '$Date: 2007-03-31 $'.split()[1] 
  5  __author__ = 'xmlbinmsg' 
  6   
  7  __doc__=''' 
  8   
  9  Autogenerated python functions to serialize/deserialize binary messages. 
 10   
 11  Generated by: ./aisxmlbinmsg2py.py 
 12   
 13  Need to then wrap these functions with the outer AIS packet and then 
 14  convert the whole binary blob to a NMEA string.  Those functions are 
 15  not currently provided in this file. 
 16   
 17  serialize: python to ais binary 
 18  deserialize: ais binary to python 
 19   
 20  The generated code uses translators.py, binary.py, and aisstring.py 
 21  which should be packaged with the resulting files. 
 22   
 23   
 24  @requires: U{epydoc<http://epydoc.sourceforge.net/>} > 3.0alpha3 
 25  @requires: U{BitVector<http://cheeseshop.python.org/pypi/BitVector>} 
 26   
 27  @author: '''+__author__+''' 
 28  @version: ''' + __version__ +''' 
 29  @var __date__: Date of last svn commit 
 30  @undocumented: __version__ __author__ __doc__ parser 
 31  @status: under development 
 32  @license: Generated code has no license 
 33  @todo: FIX: put in a description of the message here with fields and types. 
 34  ''' 
 35   
 36  import sys 
 37  from decimal import Decimal 
 38  from BitVector import BitVector 
 39   
 40  import binary, aisstring 
 41   
 42  # FIX: check to see if these will be needed 
 43  TrueBV  = BitVector(bitstring="1") 
 44  "Why always rebuild the True bit?  This should speed things up a bunch" 
 45  FalseBV = BitVector(bitstring="0") 
 46  "Why always rebuild the False bit?  This should speed things up a bunch" 
 47   
 48   
 49  fieldList = ( 
 50          'MessageID', 
 51          'RepeatIndicator', 
 52          'UserID', 
 53          'Spare1', 
 54          'DestID', 
 55          'Spare2', 
 56  ) 
 57   
 58  fieldListPostgres = ( 
 59          'MessageID', 
 60          'RepeatIndicator', 
 61          'UserID', 
 62          'Spare1', 
 63          'DestID', 
 64          'Spare2', 
 65  ) 
 66   
 67  toPgFields = { 
 68  } 
 69  ''' 
 70  Go to the Postgis field names from the straight field name 
 71  ''' 
 72   
 73  fromPgFields = { 
 74  } 
 75  ''' 
 76  Go from the Postgis field names to the straight field name 
 77  ''' 
 78   
 79  pgTypes = { 
 80  } 
 81  ''' 
 82  Lookup table for each postgis field name to get its type. 
 83  ''' 
 84   
85 -def encode(params, validate=False):
86 '''Create a utcquery binary message payload to pack into an AIS Msg utcquery. 87 88 Fields in params: 89 - MessageID(uint): AIS message number. Must be 10 (field automatically set to "10") 90 - RepeatIndicator(uint): Indicated how many times a message has been repeated 91 - UserID(uint): Unique ship identification number (MMSI) 92 - Spare1(uint): Not used. Should be set to zero. (field automatically set to "0") 93 - DestID(uint): Unique ship identification number (MMSI) 94 - Spare2(uint): Not used. Should be set to zero. (field automatically set to "0") 95 @param params: Dictionary of field names/values. Throws a ValueError exception if required is missing 96 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 97 @rtype: BitVector 98 @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 99 @note: The returned bits may not be 6 bit aligned. It is up to you to pad out the bits. 100 ''' 101 102 bvList = [] 103 bvList.append(binary.setBitVectorSize(BitVector(intVal=10),6)) 104 if 'RepeatIndicator' in params: 105 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['RepeatIndicator']),2)) 106 else: 107 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 108 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['UserID']),30)) 109 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 110 bvList.append(binary.setBitVectorSize(BitVector(intVal=params['DestID']),30)) 111 bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 112 113 return binary.joinBV(bvList)
114
115 -def decode(bv, validate=False):
116 '''Unpack a utcquery message 117 118 Fields in params: 119 - MessageID(uint): AIS message number. Must be 10 (field automatically set to "10") 120 - RepeatIndicator(uint): Indicated how many times a message has been repeated 121 - UserID(uint): Unique ship identification number (MMSI) 122 - Spare1(uint): Not used. Should be set to zero. (field automatically set to "0") 123 - DestID(uint): Unique ship identification number (MMSI) 124 - Spare2(uint): Not used. Should be set to zero. (field automatically set to "0") 125 @type bv: BitVector 126 @param bv: Bits defining a message 127 @param validate: Set to true to cause checking to occur. Runs slower. FIX: not implemented. 128 @rtype: dict 129 @return: params 130 ''' 131 132 #Would be nice to check the bit count here.. 133 #if validate: 134 # assert (len(bv)==FIX: SOME NUMBER) 135 r = {} 136 r['MessageID']=10 137 r['RepeatIndicator']=int(bv[6:8]) 138 r['UserID']=int(bv[8:38]) 139 r['Spare1']=0 140 r['DestID']=int(bv[40:70]) 141 r['Spare2']=0 142 return r
143
144 -def decodeMessageID(bv, validate=False):
145 return 10
146
147 -def decodeRepeatIndicator(bv, validate=False):
148 return int(bv[6:8])
149
150 -def decodeUserID(bv, validate=False):
151 return int(bv[8:38])
152
153 -def decodeSpare1(bv, validate=False):
154 return 0
155
156 -def decodeDestID(bv, validate=False):
157 return int(bv[40:70])
158
159 -def decodeSpare2(bv, validate=False):
160 return 0
161 162
163 -def printHtml(params, out=sys.stdout):
164 out.write("<h3>utcquery<h3>\n") 165 out.write("<table border=\"1\">\n") 166 out.write("<tr bgcolor=\"orange\">\n") 167 out.write("<th align=\"left\">Field Name</th>\n") 168 out.write("<th align=\"left\">Type</th>\n") 169 out.write("<th align=\"left\">Value</th>\n") 170 out.write("<th align=\"left\">Value in Lookup Table</th>\n") 171 out.write("<th align=\"left\">Units</th>\n") 172 out.write("\n") 173 out.write("<tr>\n") 174 out.write("<td>MessageID</td>\n") 175 out.write("<td>uint</td>\n") 176 if 'MessageID' in params: 177 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 178 out.write(" <td>"+str(params['MessageID'])+"</td>\n") 179 out.write("</tr>\n") 180 out.write("\n") 181 out.write("<tr>\n") 182 out.write("<td>RepeatIndicator</td>\n") 183 out.write("<td>uint</td>\n") 184 if 'RepeatIndicator' in params: 185 out.write(" <td>"+str(params['RepeatIndicator'])+"</td>\n") 186 if str(params['RepeatIndicator']) in RepeatIndicatorDecodeLut: 187 out.write("<td>"+RepeatIndicatorDecodeLut[str(params['RepeatIndicator'])]+"</td>") 188 else: 189 out.write("<td><i>Missing LUT entry</i></td>") 190 out.write("</tr>\n") 191 out.write("\n") 192 out.write("<tr>\n") 193 out.write("<td>UserID</td>\n") 194 out.write("<td>uint</td>\n") 195 if 'UserID' in params: 196 out.write(" <td>"+str(params['UserID'])+"</td>\n") 197 out.write(" <td>"+str(params['UserID'])+"</td>\n") 198 out.write("</tr>\n") 199 out.write("\n") 200 out.write("<tr>\n") 201 out.write("<td>Spare1</td>\n") 202 out.write("<td>uint</td>\n") 203 if 'Spare1' in params: 204 out.write(" <td>"+str(params['Spare1'])+"</td>\n") 205 out.write(" <td>"+str(params['Spare1'])+"</td>\n") 206 out.write("</tr>\n") 207 out.write("\n") 208 out.write("<tr>\n") 209 out.write("<td>DestID</td>\n") 210 out.write("<td>uint</td>\n") 211 if 'DestID' in params: 212 out.write(" <td>"+str(params['DestID'])+"</td>\n") 213 out.write(" <td>"+str(params['DestID'])+"</td>\n") 214 out.write("</tr>\n") 215 out.write("\n") 216 out.write("<tr>\n") 217 out.write("<td>Spare2</td>\n") 218 out.write("<td>uint</td>\n") 219 if 'Spare2' in params: 220 out.write(" <td>"+str(params['Spare2'])+"</td>\n") 221 out.write(" <td>"+str(params['Spare2'])+"</td>\n") 222 out.write("</tr>\n") 223 out.write("</table>\n")
224
225 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'):
226 '''Print a utcquery message to stdout. 227 228 Fields in params: 229 - MessageID(uint): AIS message number. Must be 10 (field automatically set to "10") 230 - RepeatIndicator(uint): Indicated how many times a message has been repeated 231 - UserID(uint): Unique ship identification number (MMSI) 232 - Spare1(uint): Not used. Should be set to zero. (field automatically set to "0") 233 - DestID(uint): Unique ship identification number (MMSI) 234 - Spare2(uint): Not used. Should be set to zero. (field automatically set to "0") 235 @param params: Dictionary of field names/values. 236 @param out: File like object to write to 237 @rtype: stdout 238 @return: text to out 239 ''' 240 241 if 'std'==format: 242 out.write("utcquery:\n") 243 if 'MessageID' in params: out.write(" MessageID: "+str(params['MessageID'])+"\n") 244 if 'RepeatIndicator' in params: out.write(" RepeatIndicator: "+str(params['RepeatIndicator'])+"\n") 245 if 'UserID' in params: out.write(" UserID: "+str(params['UserID'])+"\n") 246 if 'Spare1' in params: out.write(" Spare1: "+str(params['Spare1'])+"\n") 247 if 'DestID' in params: out.write(" DestID: "+str(params['DestID'])+"\n") 248 if 'Spare2' in params: out.write(" Spare2: "+str(params['Spare2'])+"\n") 249 elif 'csv'==format: 250 if None == options.fieldList: 251 options.fieldList = fieldList 252 needComma = False; 253 for field in fieldList: 254 if needComma: out.write(',') 255 needComma = True 256 if field in params: 257 out.write(str(params[field])) 258 # else: leave it empty 259 out.write("\n") 260 elif 'html'==format: 261 printHtml(params,out) 262 elif 'sql'==format: 263 sqlInsertStr(params,out,dbType=dbType) 264 else: 265 print "ERROR: unknown format:",format 266 assert False 267 268 return # Nothing to return
269 270 RepeatIndicatorEncodeLut = { 271 'default':'0', 272 'do not repeat any more':'3', 273 } #RepeatIndicatorEncodeLut 274 275 RepeatIndicatorDecodeLut = { 276 '0':'default', 277 '3':'do not repeat any more', 278 } # RepeatIndicatorEncodeLut 279 280 ###################################################################### 281 # SQL SUPPORT 282 ###################################################################### 283
284 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 285 ,addCoastGuardFields=True 286 ,dbType='postgres' 287 ):
288 ''' 289 Return the SQL CREATE command for this message type 290 @param outfile: file like object to print to. 291 @param fields: which fields to put in the create. Defaults to all. 292 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 293 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 294 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 295 @type addCoastGuardFields: bool 296 @return: sql create string 297 @rtype: str 298 299 @see: sqlCreate 300 ''' 301 # FIX: should this sqlCreate be the same as in LaTeX (createFuncName) rather than hard coded? 302 outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType)))
303
304 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'):
305 ''' 306 Return the sqlhelp object to create the table. 307 308 @param fields: which fields to put in the create. Defaults to all. 309 @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 310 @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 311 @type addCoastGuardFields: bool 312 @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 313 @return: An object that can be used to generate a return 314 @rtype: sqlhelp.create 315 ''' 316 if None == fields: fields = fieldList 317 import sqlhelp 318 c = sqlhelp.create('utcquery',dbType=dbType) 319 c.addPrimaryKey() 320 if 'MessageID' in fields: c.addInt ('MessageID') 321 if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 322 if 'UserID' in fields: c.addInt ('UserID') 323 if 'Spare1' in fields: c.addInt ('Spare1') 324 if 'DestID' in fields: c.addInt ('DestID') 325 if 'Spare2' in fields: c.addInt ('Spare2') 326 327 if addCoastGuardFields: 328 # c.addInt('cg_rssi') # Relative signal strength indicator 329 # c.addInt('cg_d') # dBm receive strength 330 # c.addInt('cg_T') # Receive timestamp from the AIS equipment 331 # c.addInt('cg_S') # Slot received in 332 # c.addVarChar('cg_x',10) # Idonno 333 c.addVarChar('cg_r',15) # Receiver station ID - should usually be an MMSI, but sometimes is a string 334 c.addInt('cg_sec') # UTC seconds since the epoch 335 336 c.addTimestamp('cg_timestamp') # UTC decoded cg_sec - not actually in the data stream 337 338 return c
339
340 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'):
341 ''' 342 Return the SQL INSERT command for this message type 343 @param params: dictionary of values keyed by field name 344 @param outfile: file like object to print to. 345 @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 346 @return: sql create string 347 @rtype: str 348 349 @see: sqlCreate 350 ''' 351 outfile.write(str(sqlInsert(params,extraParams,dbType=dbType)))
352 353
354 -def sqlInsert(params,extraParams=None,dbType='postgres'):
355 ''' 356 Give the SQL INSERT statement 357 @param params: dict keyed by field name of values 358 @param extraParams: any extra fields that you have created beyond the normal ais message fields 359 @rtype: sqlhelp.insert 360 @return: insert class instance 361 @todo: allow optional type checking of params? 362 @warning: this will take invalid keys happily and do what??? 363 ''' 364 import sqlhelp 365 i = sqlhelp.insert('utcquery',dbType=dbType) 366 367 if dbType=='postgres': 368 finished = [] 369 for key in params: 370 if key in finished: 371 continue 372 373 if key not in toPgFields and key not in fromPgFields: 374 if type(params[key])==Decimal: i.add(key,float(params[key])) 375 else: i.add(key,params[key]) 376 else: 377 if key in fromPgFields: 378 val = params[key] 379 # Had better be a WKT type like POINT(-88.1 30.321) 380 i.addPostGIS(key,val) 381 finished.append(key) 382 else: 383 # Need to construct the type. 384 pgName = toPgFields[key] 385 #valStr='GeomFromText(\''+pgTypes[pgName]+'(' 386 valStr=pgTypes[pgName]+'(' 387 vals = [] 388 for nonPgKey in fromPgFields[pgName]: 389 vals.append(str(params[nonPgKey])) 390 finished.append(nonPgKey) 391 valStr+=' '.join(vals)+')' 392 i.addPostGIS(pgName,valStr) 393 else: 394 for key in params: 395 if type(params[key])==Decimal: i.add(key,float(params[key])) 396 else: i.add(key,params[key]) 397 398 if None != extraParams: 399 for key in extraParams: 400 i.add(key,extraParams[key]) 401 402 return i
403 404 ###################################################################### 405 # LATEX SUPPORT 406 ###################################################################### 407
408 -def latexDefinitionTable(outfile=sys.stdout 409 ):
410 ''' 411 Return the LaTeX definition table for this message type 412 @param outfile: file like object to print to. 413 @type outfile: file obj 414 @return: LaTeX table string via the outfile 415 @rtype: str 416 417 ''' 418 o = outfile 419 420 o.write(''' 421 \\begin{table}%[htb] 422 \\centering 423 \\begin{tabular}{|l|c|l|} 424 \\hline 425 Parameter & Number of bits & Description 426 \\\\ \\hline\\hline 427 MessageID & 6 & AIS message number. Must be 10 \\\\ \hline 428 RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline 429 UserID & 30 & Unique ship identification number (MMSI) \\\\ \hline 430 Spare1 & 2 & Not used. Should be set to zero. \\\\ \hline 431 DestID & 30 & Unique ship identification number (MMSI) \\\\ \hline 432 Spare2 & 2 & Not used. Should be set to zero.\\\\ \\hline \\hline 433 Total bits & 72 & Appears to take 1 slot with 96 pad bits to fill the last slot \\\\ \\hline 434 \\end{tabular} 435 \\caption{AIS message number 10: Search and rescue position report} 436 \\label{tab:utcquery} 437 \\end{table} 438 ''')
439 440 441 ###################################################################### 442 # UNIT TESTING 443 ###################################################################### 444 import unittest
445 -def testParams():
446 '''Return a params file base on the testvalue tags. 447 @rtype: dict 448 @return: params based on testvalue tags 449 ''' 450 params = {} 451 params['MessageID'] = 10 452 params['RepeatIndicator'] = 1 453 params['UserID'] = 1193046 454 params['Spare1'] = 0 455 params['DestID'] = 1193046 456 params['Spare2'] = 0 457 458 return params
459
460 -class Testutcquery(unittest.TestCase):
461 '''Use testvalue tag text from each type to build test case the utcquery message'''
462 - def testEncodeDecode(self):
463 464 params = testParams() 465 bits = encode(params) 466 r = decode(bits) 467 468 # Check that each parameter came through ok. 469 self.failUnlessEqual(r['MessageID'],params['MessageID']) 470 self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 471 self.failUnlessEqual(r['UserID'],params['UserID']) 472 self.failUnlessEqual(r['Spare1'],params['Spare1']) 473 self.failUnlessEqual(r['DestID'],params['DestID']) 474 self.failUnlessEqual(r['Spare2'],params['Spare2'])
475
476 -def addMsgOptions(parser):
477 parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 478 help='decode a "utcquery" AIS message') 479 parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 480 help='encode a "utcquery" AIS message') 481 parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 482 ,help='Field parameter value [default: %default]') 483 parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 484 ,help='Field parameter value [default: %default]') 485 parser.add_option('--DestID-field', dest='DestIDField',metavar='uint',type='int' 486 ,help='Field parameter value [default: %default]')
487 488 ############################################################ 489 if __name__=='__main__': 490 491 from optparse import OptionParser 492 parser = OptionParser(usage="%prog [options]", 493 version="%prog "+__version__) 494 495 parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 496 help='run the documentation tests') 497 parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 498 help='run the unit tests') 499 parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 500 help='Make the test output verbose') 501 502 # FIX: remove nmea from binary messages. No way to build the whole packet? 503 # FIX: or build the surrounding msg 8 for a broadcast? 504 typeChoices = ('binary','nmeapayload','nmea') # FIX: what about a USCG type message? 505 parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 506 ,default='nmeapayload' 507 ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 508 509 510 outputChoices = ('std','html','csv','sql' ) 511 parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 512 ,default='std' 513 ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 514 515 parser.add_option('-o','--output',dest='outputFileName',default=None, 516 help='Name of the python file to write [default: stdout]') 517 518 parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 519 choices=fieldList, 520 help='Which fields to include in the output. Currently only for csv output [default: all]') 521 522 parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 523 help='Print the field name for csv') 524 525 parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 526 help='Print out an sql create command for the table.') 527 528 parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 529 help='Print a LaTeX table of the type') 530 531 dbChoices = ('sqlite','postgres') 532 parser.add_option('-D','--db-type',dest='dbType',default='postgres' 533 ,choices=dbChoices,type='choice' 534 ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 535 536 addMsgOptions(parser) 537 538 (options,args) = parser.parse_args() 539 success=True 540 541 if options.doctest: 542 import os; print os.path.basename(sys.argv[0]), 'doctests ...', 543 sys.argv= [sys.argv[0]] 544 if options.verbose: sys.argv.append('-v') 545 import doctest 546 numfail,numtests=doctest.testmod() 547 if numfail==0: print 'ok' 548 else: 549 print 'FAILED' 550 success=False 551 552 if not success: sys.exit('Something Failed') 553 del success # Hide success from epydoc 554 555 if options.unittest: 556 sys.argv = [sys.argv[0]] 557 if options.verbose: sys.argv.append('-v') 558 unittest.main() 559 560 outfile = sys.stdout 561 if None!=options.outputFileName: 562 outfile = file(options.outputFileName,'w') 563 564 565 if options.doEncode: 566 # First make sure all non required options are specified 567 if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 568 if None==options.UserIDField: parser.error("missing value for UserIDField") 569 if None==options.DestIDField: parser.error("missing value for DestIDField") 570 msgDict={ 571 'MessageID': '10', 572 'RepeatIndicator': options.RepeatIndicatorField, 573 'UserID': options.UserIDField, 574 'Spare1': '0', 575 'DestID': options.DestIDField, 576 'Spare2': '0', 577 } 578 579 bits = encode(msgDict) 580 if 'binary'==options.ioType: print str(bits) 581 elif 'nmeapayload'==options.ioType: 582 # FIX: figure out if this might be necessary at compile time 583 print "bitLen",len(bits) 584 bitLen=len(bits) 585 if bitLen%6!=0: 586 bits = bits + BitVector(size=(6 - (bitLen%6))) # Pad out to multiple of 6 587 print "result:",binary.bitvectoais6(bits)[0] 588 589 590 # FIX: Do not emit this option for the binary message payloads. Does not make sense. 591 elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 592 else: sys.exit('ERROR: unknown ioType. Help!') 593 594 595 if options.sqlCreate: 596 sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 597 598 if options.latexDefinitionTable: 599 latexDefinitionTable(outfile) 600 601 if options.printCsvfieldList: 602 # Make a csv separated list of fields that will be displayed for csv 603 if None == options.fieldList: options.fieldList = fieldList 604 import StringIO 605 buf = StringIO.StringIO() 606 for field in options.fieldList: 607 buf.write(field+',') 608 result = buf.getvalue() 609 if result[-1] == ',': print result[:-1] 610 else: print result 611 612 if options.doDecode: 613 for msg in args: 614 bv = None 615 616 if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 617 # Found nmea 618 # FIX: do checksum 619 bv = binary.ais6tobitvec(msg.split(',')[5]) 620 else: # either binary or nmeapayload... expect mostly nmeapayloads 621 # assumes that an all 0 and 1 string can not be a nmeapayload 622 binaryMsg=True 623 for c in msg: 624 if c not in ('0','1'): 625 binaryMsg=False 626 break 627 if binaryMsg: 628 bv = BitVector(bitstring=msg) 629 else: # nmeapayload 630 bv = binary.ais6tobitvec(msg) 631 632 printFields(decode(bv) 633 ,out=outfile 634 ,format=options.outputType 635 ,fieldList=options.fieldList 636 ,dbType=options.dbType 637 ) 638