Skip to content

Commit 217fadb

Browse files
committed
Add chunking for messeages over 512 bytes (#15)
1 parent 787f1df commit 217fadb

File tree

2 files changed

+37
-17
lines changed

2 files changed

+37
-17
lines changed

Hologram/Network/Modem/Modem.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ def connect_socket(self, host, port):
289289
self.logger.info('Connect socket is successful')
290290

291291
def listen_socket(self, port):
292-
293292
at_command_val = "%d,%s" % (self.socket_identifier, port)
294293
self.listen_socket_identifier = self.socket_identifier
295294
ok, _ = self.set('+USOLI', at_command_val, timeout=5)
@@ -298,17 +297,25 @@ def listen_socket(self, port):
298297
raise NetworkError('Failed to listen socket')
299298

300299
def write_socket(self, data):
301-
302300
self.enable_hex_mode()
303-
value = b'%d,%d,\"%s\"' % (self.socket_identifier,
304-
len(data),
305-
binascii.hexlify(data))
306-
ok, _ = self.set('+USOWR', value, timeout=10)
307-
if ok != ModemResult.OK:
308-
self.logger.error('Failed to write to socket')
309-
raise NetworkError('Failed to write socket')
301+
hexdata = binascii.hexlify(data)
302+
# We have to do it in chunks of 510 since 512 is actually too long (CMEE error)
303+
# and we need 2n chars for hexified data
304+
for chunk in self._chunks(hexdata, 510):
305+
value = b'%d,%d,\"%s\"' % (self.socket_identifier,
306+
len(binascii.unhexlify(chunk)),
307+
chunk)
308+
ok, _ = self.set('+USOWR', value, timeout=10)
309+
if ok != ModemResult.OK:
310+
self.logger.error('Failed to write to socket')
311+
raise NetworkError('Failed to write socket')
310312
self.disable_hex_mode()
311313

314+
def _chunks(self, data, n):
315+
"""Yield successive n-sized chunks from lst."""
316+
for i in range(0, len(data), n):
317+
yield data[i:i + n]
318+
312319
def read_socket(self, socket_identifier=None, payload_length=None):
313320

314321
if socket_identifier is None:

tests/Modem/test_Modem.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ def mock_open_serial_port(modem, device_name=None):
3232
def mock_close_serial_port(modem):
3333
return True
3434

35+
def mock_result(modem):
36+
return (ModemResult.OK, None)
37+
3538
def mock_detect_usable_serial_port(modem, stop_on_first=True):
3639
return '/dev/ttyUSB0'
3740

@@ -54,9 +57,14 @@ def no_serial_port(monkeypatch):
5457
def get_sms(monkeypatch):
5558
monkeypatch.setattr(Modem, 'command', mock_command_sms)
5659
monkeypatch.setattr(Modem, 'set', mock_set_sms)
60+
def override_command_result(monkeypatch):
61+
monkeypatch.setattr(Modem, '_command_result', mock_result)
5762

58-
# CONSTRUCTOR
63+
@pytest.fixture
64+
def override_command_result(monkeypatch):
65+
monkeypatch.setattr(Modem, '_command_result', mock_result)
5966

67+
# CONSTRUCTOR
6068

6169
def test_init_modem_no_args(no_serial_port):
6270
modem = Modem()
@@ -80,10 +88,8 @@ def test_get_result_string(no_serial_port):
8088
assert(modem.getResultString(-3) == 'Modem response doesn\'t match expected return value')
8189
assert(modem.getResultString(-99) == 'Unknown response code')
8290

83-
8491
# PROPERTIES
8592

86-
8793
def test_get_location(no_serial_port):
8894
modem = Modem()
8995
with pytest.raises(NotImplementedError) as e:
@@ -99,8 +105,19 @@ def test_get_sms(no_serial_port, get_sms):
99105
assert(res.timestamp == datetime.utcfromtimestamp(1498264009))
100106
assert(res.message == 'Test 123')
101107

102-
# DEBUGWRITE
108+
# WRITE SOCKET
109+
110+
def test_socket_write_under_512(no_serial_port, override_command_result):
111+
modem = Modem()
112+
data = '{message:{fill}{align}{width}}'.format(message='Test-', fill='@', align='<', width=64)
113+
modem.write_socket(data.encode())
114+
115+
def test_socket_write_over_512(no_serial_port, override_command_result):
116+
modem = Modem()
117+
data = '{message:{fill}{align}{width}}'.format(message='Test-', fill='@', align='<', width=600)
118+
modem.write_socket(data.encode())
103119

120+
# DEBUGWRITE
104121

105122
def test_debugwrite(no_serial_port):
106123
modem = Modem()
@@ -111,10 +128,8 @@ def test_debugwrite(no_serial_port):
111128
modem.debugwrite('test222', hide=True)
112129
assert(modem.debug_out == 'test') # debug_out shouldn't change since hide is enabled.
113130

114-
115131
# MODEMWRITE
116132

117-
118133
def test_modemwrite(no_serial_port):
119134
modem = Modem()
120135
assert(modem.debug_out == '')
@@ -136,7 +151,6 @@ def test_modemwrite(no_serial_port):
136151
modem.modemwrite('test5', start=True, at=True, seteq=True, read=True, end=True)
137152
assert(modem.debug_out == '[ATtest5=?]')
138153

139-
140154
# COMMAND_RESULT
141155

142156
def test_command_result(no_serial_port):
@@ -193,7 +207,6 @@ def test_command_result(no_serial_port):
193207

194208
# HANDLEURC
195209

196-
197210
# These are static methods that can be tested independently.
198211
# We decided to wrap it all here under this test object
199212
class TestModemProtectedStaticMethods():

0 commit comments

Comments
 (0)