@@ -294,84 +294,115 @@ class PingParser(object):
294294
295295 def __init__ (self ):
296296 self .buf = bytearray ()
297- self .state = PingParser .WAIT_START
298- self .payload_length = 0 # payload length remaining to be parsed for the message currently being parsed
299- self .message_id = 0 # message id of the message currently being parsed
297+ self .state = self .WAIT_START
298+ self .payload_length = 0 # remaining for the message currently being parsed
299+ self .message_id = 0 # of the message currently being parsed
300300 self .errors = 0
301301 self .parsed = 0
302- self .rx_msg = None # most recently parsed message
302+ self .rx_msg = None # most recently parsed message
303303
304- # Feed the parser a single byte
305- # Returns the current parse state
306- # If the byte fed completes a valid message, return PingParser.NEW_MESSAGE
307- # The decoded message will be available in the self.rx_msg attribute until a new message is decoded
308- def parse_byte (self , msg_byte ):
309- if type (msg_byte ) != int :
310- msg_byte = ord (msg_byte )
311- # print("byte: %d, state: %d, rem: %d, id: %d" % (msg_byte, self.state, self.payload_length, self.message_id))
312- if self .state == PingParser .WAIT_START :
313- self .buf = bytearray ()
314- if msg_byte == ord ('B' ):
315- self .buf .append (msg_byte )
316- self .state += 1
317- elif self .state == PingParser .WAIT_HEADER :
318- if msg_byte == ord ('R' ):
319- self .buf .append (msg_byte )
320- self .state += 1
321- else :
322- self .state = PingParser .WAIT_START
323- elif self .state == PingParser .WAIT_LENGTH_L :
324- self .payload_length = msg_byte
325- self .buf .append (msg_byte )
326- self .state += 1
327- elif self .state == PingParser .WAIT_LENGTH_H :
328- self .payload_length = (msg_byte << 8 ) | self .payload_length
329- self .buf .append (msg_byte )
330- self .state += 1
331- elif self .state == PingParser .WAIT_MSG_ID_L :
332- self .message_id = msg_byte
333- self .buf .append (msg_byte )
334- self .state += 1
335- elif self .state == PingParser .WAIT_MSG_ID_H :
336- self .message_id = (msg_byte << 8 ) | self .message_id
304+ def wait_start (self , msg_byte ):
305+ self .buf = bytearray ()
306+ if msg_byte == ord ('B' ):
337307 self .buf .append (msg_byte )
338308 self .state += 1
339- elif self .state == PingParser .WAIT_SRC_ID :
309+
310+ def wait_header (self , msg_byte ):
311+ if msg_byte == ord ('R' ):
340312 self .buf .append (msg_byte )
341313 self .state += 1
342- elif self .state == PingParser .WAIT_DST_ID :
343- self .buf .append (msg_byte )
314+ else :
315+ self .state = self .WAIT_START
316+
317+ def wait_length_l (self , msg_byte ):
318+ self .payload_length = msg_byte
319+ self .buf .append (msg_byte )
320+ self .state += 1
321+
322+ def wait_length_h (self , msg_byte ):
323+ self .payload_length |= (msg_byte << 8 )
324+ self .buf .append (msg_byte )
325+ self .state += 1
326+
327+ def wait_msg_id_l (self , msg_byte ):
328+ self .message_id = msg_byte
329+ self .buf .append (msg_byte )
330+ self .state += 1
331+
332+ def wait_msg_id_h (self , msg_byte ):
333+ self .message_id |= (msg_byte << 8 )
334+ self .buf .append (msg_byte )
335+ self .state += 1
336+
337+ def wait_src_id (self , msg_byte ):
338+ self .buf .append (msg_byte )
339+ self .state += 1
340+
341+ def wait_dst_id (self , msg_byte ):
342+ self .buf .append (msg_byte )
343+ self .state += 1
344+ if self .payload_length == 1 : # no payload bytes -> skip waiting
344345 self .state += 1
345- if self .payload_length == 0 : # no payload bytes
346- self .state += 1
347- elif self .state == PingParser .WAIT_PAYLOAD :
348- self .buf .append (msg_byte )
349- self .payload_length -= 1
350- if self .payload_length == 0 :
351- self .state += 1
352- elif self .state == PingParser .WAIT_CHECKSUM_L :
353- self .buf .append (msg_byte )
346+
347+ def wait_payload (self , msg_byte ):
348+ self .buf .append (msg_byte )
349+ self .payload_length -= 1
350+ if self .payload_length == 0 : # no payload bytes remaining -> stop waiting:
354351 self .state += 1
355- elif self .state == PingParser .WAIT_CHECKSUM_H :
356- self .buf .append (msg_byte )
357- self .rx_msg = PingMessage (msg_data = self .buf )
358352
359- # print(self.rx_msg)
353+ def wait_checksum_l (self , msg_byte ):
354+ self .buf .append (msg_byte )
355+ self .state += 1
360356
361- self .state = PingParser .WAIT_START
362- self .payload_length = 0
363- self .message_id = 0
357+ def wait_checksum_h (self , msg_byte ):
358+ self .state = self .WAIT_START
359+ self .payload_length = 0
360+ self .message_id = 0
364361
365- if self .rx_msg .verify_checksum ():
366- self .parsed += 1
367- return PingParser .NEW_MESSAGE
368- else :
369- # TODO add/return error state
370- print ("parse error" )
371- self .errors += 1
362+ self .buf .append (msg_byte )
363+ self .rx_msg = PingMessage (msg_data = self .buf )
364+
365+ if self .rx_msg .verify_checksum ():
366+ self .parsed += 1
367+ return self .NEW_MESSAGE
368+ else :
369+ # TODO add/return error state
370+ print ("parse error" )
371+ self .errors += 1
372372
373373 return self .state
374374
375+ def parse_byte (self , msg_byte ):
376+ """ Returns the current parse state after feeding the parser a single byte.
377+
378+ 'msg_byte' is the byte to parse.
379+ If it completes a valid message, returns PingParser.NEW_MESSAGE.
380+ The decoded PingMessage will be available in the self.rx_msg attribute
381+ until a new message is decoded.
382+
383+ """
384+ # Apply the relevant parsing method for the current state.
385+ # (offset by 1 because NEW_MESSAGE isn't processed - start at WAIT_START)
386+ result = self ._PARSE_BYTE [self .state - 1 ](self , msg_byte )
387+
388+ return self .state if result is None else result
389+
390+ # Tuple of parsing methods, in order of parser state
391+ # at bottom because otherwise methods won't be defined
392+ _PARSE_BYTE = (
393+ wait_start ,
394+ wait_header ,
395+ wait_length_l ,
396+ wait_length_h ,
397+ wait_msg_id_l ,
398+ wait_msg_id_h ,
399+ wait_src_id ,
400+ wait_dst_id ,
401+ wait_payload ,
402+ wait_checksum_l ,
403+ wait_checksum_h ,
404+ )
405+
375406
376407if __name__ == "__main__" :
377408 # Hand-written data buffers for testing and verification
0 commit comments