3 # Handle a connection to an AT device via gsm0710muxd
4 # If this is a 'master', we can reset the modem, else
5 # any misbehaviour requires that we fail (FIXME not implemented)
7 # We directly support high level commands (get/set_power, reset_modem
8 # etc) but don't know anything about AT commands - we just send them
9 # through and hand back reply. Replies also go via a callback
10 # We also provide timeout support, but someone else needs to tell us
11 # when to set a timeout, and when to clear it.
13 # This is usually subclassed by code with an agenda.
15 import gobject, sys, os, time
20 def __init__(self, path = '/var/run/gsm-mux', master = False):
23 self.connected = False
24 self.command_mode = False
36 gobject.source_remove(self.watcher)
41 self.connected = False
44 log("connect to", self.path)
45 s = socket(AF_UNIX, SOCK_STREAM)
47 self.watcher = gobject.io_add_watch(s, gobject.IO_IN, self.readdata)
50 self.command_mode = True
51 self.command_pending = False
53 def command(self, str):
54 if not self.connected or not self.command_mode:
56 log("send command", str)
57 if not self.command_pending:
58 self.command_pending = str
59 self.sock.sendall(str + '\n')
60 self.set_timeout(30000)
62 def readdata(self, io, arg):
63 r = self.sock.recv(1000)
73 def getline(self, line):
75 log("Receive cmd response", line, "to", self.command_pending)
76 if line == "OK" and self.command_pending == "connect":
77 log("Leaving command mode")
78 self.command_mode = False
81 gobject.source_remove(self.timer)
83 if self.command_pending:
84 if line[0:2] == "OK" or line[0:5] == "ERROR":
85 self.command_pending = False
88 log("receive AT response", line)
89 if self.takeline(line):
92 gobject.source_remove(self.timer)
95 def set_power(self, state):
96 if state and self.power == True:
97 return gobject.idle_add(self.power_done)
98 if not state and self.power == False:
99 return gobject.idle_add(self.power_done)
100 # OK, I need to do something
101 if self.connected and not self.command_mode:
103 if not self.connected:
105 self.command_pending = "power"
107 self.command("set_power 1")
110 self.command("set_power 0")
114 if self.connected and not self.command_mode:
116 if not self.connected:
118 self.command_pending = "reset"
119 self.command("reset_modem")
123 if not self.connected:
125 if not self.command_mode:
126 return self.power_done()
127 self.command_pending = "connect"
128 self.command("connect")
131 def atcmd(self, cmd, timeout = 2000):
133 Send the command, preceeded by 'AT' and set a timeout.
134 self.takeline() should return True when the command
135 has been responded to, otherwise we will call
136 self.timedout() after the time.
138 self.set_timeout(timeout)
139 log("send AT command", cmd, timeout)
140 self.sock.sendall('AT' + cmd + '\r')
142 def timer_fired(self):
149 def set_timeout(self, delay):
152 self.timer = gobject.timeout_add(delay, self.timer_fired)
155 def cancel_timeout(self):
157 gobject.source_remove(self.timer)
160 def abort_timeout(self):
162 self.cancel_timeout()
165 # these are likely to be over-ridden by a child class
166 def power_done(self, line=None):
167 self.linelist.append(line)
168 def takeline(self, line):
169 self.linelist.append(line)
171 def wait_line(self, timeout):
172 self.cancel_timeout()
173 c = gobject.main_context_default()
174 while not self.linelist: