Exemple #1
0
 def parse_ais_messages(self, raw, bits, source='internal'):
     "Generator code - read forever from source stream, parsing AIS messages."
     values = {}
     values['length'] = bits.bitlen
     # Without the following magic, we'd have a subtle problem near
     # certain variable-length messages: DSV reports would
     # sometimes have fewer fields than expected, because the
     # unpacker would never generate cooked tuples for the omitted
     # part of the message.  Presently a known issue for types 15
     # and 16 only.  (Would never affect variable-length messages in
     # which the last field type is 'string' or 'raw').
     bits.extend_to(168)
     # Magic recursive unpacking operation
     try:
         cooked = ais.aivdm_unpack(0, bits, 0, values, ais.aivdm_decode)
         # We now have a list of tuples containing unpacked fields
         # Collect some field groups into ISO8601 format
         for (offset, template, label, legend,
              formatter) in ais.field_groups:
             segment = cooked[offset:offset + len(template)]
             if map(lambda x: x[0], segment) == template:
                 group = ais.formatter(*map(lambda x: x[1], segment))
                 group = (label, group, 'string', legend, None)
                 cooked = cooked[:offset] + [group] + cooked[offset +
                                                             len(template):]
         # Apply the postprocessor stage
         cooked = ais.postprocess(cooked)
         expected = ais.lengths.get(values['msgtype'], None)
         # Check length; has to be done after so we have the type field
         bogon = False
         if expected is not None:
             if type(expected) == type(0):
                 expected_range = (expected, expected)
             else:
                 expected_range = expected
             actual = values['length']
             if not (actual >= expected_range[0]
                     and actual <= expected_range[1]):
                 raise Exception(
                     "invalid length %d(%d..%d)" %
                     (actual, expected_range[0], expected_range[1]))
         # We're done, hand back a decoding
         #AVNLog.ld('decoded AIS data',cooked)
         self.storeAISdata(cooked, source=source)
         return True
     except:
         (exc_type, exc_value, exc_traceback) = sys.exc_info()
         AVNLog.debug("exception %s while decoding AIS data %s", exc_value,
                      raw.strip())
         return False
Exemple #2
0
 def parse_ais_messages(self,raw,bits):
     "Generator code - read forever from source stream, parsing AIS messages."
     values = {}
     values['length'] = bits.bitlen
     # Without the following magic, we'd have a subtle problem near
     # certain variable-length messages: DSV reports would
     # sometimes have fewer fields than expected, because the
     # unpacker would never generate cooked tuples for the omitted
     # part of the message.  Presently a known issue for types 15
     # and 16 only.  (Would never affect variable-length messages in
     # which the last field type is 'string' or 'raw').
     bits.extend_to(168)
     # Magic recursive unpacking operation
     try:
         cooked = ais.aivdm_unpack(0, bits, 0, values, ais.aivdm_decode)
         # We now have a list of tuples containing unpacked fields
         # Collect some field groups into ISO8601 format
         for (offset, template, label, legend, formatter) in ais.field_groups:
             segment = cooked[offset:offset+len(template)]
             if map(lambda x: x[0], segment) == template:
                 group = ais.formatter(*map(lambda x: x[1], segment))
                 group = (label, group, 'string', legend, None)
                 cooked = cooked[:offset]+[group]+cooked[offset+len(template):]
         # Apply the postprocessor stage
         cooked = ais.postprocess(cooked)
         expected = ais.lengths.get(values['msgtype'], None)
         # Check length; has to be done after so we have the type field 
         bogon = False
         if expected is not None:
             if type(expected) == type(0):
                 expected_range = (expected, expected)
             else:
                 expected_range = expected
             actual = values['length']
             if not (actual >= expected_range[0] and actual <= expected_range[1]):
                 raise AISUnpackingException(0, "length", actual)
         # We're done, hand back a decoding
         #AVNLog.ld('decoded AIS data',cooked)
         self.storeAISdata(cooked)
         return True
     except:
         (exc_type, exc_value, exc_traceback) = sys.exc_info()
         AVNLog.debug("exception %s while decoding AIS data %s",exc_value,raw.strip())
         return False