2
# vim: ai ts=4 sts=4 et sw=4 encoding=utf-8
4
# arch: pacman -S python-pyserial
5
# debian/ubuntu: apt-get install python-serial
10
class DeviceWrapper(object):
12
def __init__(self, logger, *args, **kwargs):
13
self.device = serial.Serial(*args, **kwargs)
17
return self.device.isOpen()
23
self.device.write(str)
25
def _read(self, read_term=None, read_timeout=None):
26
"""Read from the modem (blocking) until _terminator_ is hit,
27
(defaults to \r\n, which reads a single "line"), and return."""
31
# if a different timeout was requested just
32
# for _this_ read, store and override the
33
# current device setting (not thread safe!)
34
if read_timeout is not None:
35
old_timeout = self.device.timeout
36
self.device.timeout = read_timeout
38
def __reset_timeout():
39
"""restore the device's previous timeout
40
setting, if we overrode it earlier."""
41
if read_timeout is not None:
42
self.device.timeout =\
45
# the default terminator reads
46
# until a newline is hit
51
buf = self.device.read()
53
# if a timeout was hit, raise an exception including the raw data that
54
# we've already read (in case the calling func was _expecting_ a timeout
55
# (wouldn't it be nice if serial.Serial.read returned None for this?)
58
raise(errors.GsmReadTimeoutError(buffer))
60
# if last n characters of the buffer match the read
61
# terminator, return what we've received so far
62
if ''.join(buffer[-len(read_term):]) == read_term:
63
buf_str = ''.join(buffer)
66
self._log(repr(buf_str), 'read')
70
def read_lines(self, read_term=None, read_timeout=None):
71
"""Read from the modem (blocking) one line at a time until a response
72
terminator ("OK", "ERROR", or "CMx ERROR...") is hit, then return
73
a list containing the lines."""
76
# keep on looping until a command terminator
77
# is encountered. these are NOT the same as the
78
# "read_term" argument - only OK or ERROR is valid
82
read_timeout=read_timeout)
87
# most commands return OK for success, but there
88
# are some exceptions. we're not checking those
89
# here (unlike RubyGSM), because they should be
90
# handled when they're _expected_
94
# some errors contain useful error codes, so raise a
95
# proper error with a description from pygsm/errors.py
96
m = re.match(r"^\+(CM[ES]) ERROR: (\d+)$", buf)
98
type, code = m.groups()
99
raise(errors.GsmModemError(type, int(code)))
101
# ...some errors are not so useful
102
# (at+cmee=1 should enable error codes)
104
raise(errors.GsmModemError)
106
def _log(self, str, type="debug"):
107
if hasattr(self, "logger"):
108
self.logger(self, str, type)
b'\\ No newline at end of file'