Skip to content

Commit 71c4bde

Browse files
raise an authentication error if its unable to get keys, consolidate common code (#115)
1 parent a3bf1cb commit 71c4bde

File tree

17 files changed

+571
-380
lines changed

17 files changed

+571
-380
lines changed

Hologram/HologramCloud.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from Hologram.CustomCloud import CustomCloud
1515
from HologramAuth import TOTPAuthentication, SIMOTPAuthentication
1616
from Hologram.Authentication import CSRPSKAuthentication
17-
from Exceptions.HologramError import HologramError
17+
from Exceptions.HologramError import HologramError, AuthenticationError
1818

1919
DEFAULT_SEND_MESSAGE_TIMEOUT = 5
2020
HOLOGRAM_HOST_SEND = 'cloudsocket.hologram.io'
@@ -125,6 +125,7 @@ def __populate_totp_credentials(self):
125125
self.authentication.credentials['private_key'] = self.network.imsi
126126
except Exception as e:
127127
self.logger.error('Unable to fetch device id or private key')
128+
raise AuthenticationError('Unable to fetch device id or private key for TOTP authenication')
128129

129130
def __populate_sim_otp_credentials(self):
130131
nonce = self.request_hex_nonce()

Hologram/Network/Modem/BG96.py

Lines changed: 4 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -7,183 +7,17 @@
77
#
88
# LICENSE: Distributed under the terms of the MIT License
99
#
10-
import binascii
11-
import time
1210

13-
from serial.serialutil import Timeout
14-
15-
from Hologram.Network.Modem import Modem
16-
from Hologram.Event import Event
11+
from Hologram.Network.Modem.Quectel import Quectel
1712
from UtilClasses import ModemResult
18-
from Exceptions.HologramError import SerialError, NetworkError
1913

2014
DEFAULT_BG96_TIMEOUT = 200
2115

22-
class BG96(Modem):
16+
class BG96(Quectel):
2317
usb_ids = [('2c7c', '0296')]
24-
25-
def __init__(self, device_name=None, baud_rate='9600',
26-
chatscript_file=None, event=Event()):
27-
28-
super().__init__(device_name=device_name, baud_rate=baud_rate,
29-
chatscript_file=chatscript_file, event=event)
30-
self._at_sockets_available = True
31-
self.urc_response = ''
32-
18+
3319
def connect(self, timeout=DEFAULT_BG96_TIMEOUT):
34-
35-
success = super().connect(timeout)
36-
37-
# put serial mode on other port
38-
# if success is True:
39-
# # detect another open serial port to use for PPP
40-
# devices = self.detect_usable_serial_port()
41-
# if not devices:
42-
# raise SerialError('Not enough serial ports detected for Nova')
43-
# self.logger.debug('Moving connection to port %s', devices[0])
44-
# self.device_name = devices[0]
45-
# super().initialize_serial_interface()
46-
47-
return success
48-
49-
def send_message(self, data, timeout=Modem.DEFAULT_SEND_TIMEOUT):
50-
# Waiting for the open socket urc
51-
while self.urc_state != Modem.SOCKET_WRITE_STATE:
52-
self.checkURC()
53-
54-
self.write_socket(data)
55-
56-
loop_timeout = Timeout(timeout)
57-
while self.urc_state != Modem.SOCKET_SEND_READ:
58-
self.checkURC()
59-
if self.urc_state != Modem.SOCKET_SEND_READ:
60-
if loop_timeout.expired():
61-
raise SerialError('Timeout occurred waiting for message status')
62-
time.sleep(self._RETRY_DELAY)
63-
elif self.urc_state == Modem.SOCKET_CLOSED:
64-
return '[1,0]' #this is connection closed for hologram cloud response
65-
66-
return self.urc_response
67-
68-
def create_socket(self):
69-
self._set_up_pdp_context()
70-
71-
def connect_socket(self, host, port):
72-
self.command('+QIOPEN', '1,0,\"TCP\",\"%s\",%d,0,1' % (host, port))
73-
# According to the BG96 Docs
74-
# Have to wait for URC response “+QIOPEN: <connectID>,<err>”
75-
76-
def close_socket(self, socket_identifier=None):
77-
ok, _ = self.command('+QICLOSE', self.socket_identifier)
78-
if ok != ModemResult.OK:
79-
self.logger.error('Failed to close socket')
80-
self.urc_state = Modem.SOCKET_CLOSED
81-
self._tear_down_pdp_context()
82-
83-
def write_socket(self, data):
84-
hexdata = binascii.hexlify(data)
85-
# We have to do it in chunks of 510 since 512 is actually too long (CMEE error)
86-
# and we need 2n chars for hexified data
87-
for chunk in self._chunks(hexdata, 510):
88-
value = '%d,\"%s\"' % (self.socket_identifier, chunk.decode())
89-
ok, _ = self.set('+QISENDEX', value, timeout=10)
90-
if ok != ModemResult.OK:
91-
self.logger.error('Failed to write to socket')
92-
raise NetworkError('Failed to write to socket')
93-
94-
def read_socket(self, socket_identifier=None, payload_length=None):
95-
96-
if socket_identifier is None:
97-
socket_identifier = self.socket_identifier
98-
99-
if payload_length is None:
100-
payload_length = self.last_read_payload_length
101-
102-
ok, resp = self.set('+QIRD', '%d,%d' % (socket_identifier, payload_length))
103-
if ok == ModemResult.OK:
104-
resp = resp.lstrip('+QIRD: ')
105-
if resp is not None:
106-
resp = resp.strip('"')
107-
try:
108-
resp = resp.decode()
109-
except:
110-
# This is some sort of binary data that can't be decoded so just
111-
# return the bytes. We might want to make this happen via parameter
112-
# in the future so it is more deterministic
113-
self.logger.debug('Could not decode recieved data')
114-
115-
return resp
116-
117-
def is_registered(self):
118-
return self.check_registered('+CREG') or self.check_registered('+CGREG')
119-
120-
# EFFECTS: Handles URC related AT command responses.
121-
def handleURC(self, urc):
122-
if urc.startswith('+QIOPEN: '):
123-
response_list = urc.lstrip('+QIOPEN: ').split(',')
124-
socket_identifier = int(response_list[0])
125-
err = int(response_list[-1])
126-
if err == 0:
127-
self.urc_state = Modem.SOCKET_WRITE_STATE
128-
self.socket_identifier = socket_identifier
129-
else:
130-
self.logger.error('Failed to open socket')
131-
raise NetworkError('Failed to open socket')
132-
return
133-
if urc.startswith('+QIURC: '):
134-
response_list = urc.lstrip('+QIURC: ').split(',')
135-
urctype = response_list[0]
136-
if urctype == '\"recv\"':
137-
self.urc_state = Modem.SOCKET_SEND_READ
138-
self.socket_identifier = int(response_list[1])
139-
self.last_read_payload_length = int(response_list[2])
140-
self.urc_response = self._readline_from_serial_port(5)
141-
if urctype == '\"closed\"':
142-
self.urc_state = Modem.SOCKET_CLOSED
143-
self.socket_identifier = int(response_list[-1])
144-
return
145-
super().handleURC(urc)
146-
147-
def _is_pdp_context_active(self):
148-
if not self.is_registered():
149-
return False
150-
151-
ok, r = self.command('+QIACT?')
152-
if ok == ModemResult.OK:
153-
try:
154-
pdpstatus = int(r.lstrip('+QIACT: ').split(',')[1])
155-
# 1: PDP active
156-
return pdpstatus == 1
157-
except (IndexError, ValueError) as e:
158-
self.logger.error(repr(e))
159-
except AttributeError as e:
160-
self.logger.error(repr(e))
161-
return False
162-
163-
def init_serial_commands(self):
164-
self.command("E0") #echo off
165-
self.command("+CMEE", "2") #set verbose error codes
166-
self.command("+CPIN?")
167-
self.set_timezone_configs()
168-
#self.command("+CPIN", "") #set SIM PIN
169-
self.command("+CPMS", "\"ME\",\"ME\",\"ME\"")
170-
self.set_sms_configs()
171-
self.set_network_registration_status()
172-
173-
def set_network_registration_status(self):
174-
self.command("+CREG", "2")
175-
self.command("+CGREG", "2")
176-
177-
def _set_up_pdp_context(self):
178-
if self._is_pdp_context_active(): return True
179-
self.logger.info('Setting up PDP context')
180-
self.set('+QICSGP', f'1,1,\"{self._apn}\",\"\",\"\",1')
181-
ok, _ = self.set('+QIACT', '1', timeout=30)
182-
if ok != ModemResult.OK:
183-
self.logger.error('PDP Context setup failed')
184-
raise NetworkError('Failed PDP context setup')
185-
else:
186-
self.logger.info('PDP context active')
20+
return super().connect(timeout)
18721

18822
def _tear_down_pdp_context(self):
18923
if not self._is_pdp_context_active(): return True

Hologram/Network/Modem/E303.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,7 @@ def __init__(self, device_name=None, baud_rate='9600',
2525
def connect(self, timeout = DEFAULT_E303_TIMEOUT):
2626
return super().connect(timeout)
2727

28-
def init_serial_commands(self):
29-
self.command("E0") #echo off
30-
self.command("+CMEE", "2") #set verbose error codes
31-
self.command("+CPIN?")
32-
self.command("+CTZU", "1") #time/zone sync
33-
self.command("+CTZR", "1") #time/zone URC
34-
#self.command("+CPIN", "") #set SIM PIN
35-
self.command("+CPMS", "\"ME\",\"ME\",\"ME\"")
36-
self.set_sms_configs()
28+
def set_network_registration_status(self):
3729
self.command("+CREG", "2")
3830
self.command("+CGREG", "2")
3931

Hologram/Network/Modem/E372.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,7 @@ def __init__(self, device_name=None, baud_rate='9600',
2525
def connect(self, timeout = DEFAULT_E372_TIMEOUT):
2626
return super().connect(timeout)
2727

28-
def init_serial_commands(self):
29-
self.command("E0") #echo off
30-
self.command("+CMEE", "2") #set verbose error codes
31-
self.command("+CPIN?")
32-
self.command("+CTZU", "1") #time/zone sync
33-
self.command("+CTZR", "1") #time/zone URC
34-
#self.command("+CPIN", "") #set SIM PIN
35-
self.command("+CPMS", "\"ME\",\"ME\",\"ME\"")
36-
self.set_sms_configs()
28+
def set_network_registration_status(self):
3729
self.command("+CREG", "2")
3830
self.command("+CGREG", "2")
3931

0 commit comments

Comments
 (0)