Changeset 124


Ignore:
Timestamp:
07/23/10 12:47:11 (11 years ago)
Author:
sc
Message:

thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py:

  • stream parsing rewritten for more efficient processing
File:
1 edited

Legend:

Unmodified
Added
Removed
  • thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py

    r123 r124  
    7878DEFAULT_MINDSET_ADDRESS = '00:13:EF:00:1B:FE' 
    7979 
    80 PROTOCOL_SYNC = 'xAA' 
     80PROTOCOL_SYNC = '\xAA' 
    8181PROTOCOL_EXCODE = '\x55' 
    8282 
    8383DEBUG_BYTE_COUNT = 819200 
    84 DEBUG_PACKET_COUNT = 1024 
     84DEBUG_PACKET_COUNT = 128 
    8585 
    8686##################################################################### 
     
    316316                        if code == '02': 
    317317                                poor_signal_quality = int(data_values, 16) 
    318                                 print "POOR_SIGNAL Quality:", 
    319                                 print poor_signal_quality 
     318                                if self.DEBUG > 1: 
     319                                        print "POOR_SIGNAL Quality:", 
     320                                        print poor_signal_quality 
    320321                         
    321322                        elif code == '04': 
    322323                                attention = int(data_values, 16) 
    323                                 print "ATTENTION:", 
    324                                 print attention 
     324                                if self.DEBUG > 1: 
     325                                        print "ATTENTION:", 
     326                                        print attention 
    325327                         
    326328                        elif code == '05': 
    327329                                meditation = int(data_values, 16) 
    328                                 print "MEDITATION:", 
    329                                 print meditation 
     330                                if self.DEBUG > 1: 
     331                                        print "MEDITATION:", 
     332                                        print meditation 
    330333                         
    331334                        elif code == '16': 
    332335                                blink_strength = int(data_values, 16) 
    333                                 print "Blink Strength:", 
    334                                 print blink_strength 
     336                                if self.DEBUG > 1: 
     337                                        print "Blink Strength:", 
     338                                        print blink_strength 
    335339                         
    336340                        elif code == '80': 
    337341                                raw_wave_value = data_values 
    338                                 #print "Raw EEG:", 
    339                                 #print raw_wave_value 
     342                                if self.DEBUG > 2: 
     343                                        print "Raw EEG:", 
     344                                        print raw_wave_value 
    340345                         
    341346                        elif code == '83': 
    342347                                asic_eeg_power = data_values 
    343                                 print "ASIC_EEG_POWER:", 
    344                                 print asic_eeg_power 
     348                                if self.DEBUG > 1: 
     349                                        print "ASIC_EEG_POWER:", 
     350                                        print asic_eeg_power 
    345351                                 
    346352                        else: 
     
    453459                # of the Packet's Data Payload, NOT of the entire Packet.  
    454460                # The Packet's complete length will always be [PLENGTH] + 4. 
    455  
     461                 
    456462                packet_length = packet[2] 
    457463                packet_length = packet_length.encode("hex") 
     
    590596                                         
    591597                                self.process_byte(byte) 
    592  
    593  
    594 ##################################################################### 
    595 ##################################################################### 
    596  
    597         def read_response(self, modem): 
    598  
    599                 # This function is passed to the modem each time the software 
    600                 # has asked the modem to perform a particular function. 
    601                 # It looks for an "OK" message from the modem, and stores all 
    602                 # data read back from the modem in a line, one entry per response 
    603                 # line. The function returns that list of responses, as well as 
    604                 # a status flag indicating whether the modem timed out while 
    605                 # waiting for the "OK" response. The timeout gets set during 
    606                 # modem initialization, based on the value stored in the database 
    607  
    608                 modem_timed_out = 0 
    609  
    610                 #self.log.pdebug("Waiting for 'OK' from %s modem..." % self.modem_type) 
    611  
    612                 response = [] 
    613  
    614                 while 'OK\r\n' not in response: 
    615                         reply = modem.readline() 
    616                         if (len(reply) == 0): 
    617                                 #self.log.perror("Modem timeout has been exceeded") 
    618                                 modem_timed_out = 1 
    619                                 break # The timeout has been exceeded 
     598         
     599         
     600        ################################################################## 
     601         
     602        def parse_stream(self): 
     603                 
     604                # Loop forever, parsing one Packet per loop... 
     605                packet_count = 0 
     606                 
     607                while True: 
     608                         
     609                        # Synchronize on [SYNC] bytes 
     610                        # Read from stream until two consecutive [SYNC] bytes are found 
     611                        byte = self.device.read() 
     612                        if (byte != PROTOCOL_SYNC): 
     613                                continue 
     614                         
     615                        byte = self.device.read() 
     616                        if (byte != PROTOCOL_SYNC): 
     617                                continue 
     618                         
     619                         
     620                        # Parse [PLENGTH] byte 
     621                         
     622                        # SPEC: [PLENGTH] byte indicates the length, in bytes, of the  
     623                        # Packet's Data Payload [PAYLOAD...] section, and may be any value  
     624                        # from 0 up to 169. Any higher value indicates an error  
     625                        # (PLENGTH TOO LARGE). Be sure to note that [PLENGTH] is the length  
     626                        # of the Packet's Data Payload, NOT of the entire Packet.  
     627                        # The Packet's complete length will always be [PLENGTH] + 4. 
     628                         
     629                        byte = self.device.read() 
     630                        packet_length = byte.encode("hex") 
     631                        packet_length = int(packet_length, 16) 
     632                         
     633                        if (packet_length > 170): 
     634                                if self.DEBUG: 
     635                                        print "ERROR: packet length bad" 
     636                                        continue 
     637                         
     638                         
     639                        # Collect [PAYLOAD...] bytes 
     640                        data_payload = self.device.read(packet_length) 
     641                         
     642                         
     643                        # Calculate [PAYLOAD...] checksum 
     644                         
     645                        # SPEC: The [CHKSUM] Byte must be used to verify the integrity of the 
     646                        # Packet's Data Payload. The Payload's Checksum is defined as: 
     647                        #  1. summing all the bytes of the Packet's Data Payload 
     648                        #  2. taking the lowest 8 bits of the sum 
     649                        #  3. performing the bit inverse (one's compliment inverse) 
     650                        #     on those lowest 8 bits 
     651                         
     652                        payload_checksum = 0 
     653                        for byte in data_payload: 
     654                                value = byte.encode("hex") 
     655                                value = int(value, 16) 
     656                                payload_checksum += value 
     657                         
     658                         
     659                        # Take the lowest 8 bits of the calculated payload_checksum 
     660                        # and invert them. Serious C code mojo follows. 
     661                        payload_checksum &= 0xff 
     662                        payload_checksum = ~payload_checksum & 0xff 
     663                         
     664                         
     665                        # Parse [CKSUM] byte 
     666                        packet_checksum = self.device.read() 
     667                        packet_checksum = packet_checksum.encode("hex") 
     668                        packet_checksum = int(packet_checksum, 16) 
     669                         
     670                         
     671                        # Verify [CKSUM] byte against calculated [PAYLOAD...] checksum 
     672                        if packet_checksum != payload_checksum: 
     673                                if self.DEBUG > 1: 
     674                                        print "ERROR: packet checksum does not match" 
     675                                        print "       packet_checksum:", 
     676                                        print packet_checksum 
     677                                        print "       payload_checksum:", 
     678                                        print payload_checksum 
     679                                 
     680                                continue 
     681                         
     682                         
    620683                        else: 
    621                                 if (reply != '\r\n'): 
    622                                         log_reply = string.replace(reply, '\r', '') 
    623                                         log_reply = string.replace(log_reply, '\n', '') 
    624                                         #self.log.pdebug(log_reply) 
    625                                 response.append(reply) 
    626  
    627                 #self.log.debug(response) 
    628                 if self.DEBUG: 
    629                         print "DEBUG:", 
    630                         print response 
    631  
    632                 return (response, modem_timed_out) 
    633  
    634  
    635         ################################################################## 
    636  
    637         def test_modem(self, modem): 
    638  
    639                 # This function simply sends an "AT" command to the modem 
    640                 # and checks for a reponse. It is useful for verifying 
    641                 # that the modem is attached, configured, and functioning correctly 
    642  
    643                 modem.write("AT\r") 
    644                 (response, modem_timed_out) = read_response(modem) 
     684                                # Since [CKSUM] is OK, parse the Data Payload 
     685                                if self.DEBUG > 2: 
     686                                        print "packet checksum correct" 
     687                                 
     688                                 
     689                                self.process_data_payload(data_payload) 
     690                         
     691                         
     692                        if self.DEBUG > 1: 
     693                                packet_count += 1 
     694                                if packet_count >= DEBUG_PACKET_COUNT: 
     695                                        print "max debugging count reached, disconnecting" 
     696                                        self.device.close() 
     697                                        sys.exit() 
    645698 
    646699 
     
    674727        #sys.exit(app.exec_()) 
    675728         
    676         server.start() 
    677          
    678          
     729        #server.start() 
     730         
     731        server.parse_stream() 
     732         
     733         
Note: See TracChangeset for help on using the changeset viewer.