source: thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py @ 124

Last change on this file since 124 was 124, checked in by sc, 11 years ago

thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py:

  • stream parsing rewritten for more efficient processing
  • Property svn:executable set to *
File size: 21.5 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3#
4# Puzzlebox - Brainstorms - Network - Server - ThinkGear - Serial Protocol
5#
6# Copyright Puzzlebox Productions, LLC (2010)
7#
8# This code is released under the GNU Pulic License (GPL) version 2
9# For more information please refer to http://www.gnu.org/copyleft/gpl.html
10#
11# Last Update: 2010.07.22
12#
13#####################################################################
14# SPEC:
15#
16# CODE Definitions Table
17# Single-Byte CODEs
18# Extended             (Byte)
19# Code Level   [CODE] [LENGTH] Data Value Meaning
20# ----------   ------ -------- ------------------
21#           0    0x02        - POOR_SIGNAL Quality (0-255)
22#           0    0x04        - ATTENTION eSense (0 to 100)
23#           0    0x05        - MEDITATION eSense (0 to 100)
24#           0    0x16        - Blink Strength. (0-255) Sent only
25#                              when Blink event occurs.
26# Multi-Byte CODEs
27# Extended             (Byte)
28# Code Level   [CODE] [LENGTH] Data Value Meaning
29# ----------   ------ -------- ------------------
30#           0    0x80        2 RAW Wave Value: a single big-endian
31#                                16-bit two's-compliment signed value
32#                                (high-order byte followed by
33#                                low-order byte) (-32768 to 32767)
34#           0    0x83       24 ASIC_EEG_POWER: eight big-endian
35#                                3-byte unsigned integer values
36#                                representing delta, theta, low-alpha
37#                                high-alpha, low-beta, high-beta,
38#                                low-gamma, and mid-gamma EEG band
39#                                power values
40#         Any    0x55        - NEVER USED (reserved for [EXCODE])
41#         Any    0xAA        - NEVER USED (reserved for [SYNC])
42#
43#####################################################################
44# Linux Bluetooth serial protocol profile example:
45#    rfcomm connect rfcomm0 00:13:EF:00:1B:FE 3
46#####################################################################
47# TODO:
48# - needs to handle:
49#   serial.serialutil.SerialException:
50#   could not open port /dev/rfcomm0:
51#   [Errno 16] Device or resource busy: '/dev/rfcomm0'
52#####################################################################
53
54import sys
55import serial
56
57#from PyQt4 import QtCore, QtNetwork
58
59import puzzlebox_thinkgear_emulator_configuration as configuration
60#import puzzlebox_logger
61
62#####################################################################
63# Globals
64#####################################################################
65
66DEBUG = 2
67
68DEFAULT_SERIAL_PORT_WINDOWS = 'COM2'
69DEFAULT_SERIAL_PORT_LINUX = '/dev/rfcomm0'
70
71if (sys.platform == 'win32'):
72        DEFAULT_SERIAL_PORT = DEFAULT_SERIAL_PORT_WINDOWS
73else:
74        DEFAULT_SERIAL_PORT = DEFAULT_SERIAL_PORT_LINUX
75
76DEFAULT_SERIAL_BAUDRATE = 57600
77
78DEFAULT_MINDSET_ADDRESS = '00:13:EF:00:1B:FE'
79
80PROTOCOL_SYNC = '\xAA'
81PROTOCOL_EXCODE = '\x55'
82
83DEBUG_BYTE_COUNT = 819200
84DEBUG_PACKET_COUNT = 128
85
86#####################################################################
87# Classes
88#####################################################################
89
90class puzzlebox_thinkgear_serial_protocol:
91       
92        def __init__(self, log, \
93                               serial_port=DEFAULT_SERIAL_PORT, \
94                               DEBUG=DEBUG, \
95                               parent=None):
96               
97                self.log = log
98                self.DEBUG = DEBUG
99               
100                self.serial_port = serial_port
101                self.device = None
102                self.buffer = ''
103               
104                self.device = self.initialize_device()
105       
106       
107        ##################################################################
108       
109        def initialize_device(self):
110               
111                baudrate = DEFAULT_SERIAL_BAUDRATE
112                bytesize = 8
113                parity = 'NONE'
114                stopbits = 1
115                software_flow_control = 'f'
116                rts_cts_flow_control = 'f'
117                #timeout = 15
118                timeout = 5
119               
120                # convert bytesize
121                if (bytesize == 5):
122                        init_byte_size = serial.FIVEBITS
123                elif (bytesize == 6):
124                        init_byte_size = serial.SIXBITS
125                elif (bytesize == 7):
126                        init_byte_size = serial.SEVENBITS
127                elif (bytesize == 8):
128                        init_byte_size = serial.EIGHTBITS
129                else:
130                        #self.log.perror("Invalid value for %s modem byte size! Using default (8)" % modem_type)
131                        init_byte_size = serial.EIGHTBITS
132               
133                # convert parity
134                if (parity == 'NONE'):
135                        init_parity = serial.PARITY_NONE
136                elif (parity == 'EVEN'):
137                        init_parity = serial.PARITY_EVEN
138                elif (parity == 'ODD'):
139                        init_parity = serial.PARITY_ODD
140                else:
141                        #self.log.perror("Invalid value for %s modem parity! Using default (NONE)" % modem_type)
142                        init_parity = serial.PARITY_NONE
143               
144                # convert stopbits
145                if (stopbits == 1):
146                        init_stopbits = serial.STOPBITS_ONE
147                elif (stopbits == 2):
148                        init_stopbits = serial.STOPBITS_TWO
149                else:
150                        #self.log.perror("Invalid value for %s modem stopbits! Using default (8)" % modem_type)
151                        init_byte_size = serial.STOPBITS_ONE
152               
153                # convert software flow control
154                if (software_flow_control == 't'):
155                        init_software_flow_control = 1
156                else:
157                        init_software_flow_control = 0
158               
159                # convert rts cts flow control
160                if (rts_cts_flow_control == 't'):
161                        init_rts_cts_flow_control = 1
162                else:
163                        init_rts_cts_flow_control = 0
164               
165               
166                # Initialize the modem
167                #self.log.pdebug("Initializing %s modem" % modem_code)
168               
169                device = serial.Serial(port = serial_port, \
170                                            baudrate = baudrate, \
171                                            bytesize = init_byte_size, \
172                                            parity = init_parity, \
173                                            stopbits = init_stopbits, \
174                                            xonxoff = init_software_flow_control, \
175                                            rtscts = init_rts_cts_flow_control, \
176                                            timeout = timeout)
177               
178               
179                return(device)
180       
181       
182        ##################################################################
183       
184        def communicate_with_handsfree_profile(self):
185               
186                #"AT+CKPD=200" - Indicates a Bluetooth button press
187                #"AT+VGM=" - Indicates a microphone volume change
188                #"AT+VGS=" - Indicates a speakerphone volume change
189                #"AT+BRSF=" - The Headset is asking what features are supported
190                #"AT+CIND?" - The Headset is asking about the indicators that are signaled
191                #"AT+CIND=?" - The Headset is asking about the test indicators
192                #"AT+CMER=" - The Headset is asking which indicates are registered for updates
193                #"ATA" - When an incoming call has been answered, usually a Bluetooth button press
194                #"AT+CHUP" - When a call has been hung up, usually a Bluetooth button press
195                #"ATD>" - The Headset is requesting the local device to perform a memory dial
196                #"ATD" - The Headset is requesting to dial the number
197                #"AT+BLDN" - The Headset is requesting to perform last number dialed
198                #"AT+CCWA=" - The Headset has enabled call waiting
199                #"AT+CLIP=" - The Headset has enabled CLI (Calling Line Identification)
200                #"AT+VTS=" - The Headset is asking to send DTMF digits
201                #"AT+CHLD=" - The Headset is asking to put the call on Hold
202                #"AT+BVRA=" - The Headset is requesting voice recognition
203                #"ATH" - Call hang-up
204               
205                #self.device.write('\x29')
206                #self.device.write('AT+BRSF=24\r\n')
207               
208                buffer = ''
209               
210                while True:
211                        reply = self.device.read()
212                       
213                        if (len(reply) != 0):
214                                if DEBUG > 1:
215                                        print reply
216                                buffer += reply
217                       
218                        if buffer == "AT+BRSF=24\r":
219                                print "--> Received:",
220                                print buffer
221                                response = '\r\nOK\r\n'
222                                print "<-- Sending:",
223                                print response.replace('\r\n', '')
224                                self.device.write(response)
225                                buffer = ''
226                       
227                        elif buffer == 'AT+CIND=?\r':
228                                print "--> Received:",
229                                print buffer
230                                # first field indicates that we have cellular service [0-1]
231                                # second field indicates that we're in a call (0 for false) [0-1]
232                                # third field indicates the current call setup (0 for idle) [0-3]
233                                response = '\r\n+CIND: 1,0,0\r\n'
234                                print "<-- Sending:",
235                                print response.replace('\r\n', '')
236                                self.device.write(response)
237                                response = '\r\nOK\r\n'
238                                print "<-- Sending:",
239                                print response.replace('\r\n', '')
240                                self.device.write(response)
241                                buffer = ''
242                       
243                        elif buffer == 'AT+CMER=3, 0, 0, 1\r':
244                                print "--> Received:",
245                                print buffer
246                                response = '\r\nOK\r\n'
247                                print "<-- Sending:",
248                                print response.replace('\r\n', '')
249                                self.device.write(response)
250                                response = '\r\n+CIEV:2,1\r\n'
251                                print "<-- Sending:",
252                                print response.replace('\r\n', '')
253                                self.device.write(response)
254                                response = '\r\n+CIEV:3,0\r\n'
255                                print "<-- Sending:",
256                                print response.replace('\r\n', '')
257                                self.device.write(response)
258                                buffer = ''
259                       
260                        elif buffer == 'AT+VGS=15\r':
261                                print "--> Received:",
262                                print buffer
263                                response = '\r\nOK\r\n'
264                                print "<-- Sending:",
265                                print response.replace('\r\n', '')
266                                self.device.write(response)
267                                buffer = ''
268                       
269                        elif buffer == 'AT+VGM=08\r':
270                                print "--> Received:",
271                                print buffer
272                                response = '\r\nOK\r\n'
273                                print "<-- Sending:",
274                                print response.replace('\r\n', '')
275                                self.device.write(response)
276                                buffer = ''
277                               
278                                self.device.close()
279                                sys.exit()
280       
281       
282        ##################################################################
283       
284        def process_data_row(self, extended_code_level, code, length, data_values):
285               
286                '''CODE Definitions Table
287                   Single-Byte CODEs
288                   Extended             (Byte)
289                   Code Level   [CODE] [LENGTH] Data Value Meaning
290                   ----------   ------ -------- ------------------
291                             0    0x02        - POOR_SIGNAL Quality (0-255)
292                             0    0x04        - ATTENTION eSense (0 to 100)
293                             0    0x05        - MEDITATION eSense (0 to 100)
294                             0    0x16        - Blink Strength. (0-255) Sent only
295                                                when Blink event occurs.
296                   Multi-Byte CODEs
297                   Extended             (Byte)
298                   Code Level   [CODE] [LENGTH] Data Value Meaning
299                   ----------   ------ -------- ------------------
300                             0    0x80        2 RAW Wave Value: a single big-endian
301                                                  16-bit two's-compliment signed value
302                                                  (high-order byte followed by
303                                                  low-order byte) (-32768 to 32767)
304                             0    0x83       24 ASIC_EEG_POWER: eight big-endian
305                                                  3-byte unsigned integer values
306                                                  representing delta, theta, low-alpha
307                                                  high-alpha, low-beta, high-beta,
308                                                  low-gamma, and mid-gamma EEG band
309                                                  power values
310                           Any    0x55        - NEVER USED (reserved for [EXCODE])
311                           Any    0xAA        - NEVER USED (reserved for [SYNC])'''
312               
313               
314                if extended_code_level == 0:
315                       
316                        if code == '02':
317                                poor_signal_quality = int(data_values, 16)
318                                if self.DEBUG > 1:
319                                        print "POOR_SIGNAL Quality:",
320                                        print poor_signal_quality
321                       
322                        elif code == '04':
323                                attention = int(data_values, 16)
324                                if self.DEBUG > 1:
325                                        print "ATTENTION:",
326                                        print attention
327                       
328                        elif code == '05':
329                                meditation = int(data_values, 16)
330                                if self.DEBUG > 1:
331                                        print "MEDITATION:",
332                                        print meditation
333                       
334                        elif code == '16':
335                                blink_strength = int(data_values, 16)
336                                if self.DEBUG > 1:
337                                        print "Blink Strength:",
338                                        print blink_strength
339                       
340                        elif code == '80':
341                                raw_wave_value = data_values
342                                if self.DEBUG > 2:
343                                        print "Raw EEG:",
344                                        print raw_wave_value
345                       
346                        elif code == '83':
347                                asic_eeg_power = data_values
348                                if self.DEBUG > 1:
349                                        print "ASIC_EEG_POWER:",
350                                        print asic_eeg_power
351                               
352                        else:
353                                if self.DEBUG:
354                                        print "ERROR: data payload row code not matched"
355       
356       
357        ##################################################################
358       
359        def process_data_payload(self, data_payload):
360               
361                '''A DataRow consists of bytes in the following format:
362                ([EXCODE]...) [CODE] ([VLENGTH])   [VALUE...]
363                ____________________ ____________ ___________
364                ^^^^(Value Type)^^^^ ^^(length)^^ ^^(value)^^'''
365               
366                if self.DEBUG > 2:
367                        print "data payload:",
368                        for byte in data_payload:
369                                print byte.encode("hex"),
370                        print
371               
372                byte_index = 0
373               
374                # Parse the extended_code_level, code, and length
375                while (byte_index < len(data_payload)):
376                        extended_code_level = 0
377                       
378                        # 1. Parse and count the number of [EXCODE] (0x55)
379                        #    bytes that may be at the beginning of the
380                        #    current DataRow.
381                        while (data_payload[byte_index] == PROTOCOL_EXCODE):
382                                extended_code_level += 1
383                                byte_index += 1
384                       
385                        # 2. Parse the [CODE] byte for the current DataRow.
386                        code = data_payload[byte_index]
387                        byte_index += 1
388                        code = code.encode("hex")
389                       
390                        # 3. If [CODE] >= 0x80, parse the next byte as the
391                        #    [VLENGTH] byte for the current DataRow.
392                        if (code > '\x7f'.encode("hex")):
393                                length = data_payload[byte_index]
394                                byte_index += 1
395                                length = length.encode("hex")
396                                length = int(length, 16)
397                        else:
398                                length = 1
399                       
400                       
401                        if self.DEBUG > 2:
402                                print "EXCODE level:",
403                                print extended_code_level,
404                                print " CODE:",
405                                print code,
406                                print " length:",
407                                print length
408                                print type(code)
409                       
410                        data_values = ''
411                        value_index = 0
412                       
413                        # 4. Parse and handle the [VALUE...] byte(s) of the current
414                        #    DataRow, based on the DataRow's [EXCODE] level, [CODE],
415                        #    and [VLENGTH] (refer to the Code De nitions Table).
416                        while value_index < length:
417                                # Uh-oh more C mojo
418                                value = data_payload[(byte_index + value_index)] # & 0xFF
419                                data_values += value.encode("hex")
420                                value_index += 1
421                       
422                        if self.DEBUG > 2:
423                                print "Data Values:",
424                                print data_values
425                                print
426                       
427                        self.process_data_row(extended_code_level, \
428                                              code, \
429                                              length, \
430                                              data_values)
431                       
432                        byte_index += length
433                       
434                        # 5. If not all bytes have been parsed from the payload[] array,
435                        # return to step 1. to continue parsing the next DataRow.
436       
437       
438        ##################################################################
439       
440        def process_packet(self, packet):
441               
442                '''Each Packet begins with its Header, followed by its Data Payload,
443                and ends with the Payload's Check-sum Byte, as follows:
444                [SYNC] [SYNC] [PLENGTH]      [PAYLOAD...]         [CHKSUM]
445                _______________________      _____________     ____________
446                ^^^^^^^^(Header)^^^^^^^      ^^(Payload)^^     ^(Checksum)^'''
447               
448                valid_length = False
449                valid_checksum = False
450               
451                if self.DEBUG > 2:
452                        print packet
453               
454               
455                # SPEC: [PLENGTH] byte indicates the length, in bytes, of the
456                # Packet's Data Payload [PAYLOAD...] section, and may be any value
457                # from 0 up to 169. Any higher value indicates an error
458                # (PLENGTH TOO LARGE). Be sure to note that [PLENGTH] is the length
459                # of the Packet's Data Payload, NOT of the entire Packet.
460                # The Packet's complete length will always be [PLENGTH] + 4.
461               
462                packet_length = packet[2]
463                packet_length = packet_length.encode("hex")
464                packet_length = int(packet_length, 16)
465               
466                if ((packet_length <= 169) and \
467                         (packet_length + 4) == (len(packet))):
468                       
469                        if self.DEBUG > 2:
470                                print "packet length correct"
471                       
472                        valid_length = True
473               
474                else:
475                        if self.DEBUG:
476                                print "ERROR: packet length bad"
477               
478               
479                if valid_length:
480                       
481                        data_payload = packet[3:-1]
482                       
483                        # SPEC: The [CHKSUM] Byte must be used to verify the integrity of the
484                        # Packet's Data Payload. The Payload's Checksum is defined as:
485                        #  1. summing all the bytes of the Packet's Data Payload
486                        #  2. taking the lowest 8 bits of the sum
487                        #  3. performing the bit inverse (one's compliment inverse)
488                        #     on those lowest 8 bits
489                       
490                        packet_checksum = packet[-1]
491                        packet_checksum = packet_checksum.encode("hex")
492                        packet_checksum = int(packet_checksum, 16)
493                       
494                        payload_checksum = 0
495                        for byte in data_payload:
496                                value = byte.encode("hex")
497                                value = int(value, 16)
498                                payload_checksum += value
499                       
500                        # Take the lowest 8 bits of the calculated payload_checksum
501                        # and invert them. Serious C code mojo.
502                        payload_checksum &= 0xff
503                        payload_checksum = ~payload_checksum & 0xff
504                       
505                       
506                        if packet_checksum != payload_checksum:
507                                if self.DEBUG > 1:
508                                        print "ERROR: packet checksum does not match"
509                                        print "       packet_checksum:",
510                                        print packet_checksum
511                                        print "       payload_checksum:",
512                                        print payload_checksum
513                       
514                        else:
515                                valid_checksum = True
516                                if self.DEBUG > 2:
517                                        print "packet checksum correct"
518                                       
519                                self.process_data_payload(data_payload)
520               
521               
522                return(valid_length, valid_checksum)
523       
524       
525        ##################################################################
526       
527        def process_byte(self, byte):
528               
529                self.buffer += byte
530                self.byte_count += 1
531               
532                if (len(self.buffer) > 2):
533                        if self.buffer[-2:] == '\xAA\xAA':
534                                # New packet header found
535                               
536                                (valid_length, valid_checksum) = self.process_packet(self.buffer[:-2])
537                               
538                                if ((valid_length) or \
539                                         (len(self.buffer) > 173)):
540                                        # If processing the packet returned valid checks then we
541                                        # restart reading the buffer to examine new packages.
542                                        # However if the current buffer size is larger than 173 bytes
543                                        # (the maximum possible packet length according to the protocol
544                                        # specification document, then we still want to reset the buffer
545                                        # because an error has occured in the stream)
546                                        self.buffer = '\xAA\xAA'
547                                        self.packet_count += 1
548               
549               
550                elif self.buffer == "AT+BRSF=24\r":
551                        # This string is received when connecting to the wrong
552                        # Bluetooth serial device channel of the ThinkGear device
553                        if self.DEBUG:
554                                print "--> Received:",
555                                print self.buffer
556                        response = '\r\nOK\r\n'
557                        if self.DEBUG:
558                                print "<-- Sending:",
559                                print response.replace('\r\n', '')
560                        self.device.write(response)
561                        self.buffer = ''
562                       
563                        if self.DEBUG:
564                                print "ERROR: Serial device connected to wrong channel"
565                                print "(Consider changing from channel 1 to channel 3",
566                                print " or another COM port for example)"
567                       
568                        self.device.close()
569                        sys.exit()
570               
571               
572                if ((self.DEBUG > 2) and \
573                         ((self.byte_count >= DEBUG_BYTE_COUNT) or \
574                          (self.packet_count >= DEBUG_PACKET_COUNT))):
575                        if self.DEBUG:
576                                print "max debugging count reached, disconnecting"
577                        self.device.close()
578                        sys.exit()
579       
580       
581        ##################################################################
582       
583        def start(self):
584               
585                self.buffer = ''
586                self.packet_count = 0
587                self.byte_count = 0
588               
589                while True:
590                       
591                        byte = self.device.read()
592                       
593                        if (len(byte) != 0):
594                                if DEBUG > 2:
595                                        print byte
596                                       
597                                self.process_byte(byte)
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                       
683                        else:
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()
698
699
700#####################################################################
701# Main
702#####################################################################
703
704if __name__ == '__main__':
705       
706        # Perform correct KeyboardInterrupt handling
707        #signal.signal(signal.SIGINT, signal.SIG_DFL)
708       
709        #log = puzzlebox_logger.puzzlebox_logger(logfile='server_thinkgear')
710        log = None
711       
712        # Collect default settings and command line parameters
713        serial_port = DEFAULT_SERIAL_PORT
714       
715        for each in sys.argv:
716               
717                if each.startswith("--port="):
718                        serial_port = each[ len("--port="): ]
719       
720       
721        #app = QtCore.QCoreApplication(sys.argv)
722       
723        server = puzzlebox_thinkgear_serial_protocol(log, \
724                                                           serial_port, \
725                                                           DEBUG=DEBUG)
726       
727        #sys.exit(app.exec_())
728       
729        #server.start()
730       
731        server.parse_stream()
732       
733       
Note: See TracBrowser for help on using the repository browser.