source: thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py @ 120

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

thinkgear_emulator/puzzlebox_thinkgear_serial_protocol.py:

  • enhanded debugging and minor cross-platform update
  • Property svn:executable set to *
File size: 9.1 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
15import sys
16import serial
17
18#from PyQt4 import QtCore, QtNetwork
19
20import puzzlebox_thinkgear_emulator_configuration as configuration
21#import puzzlebox_logger
22
23#####################################################################
24# Globals
25#####################################################################
26
27DEBUG = 2
28
29DEFAULT_SERIAL_PORT_WINDOWS = 'COM6'
30DEFAULT_SERIAL_PORT_LINUX = '/dev/rfcomm0'
31
32if (sys.platform == 'win32'):
33        DEFAULT_SERIAL_PORT = DEFAULT_SERIAL_PORT_WINDOWS
34else:
35        DEFAULT_SERIAL_PORT = DEFAULT_SERIAL_PORT_LINUX
36
37DEFAULT_SERIAL_BAUDRATE = 57600
38
39DEFAULT_MINDSET_ADDRESS = '00:13:EF:00:1B:FE'
40
41#####################################################################
42# Classes
43#####################################################################
44
45class puzzlebox_thinkgear_serial_protocol:
46       
47        def __init__(self, log, \
48                               serial_port=DEFAULT_SERIAL_PORT, \
49                               DEBUG=DEBUG, \
50                               parent=None):
51               
52                self.log = log
53                self.DEBUG = DEBUG
54               
55                self.serial_port = serial_port
56                self.device = None
57               
58                self.device = self.initialize_device()
59       
60       
61        ##################################################################
62       
63        def initialize_device(self):
64               
65                baudrate = DEFAULT_SERIAL_BAUDRATE
66                bytesize = 8
67                parity = 'NONE'
68                stopbits = 1
69                software_flow_control = 'f'
70                rts_cts_flow_control = 'f'
71                #timeout = 15
72                timeout = 5
73               
74                # convert bytesize
75                if (bytesize == 5):
76                        init_byte_size = serial.FIVEBITS
77                elif (bytesize == 6):
78                        init_byte_size = serial.SIXBITS
79                elif (bytesize == 7):
80                        init_byte_size = serial.SEVENBITS
81                elif (bytesize == 8):
82                        init_byte_size = serial.EIGHTBITS
83                else:
84                        #self.log.perror("Invalid value for %s modem byte size! Using default (8)" % modem_type)
85                        init_byte_size = serial.EIGHTBITS
86               
87                # convert parity
88                if (parity == 'NONE'):
89                        init_parity = serial.PARITY_NONE
90                elif (parity == 'EVEN'):
91                        init_parity = serial.PARITY_EVEN
92                elif (parity == 'ODD'):
93                        init_parity = serial.PARITY_ODD
94                else:
95                        #self.log.perror("Invalid value for %s modem parity! Using default (NONE)" % modem_type)
96                        init_parity = serial.PARITY_NONE
97               
98                # convert stopbits
99                if (stopbits == 1):
100                        init_stopbits = serial.STOPBITS_ONE
101                elif (stopbits == 2):
102                        init_stopbits = serial.STOPBITS_TWO
103                else:
104                        #self.log.perror("Invalid value for %s modem stopbits! Using default (8)" % modem_type)
105                        init_byte_size = serial.STOPBITS_ONE
106               
107                # convert software flow control
108                if (software_flow_control == 't'):
109                        init_software_flow_control = 1
110                else:
111                        init_software_flow_control = 0
112
113                # convert rts cts flow control
114                if (rts_cts_flow_control == 't'):
115                        init_rts_cts_flow_control = 1
116                else:
117                        init_rts_cts_flow_control = 0
118               
119               
120                # Initialize the modem
121                #self.log.pdebug("Initializing %s modem" % modem_code)
122               
123                device = serial.Serial(port = serial_port, \
124                                            baudrate = baudrate, \
125                                            bytesize = init_byte_size, \
126                                            parity = init_parity, \
127                                            stopbits = init_stopbits, \
128                                            xonxoff = init_software_flow_control, \
129                                            rtscts = init_rts_cts_flow_control, \
130                                            timeout = timeout)
131               
132               
133                return(device)
134       
135       
136        ##################################################################
137       
138        def start(self):
139               
140                #"AT+CKPD=200" - Indicates a Bluetooth button press
141                #"AT+VGM=" - Indicates a microphone volume change
142                #"AT+VGS=" - Indicates a speakerphone volume change
143                #"AT+BRSF=" - The Headset is asking what features are supported
144                #"AT+CIND?" - The Headset is asking about the indicators that are signaled
145                #"AT+CIND=?" - The Headset is asking about the test indicators
146                #"AT+CMER=" - The Headset is asking which indicates are registered for updates
147                #"ATA" - When an incoming call has been answered, usually a Bluetooth button press
148                #"AT+CHUP" - When a call has been hung up, usually a Bluetooth button press
149                #"ATD>" - The Headset is requesting the local device to perform a memory dial
150                #"ATD" - The Headset is requesting to dial the number
151                #"AT+BLDN" - The Headset is requesting to perform last number dialed
152                #"AT+CCWA=" - The Headset has enabled call waiting
153                #"AT+CLIP=" - The Headset has enabled CLI (Calling Line Identification)
154                #"AT+VTS=" - The Headset is asking to send DTMF digits
155                #"AT+CHLD=" - The Headset is asking to put the call on Hold
156                #"AT+BVRA=" - The Headset is requesting voice recognition
157                #"ATH" - Call hang-up
158               
159                #self.device.write('\x29')
160                #self.device.write('AT+BRSF=24\r\n')
161               
162                buffer = ''
163               
164                while True:
165                        reply = self.device.read()
166                       
167                        if (len(reply) != 0):
168                                if DEBUG > 1:
169                                        print reply
170                                buffer += reply
171                       
172                        if buffer == "AT+BRSF=24\r":
173                                print "--> Received:",
174                                print buffer
175                                response = '\r\nOK\r\n'
176                                print "<-- Sending:",
177                                print response.replace('\r\n', '')
178                                self.device.write(response)
179                                buffer = ''
180                       
181                        elif buffer == 'AT+CIND=?\r':
182                                print "--> Received:",
183                                print buffer
184                                # first field indicates that we have cellular service [0-1]
185                                # second field indicates that we're in a call (0 for false) [0-1]
186                                # third field indicates the current call setup (0 for idle) [0-3]
187                                response = '\r\n+CIND: 1,0,0\r\n'
188                                print "<-- Sending:",
189                                print response.replace('\r\n', '')
190                                self.device.write(response)
191                                response = '\r\nOK\r\n'
192                                print "<-- Sending:",
193                                print response.replace('\r\n', '')
194                                self.device.write(response)
195                                buffer = ''
196                       
197                        elif buffer == 'AT+CMER=3, 0, 0, 1\r':
198                                print "--> Received:",
199                                print buffer
200                                response = '\r\nOK\r\n'
201                                print "<-- Sending:",
202                                print response.replace('\r\n', '')
203                                self.device.write(response)
204                                response = '\r\n+CIEV:2,1\r\n'
205                                print "<-- Sending:",
206                                print response.replace('\r\n', '')
207                                self.device.write(response)
208                                response = '\r\n+CIEV:3,0\r\n'
209                                print "<-- Sending:",
210                                print response.replace('\r\n', '')
211                                self.device.write(response)
212                                buffer = ''
213                       
214                        elif buffer == 'AT+VGS=15\r':
215                                print "--> Received:",
216                                print buffer
217                                response = '\r\nOK\r\n'
218                                print "<-- Sending:",
219                                print response.replace('\r\n', '')
220                                self.device.write(response)
221                                buffer = ''
222                       
223                        elif buffer == 'AT+VGM=08\r':
224                                print "--> Received:",
225                                print buffer
226                                response = '\r\nOK\r\n'
227                                print "<-- Sending:",
228                                print response.replace('\r\n', '')
229                                self.device.write(response)
230                                buffer = ''
231                               
232                                self.device.close()
233                                sys.exit()
234
235
236#####################################################################
237#####################################################################
238
239        def read_response(self, modem):
240
241                # This function is passed to the modem each time the software
242                # has asked the modem to perform a particular function.
243                # It looks for an "OK" message from the modem, and stores all
244                # data read back from the modem in a line, one entry per response
245                # line. The function returns that list of responses, as well as
246                # a status flag indicating whether the modem timed out while
247                # waiting for the "OK" response. The timeout gets set during
248                # modem initialization, based on the value stored in the database
249
250                modem_timed_out = 0
251
252                #self.log.pdebug("Waiting for 'OK' from %s modem..." % self.modem_type)
253
254                response = []
255
256                while 'OK\r\n' not in response:
257                        reply = modem.readline()
258                        if (len(reply) == 0):
259                                #self.log.perror("Modem timeout has been exceeded")
260                                modem_timed_out = 1
261                                break # The timeout has been exceeded
262                        else:
263                                if (reply != '\r\n'):
264                                        log_reply = string.replace(reply, '\r', '')
265                                        log_reply = string.replace(log_reply, '\n', '')
266                                        #self.log.pdebug(log_reply)
267                                response.append(reply)
268
269                #self.log.debug(response)
270                if self.DEBUG:
271                        print "DEBUG:",
272                        print response
273
274                return (response, modem_timed_out)
275
276
277        ##################################################################
278
279        def test_modem(self, modem):
280
281                # This function simply sends an "AT" command to the modem
282                # and checks for a reponse. It is useful for verifying
283                # that the modem is attached, configured, and functioning correctly
284
285                modem.write("AT\r")
286                (response, modem_timed_out) = read_response(modem)
287
288
289#####################################################################
290# Main
291#####################################################################
292
293if __name__ == '__main__':
294       
295        # Perform correct KeyboardInterrupt handling
296        #signal.signal(signal.SIGINT, signal.SIG_DFL)
297       
298        #log = puzzlebox_logger.puzzlebox_logger(logfile='server_thinkgear')
299        log = None
300       
301        # Collect default settings and command line parameters
302        serial_port = DEFAULT_SERIAL_PORT
303       
304        for each in sys.argv:
305               
306                if each.startswith("--port="):
307                        serial_port = each[ len("--port="): ]
308       
309       
310        #app = QtCore.QCoreApplication(sys.argv)
311       
312        server = puzzlebox_thinkgear_serial_protocol(log, \
313                                                           serial_port, \
314                                                           DEBUG=DEBUG)
315       
316        #sys.exit(app.exec_())
317       
318        server.start()
319       
320       
Note: See TracBrowser for help on using the repository browser.