Skip to content

Commit

Permalink
Add support for newer SIMCom devices
Browse files Browse the repository at this point in the history
This patch adds support to event driven calls for newer SIMCom devices
such as the SIM7100, SIM7500, and SIM7600.

These devices support the command "AT+CLCC=1" which sets the modem to
print the CLCC output on every call status change. I made an effort to
to probe modem upport for automatic reporting by trying setting AT+CLCC
to 1. The untested assumption is that the command will fail if the modem
does not support it.

The regular expressions used for _handleCallAnswered,
_handleCallInitiated, and _handleCallEnded are simply a copy and paste
from the regular expression used for CLCC, replacing what was on the
third group by a fixed number representing the call status. For example,
using the number 6 to indicate that the call was disconnected.

To detect the newer devices I used the availability of the +SIMCOMATI
command but I am not really sure how reliable this is. My concern is of
false positives for devices that could support the +SIMCOMATI and not
support the automatic reporting of "AT+CLCC=1".

This was tested on an SIM7600G.

Signed-off-by: Peter Senna Tschudin <[email protected]>
  • Loading branch information
petersenna committed Nov 20, 2022
1 parent ea7db39 commit 96ccc75
Showing 1 changed file with 35 additions and 1 deletion.
36 changes: 35 additions & 1 deletion gsmmodem/modem.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ def connect(self, pin=None, waitingForModemToStartInSeconds=0):
enableWind = True
elif '+ZPAS' in commands:
callUpdateTableHint = 3 # ZTE
if '+SIMCOMATI' in commands:
callUpdateTableHint = 4 # SIMCom
else:
# Try to enable general notifications on Wavecom-like device
enableWind = True
Expand Down Expand Up @@ -323,6 +325,38 @@ def connect(self, pin=None, waitingForModemToStartInSeconds=0):
self._waitForCallInitUpdate = False # ZTE modems do not provide "call initiated" updates
if commands == None: # ZTE uses standard +VTS for DTMF
Call.dtmfSupport = True
elif callUpdateTableHint == 4: # SIMCom (Tested on SIM7600)
self.log.info('Loading SIMCOM call state update table')
self._mustPollCallStatus = False
Call.dtmfSupport = True
try:
# Enables automatic reporting of the list of current calls
# when the call status changes
self.write('AT+CLCC=1')
except CommandError:
# Modem does not support automatic reporting of the list of
# current calls when the call status changes
self.log.info('Will use polling for call state updates')
self._mustPollCallStatus = True

# This works well with the SIM7600G for example
if not self._mustPollCallStatus:
# Using the field <stat> of the AT+CLCC command. Notice the
# numbers between groups 1 and 2 on the following regexes
#
# The possible values are:
# 0 – active
# 1 – held
# 2 – dialing (MO call)
# 3 – alerting (MO call)
# 4 – incoming (MT call)
# 5 – waiting (MT call)
# 6 – disconnect
self._callStatusUpdates = (
(re.compile('^\+CLCC:\s+(\d+),(\d),0,(\d),([^,]),"([^,]*)",(\d+)$'), self._handleCallAnswered),
(re.compile('^\+CLCC:\s+(\d+),(\d),2,(\d),([^,]),"([^,]*)",(\d+)$'), self._handleCallInitiated),
(re.compile('^\+CLCC:\s+(\d+),(\d),6,(\d),([^,]),"([^,]*)",(\d+)$'), self._handleCallEnded),
(re.compile('^BUSY$'), self._handleCallRejected))
else:
# Unknown modem - we do not know what its call updates look like. Use polling instead
self.log.info('Unknown/generic modem type - will use polling for call state updates')
Expand Down Expand Up @@ -567,7 +601,7 @@ def supportedCommands(self):
except (TimeoutException, CommandError):
# Try interactive command recognition
commands = []
checkable_commands = ['^CVOICE', '+VTS', '^DTMF', '^USSDMODE', '+WIND', '+ZPAS', '+CSCS', '+CNUM']
checkable_commands = ['^CVOICE', '+VTS', '^DTMF', '^USSDMODE', '+WIND', '+ZPAS', '+CSCS', '+CNUM', '+SIMCOMATI']

# Check if modem is still alive
try:
Expand Down

0 comments on commit 96ccc75

Please sign in to comment.