1   
  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   
 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          'SeqNum', 
 54          'DestinationID', 
 55          'RetransmitFlag', 
 56          'Spare', 
 57          'BinaryData', 
 58  ) 
 59   
 60  fieldListPostgres = ( 
 61          'MessageID', 
 62          'RepeatIndicator', 
 63          'UserID', 
 64          'SeqNum', 
 65          'DestinationID', 
 66          'RetransmitFlag', 
 67          'Spare', 
 68          'BinaryData', 
 69  ) 
 70   
 71  toPgFields = { 
 72  } 
 73  ''' 
 74  Go to the Postgis field names from the straight field name 
 75  ''' 
 76   
 77  fromPgFields = { 
 78  } 
 79  ''' 
 80  Go from the Postgis field names to the straight field name 
 81  ''' 
 82   
 83  pgTypes = { 
 84  } 
 85  ''' 
 86  Lookup table for each postgis field name to get its type. 
 87  ''' 
 88   
 89 -def encode(params, validate=False): 
  90          '''Create a abm binary message payload to pack into an AIS Msg abm. 
 91   
 92          Fields in params: 
 93            - MessageID(uint): AIS message number.  Must be 6 (field automatically set to "6") 
 94            - RepeatIndicator(uint): Indicated how many times a message has been repeated 
 95            - UserID(uint): Unique ship identification number (MMSI).  Also known as the Source ID 
 96            - SeqNum(uint): Sequence number as described in 5.3.1.  Assigned to each station 
 97            - DestinationID(uint): Unique ship identification number (MMSI). 
 98            - RetransmitFlag(bool): Should the message be restransmitted? 
 99            - Spare(uint): Must be 0 (field automatically set to "0") 
100            - BinaryData(binary): Bits for a binary broadcast message 
101          @param params: Dictionary of field names/values.  Throws a ValueError exception if required is missing 
102          @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented. 
103          @rtype: BitVector 
104          @return: encoded binary message (for binary messages, this needs to be wrapped in a msg 8 
105          @note: The returned bits may not be 6 bit aligned.  It is up to you to pad out the bits. 
106          ''' 
107   
108          bvList = [] 
109          bvList.append(binary.setBitVectorSize(BitVector(intVal=6),6)) 
110          if 'RepeatIndicator' in params: 
111                  bvList.append(binary.setBitVectorSize(BitVector(intVal=params['RepeatIndicator']),2)) 
112          else: 
113                  bvList.append(binary.setBitVectorSize(BitVector(intVal=0),2)) 
114          bvList.append(binary.setBitVectorSize(BitVector(intVal=params['UserID']),30)) 
115          bvList.append(binary.setBitVectorSize(BitVector(intVal=params['SeqNum']),2)) 
116          bvList.append(binary.setBitVectorSize(BitVector(intVal=params['DestinationID']),30)) 
117          if params["RetransmitFlag"]: bvList.append(TrueBV) 
118          else: bvList.append(FalseBV) 
119          bvList.append(binary.setBitVectorSize(BitVector(intVal=0),1)) 
120          bvList.append(params['BinaryData']) 
121   
122          return binary.joinBV(bvList) 
 123   
124 -def decode(bv, validate=False): 
 125          '''Unpack a abm message  
126   
127          Fields in params: 
128            - MessageID(uint): AIS message number.  Must be 6 (field automatically set to "6") 
129            - RepeatIndicator(uint): Indicated how many times a message has been repeated 
130            - UserID(uint): Unique ship identification number (MMSI).  Also known as the Source ID 
131            - SeqNum(uint): Sequence number as described in 5.3.1.  Assigned to each station 
132            - DestinationID(uint): Unique ship identification number (MMSI). 
133            - RetransmitFlag(bool): Should the message be restransmitted? 
134            - Spare(uint): Must be 0 (field automatically set to "0") 
135            - BinaryData(binary): Bits for a binary broadcast message 
136          @type bv: BitVector 
137          @param bv: Bits defining a message 
138          @param validate: Set to true to cause checking to occur.  Runs slower.  FIX: not implemented. 
139          @rtype: dict 
140          @return: params 
141          ''' 
142   
143           
144           
145           
146          r = {} 
147          r['MessageID']=6 
148          r['RepeatIndicator']=int(bv[6:8]) 
149          r['UserID']=int(bv[8:38]) 
150          r['SeqNum']=int(bv[38:40]) 
151          r['DestinationID']=int(bv[40:70]) 
152          r['RetransmitFlag']=bool(int(bv[70:71])) 
153          r['Spare']=0 
154          r['BinaryData']=bv[72:] 
155          return r 
 156   
159   
162   
165   
167          return int(bv[38:40]) 
 168   
170          return int(bv[40:70]) 
 171   
173          return bool(int(bv[70:71])) 
 174   
177   
180   
181   
183                  out.write("<h3>abm<h3>\n") 
184                  out.write("<table border=\"1\">\n") 
185                  out.write("<tr bgcolor=\"orange\">\n") 
186                  out.write("<th align=\"left\">Field Name</th>\n") 
187                  out.write("<th align=\"left\">Type</th>\n") 
188                  out.write("<th align=\"left\">Value</th>\n") 
189                  out.write("<th align=\"left\">Value in Lookup Table</th>\n") 
190                  out.write("<th align=\"left\">Units</th>\n") 
191                  out.write("\n") 
192                  out.write("<tr>\n") 
193                  out.write("<td>MessageID</td>\n") 
194                  out.write("<td>uint</td>\n") 
195                  if 'MessageID' in params: 
196                          out.write("     <td>"+str(params['MessageID'])+"</td>\n") 
197                          out.write("     <td>"+str(params['MessageID'])+"</td>\n") 
198                  out.write("</tr>\n") 
199                  out.write("\n") 
200                  out.write("<tr>\n") 
201                  out.write("<td>RepeatIndicator</td>\n") 
202                  out.write("<td>uint</td>\n") 
203                  if 'RepeatIndicator' in params: 
204                          out.write("     <td>"+str(params['RepeatIndicator'])+"</td>\n") 
205                          if str(params['RepeatIndicator']) in RepeatIndicatorDecodeLut: 
206                                  out.write("<td>"+RepeatIndicatorDecodeLut[str(params['RepeatIndicator'])]+"</td>") 
207                          else: 
208                                  out.write("<td><i>Missing LUT entry</i></td>") 
209                  out.write("</tr>\n") 
210                  out.write("\n") 
211                  out.write("<tr>\n") 
212                  out.write("<td>UserID</td>\n") 
213                  out.write("<td>uint</td>\n") 
214                  if 'UserID' in params: 
215                          out.write("     <td>"+str(params['UserID'])+"</td>\n") 
216                          out.write("     <td>"+str(params['UserID'])+"</td>\n") 
217                  out.write("</tr>\n") 
218                  out.write("\n") 
219                  out.write("<tr>\n") 
220                  out.write("<td>SeqNum</td>\n") 
221                  out.write("<td>uint</td>\n") 
222                  if 'SeqNum' in params: 
223                          out.write("     <td>"+str(params['SeqNum'])+"</td>\n") 
224                          out.write("     <td>"+str(params['SeqNum'])+"</td>\n") 
225                  out.write("</tr>\n") 
226                  out.write("\n") 
227                  out.write("<tr>\n") 
228                  out.write("<td>DestinationID</td>\n") 
229                  out.write("<td>uint</td>\n") 
230                  if 'DestinationID' in params: 
231                          out.write("     <td>"+str(params['DestinationID'])+"</td>\n") 
232                          out.write("     <td>"+str(params['DestinationID'])+"</td>\n") 
233                  out.write("</tr>\n") 
234                  out.write("\n") 
235                  out.write("<tr>\n") 
236                  out.write("<td>RetransmitFlag</td>\n") 
237                  out.write("<td>bool</td>\n") 
238                  if 'RetransmitFlag' in params: 
239                          out.write("     <td>"+str(params['RetransmitFlag'])+"</td>\n") 
240                          out.write("     <td>"+str(params['RetransmitFlag'])+"</td>\n") 
241                  out.write("</tr>\n") 
242                  out.write("\n") 
243                  out.write("<tr>\n") 
244                  out.write("<td>Spare</td>\n") 
245                  out.write("<td>uint</td>\n") 
246                  if 'Spare' in params: 
247                          out.write("     <td>"+str(params['Spare'])+"</td>\n") 
248                          out.write("     <td>"+str(params['Spare'])+"</td>\n") 
249                  out.write("</tr>\n") 
250                  out.write("\n") 
251                  out.write("<tr>\n") 
252                  out.write("<td>BinaryData</td>\n") 
253                  out.write("<td>binary</td>\n") 
254                  if 'BinaryData' in params: 
255                          out.write("     <td>"+str(params['BinaryData'])+"</td>\n") 
256                          out.write("     <td>"+str(params['BinaryData'])+"</td>\n") 
257                  out.write("</tr>\n") 
258                  out.write("</table>\n") 
 259   
260 -def printFields(params, out=sys.stdout, format='std', fieldList=None, dbType='postgres'): 
 261          '''Print a abm message to stdout. 
262   
263          Fields in params: 
264            - MessageID(uint): AIS message number.  Must be 6 (field automatically set to "6") 
265            - RepeatIndicator(uint): Indicated how many times a message has been repeated 
266            - UserID(uint): Unique ship identification number (MMSI).  Also known as the Source ID 
267            - SeqNum(uint): Sequence number as described in 5.3.1.  Assigned to each station 
268            - DestinationID(uint): Unique ship identification number (MMSI). 
269            - RetransmitFlag(bool): Should the message be restransmitted? 
270            - Spare(uint): Must be 0 (field automatically set to "0") 
271            - BinaryData(binary): Bits for a binary broadcast message 
272          @param params: Dictionary of field names/values.   
273          @param out: File like object to write to 
274          @rtype: stdout 
275          @return: text to out 
276          ''' 
277   
278          if 'std'==format: 
279                  out.write("abm:\n") 
280                  if 'MessageID' in params: out.write("   MessageID:        "+str(params['MessageID'])+"\n") 
281                  if 'RepeatIndicator' in params: out.write("     RepeatIndicator:  "+str(params['RepeatIndicator'])+"\n") 
282                  if 'UserID' in params: out.write("      UserID:           "+str(params['UserID'])+"\n") 
283                  if 'SeqNum' in params: out.write("      SeqNum:           "+str(params['SeqNum'])+"\n") 
284                  if 'DestinationID' in params: out.write("       DestinationID:    "+str(params['DestinationID'])+"\n") 
285                  if 'RetransmitFlag' in params: out.write("      RetransmitFlag:   "+str(params['RetransmitFlag'])+"\n") 
286                  if 'Spare' in params: out.write("       Spare:            "+str(params['Spare'])+"\n") 
287                  if 'BinaryData' in params: out.write("  BinaryData:       "+str(params['BinaryData'])+"\n") 
288          elif 'csv'==format: 
289                  if None == options.fieldList: 
290                          options.fieldList = fieldList 
291                  needComma = False; 
292                  for field in fieldList: 
293                          if needComma: out.write(',') 
294                          needComma = True 
295                          if field in params: 
296                                  out.write(str(params[field])) 
297                           
298                  out.write("\n") 
299          elif 'html'==format: 
300                  printHtml(params,out) 
301          elif 'sql'==format: 
302                  sqlInsertStr(params,out,dbType=dbType) 
303          else:  
304                  print "ERROR: unknown format:",format 
305                  assert False 
306   
307          return  
 308   
309  RepeatIndicatorEncodeLut = { 
310          'default':'0', 
311          'do not repeat any more':'3', 
312          }  
313   
314  RepeatIndicatorDecodeLut = { 
315          '0':'default', 
316          '3':'do not repeat any more', 
317          }  
318   
319   
320   
321   
322   
323 -def sqlCreateStr(outfile=sys.stdout, fields=None, extraFields=None 
324                  ,addCoastGuardFields=True 
325                  ,dbType='postgres' 
326                  ): 
 327          ''' 
328          Return the SQL CREATE command for this message type 
329          @param outfile: file like object to print to. 
330          @param fields: which fields to put in the create.  Defaults to all. 
331          @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 
332          @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 
333          @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 
334          @type addCoastGuardFields: bool 
335          @return: sql create string 
336          @rtype: str 
337   
338          @see: sqlCreate 
339          ''' 
340           
341          outfile.write(str(sqlCreate(fields,extraFields,addCoastGuardFields,dbType=dbType))) 
 342   
343 -def sqlCreate(fields=None, extraFields=None, addCoastGuardFields=True, dbType='postgres'): 
 344          ''' 
345          Return the sqlhelp object to create the table. 
346   
347          @param fields: which fields to put in the create.  Defaults to all. 
348          @param extraFields: A sequence of tuples containing (name,sql type) for additional fields 
349          @param addCoastGuardFields: Add the extra fields that come after the NMEA check some from the USCG N-AIS format 
350          @type addCoastGuardFields: bool 
351          @param dbType: Which flavor of database we are using so that the create is tailored ('sqlite' or 'postgres') 
352          @return: An object that can be used to generate a return 
353          @rtype: sqlhelp.create 
354          ''' 
355          if None == fields: fields = fieldList 
356          import sqlhelp 
357          c = sqlhelp.create('abm',dbType=dbType) 
358          c.addPrimaryKey() 
359          if 'MessageID' in fields: c.addInt ('MessageID') 
360          if 'RepeatIndicator' in fields: c.addInt ('RepeatIndicator') 
361          if 'UserID' in fields: c.addInt ('UserID') 
362          if 'SeqNum' in fields: c.addInt ('SeqNum') 
363          if 'DestinationID' in fields: c.addInt ('DestinationID') 
364          if 'RetransmitFlag' in fields: c.addBool('RetransmitFlag') 
365          if 'Spare' in fields: c.addInt ('Spare') 
366          if 'BinaryData' in fields: c.addBitVarying('BinaryData',1024) 
367   
368          if addCoastGuardFields: 
369                   
370                   
371                   
372                   
373                   
374                  c.addVarChar('cg_r',15)    
375                  c.addInt('cg_sec')         
376   
377                  c.addTimestamp('cg_timestamp')  
378   
379          return c 
 380   
381 -def sqlInsertStr(params, outfile=sys.stdout, extraParams=None, dbType='postgres'): 
 382          ''' 
383          Return the SQL INSERT command for this message type 
384          @param params: dictionary of values keyed by field name 
385          @param outfile: file like object to print to. 
386          @param extraParams: A sequence of tuples containing (name,sql type) for additional fields 
387          @return: sql create string 
388          @rtype: str 
389   
390          @see: sqlCreate 
391          ''' 
392          outfile.write(str(sqlInsert(params,extraParams,dbType=dbType))) 
 393   
394   
395 -def sqlInsert(params,extraParams=None,dbType='postgres'): 
 396          ''' 
397          Give the SQL INSERT statement 
398          @param params: dict keyed by field name of values 
399          @param extraParams: any extra fields that you have created beyond the normal ais message fields 
400          @rtype: sqlhelp.insert 
401          @return: insert class instance 
402          @todo: allow optional type checking of params? 
403          @warning: this will take invalid keys happily and do what??? 
404          ''' 
405          import sqlhelp 
406          i = sqlhelp.insert('abm',dbType=dbType) 
407   
408          if dbType=='postgres': 
409                  finished = [] 
410                  for key in params: 
411                          if key in finished:  
412                                  continue 
413   
414                          if key not in toPgFields and key not in fromPgFields: 
415                                  if type(params[key])==Decimal: i.add(key,float(params[key])) 
416                                  else: i.add(key,params[key]) 
417                          else: 
418                                  if key in fromPgFields: 
419                                          val = params[key] 
420                                           
421                                          i.addPostGIS(key,val) 
422                                          finished.append(key) 
423                                  else: 
424                                           
425                                          pgName = toPgFields[key] 
426                                           
427                                          valStr=pgTypes[pgName]+'(' 
428                                          vals = [] 
429                                          for nonPgKey in fromPgFields[pgName]: 
430                                                  vals.append(str(params[nonPgKey])) 
431                                                  finished.append(nonPgKey) 
432                                          valStr+=' '.join(vals)+')' 
433                                          i.addPostGIS(pgName,valStr) 
434          else: 
435                  for key in params:  
436                          if type(params[key])==Decimal: i.add(key,float(params[key])) 
437                          else: i.add(key,params[key]) 
438   
439          if None != extraParams: 
440                  for key in extraParams:  
441                          i.add(key,extraParams[key]) 
442   
443          return i 
 444   
445   
446   
447   
448   
451          ''' 
452          Return the LaTeX definition table for this message type 
453          @param outfile: file like object to print to. 
454          @type outfile: file obj 
455          @return: LaTeX table string via the outfile 
456          @rtype: str 
457   
458          ''' 
459          o = outfile 
460   
461          o.write(''' 
462  \\begin{table}%[htb] 
463  \\centering 
464  \\begin{tabular}{|l|c|l|} 
465  \\hline 
466  Parameter & Number of bits & Description  
467  \\\\  \\hline\\hline 
468  MessageID & 6 & AIS message number.  Must be 6 \\\\ \hline  
469  RepeatIndicator & 2 & Indicated how many times a message has been repeated \\\\ \hline  
470  UserID & 30 & Unique ship identification number (MMSI).  Also known as the Source ID \\\\ \hline  
471  SeqNum & 2 & Sequence number as described in 5.3.1.  Assigned to each station \\\\ \hline  
472  DestinationID & 30 & Unique ship identification number (MMSI). \\\\ \hline  
473  RetransmitFlag & 1 & Should the message be restransmitted? \\\\ \hline  
474  Spare & 1 & Must be 0 \\\\ \hline  
475  BinaryData & -1 & Bits for a binary broadcast message\\\\ \\hline \\hline 
476  Total bits & 71 & Appears to take 1 slot with 97 pad bits to fill the last slot \\\\ \\hline 
477  \\end{tabular} 
478  \\caption{AIS message number 8: Addressed Binary Message} 
479  \\label{tab:abm} 
480  \\end{table} 
481  ''') 
 482   
483   
484   
485   
486   
487  import unittest 
489          '''Return a params file base on the testvalue tags. 
490          @rtype: dict 
491          @return: params based on testvalue tags 
492          ''' 
493          params = {} 
494          params['MessageID'] = 6 
495          params['RepeatIndicator'] = 1 
496          params['UserID'] = 1193046 
497          params['SeqNum'] = 3 
498          params['DestinationID'] = 1193047 
499          params['RetransmitFlag'] = True 
500          params['Spare'] = 0 
501          params['BinaryData'] = BitVector(bitstring='110000101100000111100010010101001110111001101010011011111111100000110001011100001011111111101111111110011001000000010001110') 
502   
503          return params 
 504   
506          '''Use testvalue tag text from each type to build test case the abm message''' 
508   
509                  params = testParams() 
510                  bits   = encode(params) 
511                  r      = decode(bits) 
512   
513                   
514                  self.failUnlessEqual(r['MessageID'],params['MessageID']) 
515                  self.failUnlessEqual(r['RepeatIndicator'],params['RepeatIndicator']) 
516                  self.failUnlessEqual(r['UserID'],params['UserID']) 
517                  self.failUnlessEqual(r['SeqNum'],params['SeqNum']) 
518                  self.failUnlessEqual(r['DestinationID'],params['DestinationID']) 
519                  self.failUnlessEqual(r['RetransmitFlag'],params['RetransmitFlag']) 
520                  self.failUnlessEqual(r['Spare'],params['Spare']) 
521                  self.failUnlessEqual(r['BinaryData'],params['BinaryData']) 
  522   
524          parser.add_option('-d','--decode',dest='doDecode',default=False,action='store_true', 
525                  help='decode a "abm" AIS message') 
526          parser.add_option('-e','--encode',dest='doEncode',default=False,action='store_true', 
527                  help='encode a "abm" AIS message') 
528          parser.add_option('--RepeatIndicator-field', dest='RepeatIndicatorField',default=0,metavar='uint',type='int' 
529                  ,help='Field parameter value [default: %default]') 
530          parser.add_option('--UserID-field', dest='UserIDField',metavar='uint',type='int' 
531                  ,help='Field parameter value [default: %default]') 
532          parser.add_option('--SeqNum-field', dest='SeqNumField',metavar='uint',type='int' 
533                  ,help='Field parameter value [default: %default]') 
534          parser.add_option('--DestinationID-field', dest='DestinationIDField',metavar='uint',type='int' 
535                  ,help='Field parameter value [default: %default]') 
536          parser.add_option('--RetransmitFlag-field', dest='RetransmitFlagField',metavar='bool',type='int' 
537                  ,help='Field parameter value [default: %default]') 
538          parser.add_option('--BinaryData-field', dest='BinaryDataField',metavar='binary',type='string' 
539                  ,help='Field parameter value [default: %default]') 
 540   
541   
542  if __name__=='__main__': 
543   
544          from optparse import OptionParser 
545          parser = OptionParser(usage="%prog [options]", 
546                  version="%prog "+__version__) 
547   
548          parser.add_option('--doc-test',dest='doctest',default=False,action='store_true', 
549                  help='run the documentation tests') 
550          parser.add_option('--unit-test',dest='unittest',default=False,action='store_true', 
551                  help='run the unit tests') 
552          parser.add_option('-v','--verbose',dest='verbose',default=False,action='store_true', 
553                  help='Make the test output verbose') 
554   
555           
556           
557          typeChoices = ('binary','nmeapayload','nmea')  
558          parser.add_option('-t','--type',choices=typeChoices,type='choice',dest='ioType' 
559                  ,default='nmeapayload' 
560                  ,help='What kind of string to write for encoding ('+', '.join(typeChoices)+') [default: %default]') 
561   
562   
563          outputChoices = ('std','html','csv','sql' ) 
564          parser.add_option('-T','--output-type',choices=outputChoices,type='choice',dest='outputType' 
565                  ,default='std' 
566                  ,help='What kind of string to output ('+', '.join(outputChoices)+') [default: %default]') 
567   
568          parser.add_option('-o','--output',dest='outputFileName',default=None, 
569                            help='Name of the python file to write [default: stdout]') 
570   
571          parser.add_option('-f','--fields',dest='fieldList',default=None, action='append', 
572                            choices=fieldList, 
573                            help='Which fields to include in the output.  Currently only for csv output [default: all]') 
574   
575          parser.add_option('-p','--print-csv-field-list',dest='printCsvfieldList',default=False,action='store_true', 
576                            help='Print the field name for csv') 
577   
578          parser.add_option('-c','--sql-create',dest='sqlCreate',default=False,action='store_true', 
579                            help='Print out an sql create command for the table.') 
580   
581          parser.add_option('--latex-table',dest='latexDefinitionTable',default=False,action='store_true', 
582                            help='Print a LaTeX table of the type') 
583   
584          dbChoices = ('sqlite','postgres') 
585          parser.add_option('-D','--db-type',dest='dbType',default='postgres' 
586                            ,choices=dbChoices,type='choice' 
587                            ,help='What kind of database ('+', '.join(dbChoices)+') [default: %default]') 
588   
589          addMsgOptions(parser) 
590   
591          (options,args) = parser.parse_args() 
592          success=True 
593   
594          if options.doctest: 
595                  import os; print os.path.basename(sys.argv[0]), 'doctests ...', 
596                  sys.argv= [sys.argv[0]] 
597                  if options.verbose: sys.argv.append('-v') 
598                  import doctest 
599                  numfail,numtests=doctest.testmod() 
600                  if numfail==0: print 'ok' 
601                  else:  
602                          print 'FAILED' 
603                          success=False 
604   
605          if not success: sys.exit('Something Failed') 
606          del success  
607   
608          if options.unittest: 
609                  sys.argv = [sys.argv[0]] 
610                  if options.verbose: sys.argv.append('-v') 
611                  unittest.main() 
612   
613          outfile = sys.stdout 
614          if None!=options.outputFileName: 
615                  outfile = file(options.outputFileName,'w') 
616   
617   
618          if options.doEncode: 
619                   
620                  if None==options.RepeatIndicatorField: parser.error("missing value for RepeatIndicatorField") 
621                  if None==options.UserIDField: parser.error("missing value for UserIDField") 
622                  if None==options.SeqNumField: parser.error("missing value for SeqNumField") 
623                  if None==options.DestinationIDField: parser.error("missing value for DestinationIDField") 
624                  if None==options.RetransmitFlagField: parser.error("missing value for RetransmitFlagField") 
625                  if None==options.BinaryDataField: parser.error("missing value for BinaryDataField") 
626                  msgDict={ 
627                          'MessageID': '6', 
628                          'RepeatIndicator': options.RepeatIndicatorField, 
629                          'UserID': options.UserIDField, 
630                          'SeqNum': options.SeqNumField, 
631                          'DestinationID': options.DestinationIDField, 
632                          'RetransmitFlag': options.RetransmitFlagField, 
633                          'Spare': '0', 
634                          'BinaryData': options.BinaryDataField, 
635                  } 
636   
637                  bits = encode(msgDict) 
638                  if 'binary'==options.ioType: print str(bits) 
639                  elif 'nmeapayload'==options.ioType: 
640                           
641                          print "bitLen",len(bits) 
642                          bitLen=len(bits) 
643                          if bitLen%6!=0: 
644                              bits = bits + BitVector(size=(6 - (bitLen%6)))   
645                          print "result:",binary.bitvectoais6(bits)[0] 
646   
647   
648                   
649                  elif 'nmea'==options.ioType: sys.exit("FIX: need to implement this capability") 
650                  else: sys.exit('ERROR: unknown ioType.  Help!') 
651   
652   
653          if options.sqlCreate: 
654                  sqlCreateStr(outfile,options.fieldList,dbType=options.dbType) 
655   
656          if options.latexDefinitionTable: 
657                  latexDefinitionTable(outfile) 
658   
659          if options.printCsvfieldList: 
660                   
661                  if None == options.fieldList: options.fieldList = fieldList 
662                  import StringIO 
663                  buf = StringIO.StringIO() 
664                  for field in options.fieldList: 
665                          buf.write(field+',') 
666                  result = buf.getvalue() 
667                  if result[-1] == ',': print result[:-1] 
668                  else: print result 
669   
670          if options.doDecode: 
671                  for msg in args: 
672                          bv = None 
673   
674                          if msg[0] in ('$','!') and msg[3:6] in ('VDM','VDO'): 
675                                   
676                                   
677                                  bv = binary.ais6tobitvec(msg.split(',')[5]) 
678                          else:  
679                                   
680                                  binaryMsg=True 
681                                  for c in msg: 
682                                          if c not in ('0','1'): 
683                                                  binaryMsg=False 
684                                                  break 
685                                  if binaryMsg: 
686                                          bv = BitVector(bitstring=msg) 
687                                  else:  
688                                          bv = binary.ais6tobitvec(msg) 
689   
690                          printFields(decode(bv) 
691                                      ,out=outfile 
692                                      ,format=options.outputType 
693                                      ,fieldList=options.fieldList 
694                                      ,dbType=options.dbType 
695                                      ) 
696