Closed dauheeIRL closed 11 years ago
Hi, sorry for the late response - I'd been travelling these last couple of days. Thanks for this report - modem dialing is sadly very specific to the modem model, and whilst the library attempts to cater for the lowest common denominator, this does not always work (as can be seen from your output). This is what the log message
INFO: Unknown modem type - will use polling for call state updates" log message is indicating
means - the library does not know how your modem reports to call state updates, and falls back to polling it (which is not going to work in your case because "ATD" does not respond with the expected "OK").
Your post does give me most of what I need to implement full support for your modem though, thanks! Just a couple of direct questions, in order for me to to fully place where those notifications fit in:
Assuming the assumptions above are correct, could you please test the following and post the relevant bits of the output:
a. Dial a number (with waitForResponse == False), then reject the call at the remote end (i.e. without answering it first)
b. Dial a number (with waitForResponse == False), answer the call, then issue an ATH (i.e. local hangup) to the modem
c. Dial a number (with waitForResponse == False), then issue ATH (i.e. local hangup) before the call is answered.
In order to easily do (b) and (c) at this stage I'd recommend putting in a 10-second sleep() call or something similar, followed by a self.write('ATH').
no problem at all, I am just meddling at this stage :) OK hopefully I've done this right.
a. CONNECT received first, then ['HANGUP: 1'] about 30 seconds later when mobile receives SMS from network indicating missed call b. after dialling, start sleep for 10 sec, answering call after 5 sec, then issuing ATH, response was 'OK' c. after dialling, sleeping for 10 seconds, then issuing ATH while mobile was still ringing, response was 'OK'
Repeating a bit here but sending on in response to listed assumptions in case useful: 1 = yes no response until call is answered/rejected 2= yes CONNECT when call is answered and ['HANGUP: 1'] immediately when finished 3= yes the "HANGUP: 1" happens immediately when the call is finished (after answering). When the call is rejected (without answering), the CONNECT happens immediately, but the "HANGUP: 1" seems to only sent when the receiving mobile gets a network SMS indicating a call has been missed (this message happens as standard on most irish networks I believe)
Thanks for the info - this is exactly what I need to simulate the modem's behaviour and add full support for it.
The only potential problem is that "CONNECT"->"HANGUP" sequence when the call is rejected without answering - this is seemingly network (not modem) specific; are you sure the call isn't going to voicemail? If that is the case, the modem would still see the call as being "answered" - it doesn't care whether it is the actual remote party or the network's voicemail service that answers. The fact that the "HANGUP" coincides with the "missed call" SMS also makes me suspect this... In any case, I have enough info to build a call simulation for this modem, thanks!
I need to be able to identify this modem type during connect(), and since it does not report its supported commands and it's reported manufacturer information doesn't entirely match the profile thus far (that of a ZTE modem), we need to identify it by attempting to issue ZTE-specific commands (I could detect the ZTE-specific unsolicted notifications and use those as identification, but that relies a bit much on timing and luck since they can happen at any point). Using hyperterminal, could you please post the output of the following commands (some/most of them may fail):
AT+ZSEC? AT+ZRSSI AT+ZPAS? AT+ZSNT=?
yes the behaviour for rejecting a call would appear to be strange with the HANGUP only coming from the modem when the SMS is sent from the network operator - which can be 30 - 60 seconds.
I have the debug output below - I put in a sleep beforehand to catch the start-up unsolicited messages: DEBUG: write: AT+ZSEC? DEBUG: response: ['+ZSEC: 3,0', 'OK'] DEBUG: write: AT+ZRSSI DEBUG: response: ['ERROR'] DEBUG: write: AT+ZPAS? DEBUG: response: ['+BEARTYPE: "UMTS","CS_PS"', 'OK'] DEBUG: write: AT+ZSNT=? DEBUG: response: ['OK']
On Wed, May 8, 2013 at 12:35 PM, Francois Aucamp notifications@github.comwrote:
I need to be able to identify this modem type during connect(), and since it does not report its supported commands and it's reported manufacturer information doesn't entirely match the profile thus far (that of a ZTE modem), we need to identify it by attempting to issue ZTE-specific commands (I could detect the ZTE-specific unsolicted notifications and use those as identification, but that relies a bit much on timing and luck since they can happen at any point). Using hyperterminal, could you please post the output of the following commands (some/most of them may fail):
AT+ZSEC? AT+ZRSSI AT+ZPAS? AT+ZSNT=?
— Reply to this email directly or view it on GitHubhttps://github.com/faucamp/python-gsmmodem/issues/12#issuecomment-17600077 .
Ok, connect() should now detect your modem type and therefore detect the correct call state updates. The only tricky part is that your modem does not provide any indication of whether the call has been initiated (i.e. when it is ringing) - I have used polling as a substitute for this portion, since that is what is used for modems that are not recognized.
Please test this and see if the current code works for you - there is a slight chance that the modem might not appreciate the call state polling (but I doubt it will be a problem).
OK I just tried that with code from commit 702068b and it times out - call doesn't go through to mobile either:
DEBUG: write: ATD087111111; DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK']
.... multiple entries omitted . . .
DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] DEBUG: write: AT+CLCC DEBUG: response: ['OK'] Exception in thread Thread-2: Traceback (most recent call last): File "c:\python27\lib\threading.py", line 551, in bootstrap_inner self.run() File "c:\python27\lib\threading.py", line 504, in run self.__target(_self.args, *_self.__kwargs) File "c:\python27\lib\site-packages\gsmmodem\modem.py", line 825, in _pollCallStatus raise TimeoutException() TimeoutException
If I put a return statement right after the ATD write in def dial, the unsolicited messages can be seen again:
DEBUG: notification: ['CONNECT'] DEBUG: notification: ['HANGUP: 1'] DEBUG: Unhandled unsolicited modem notification: ['HANGUP: 1']
If I put a return statement right after the ATD write in def dial, the unsolicited messages can be seen again
Thanks for the feedback. That's a bit disappointing - I would have liked the +CLCC polling checks to be able to pick up the current call status (to get the call ID, etc), but it doesn't look like the modem supports it properly (which is strange) or as luck would have it, the call was failing during those tests (which is unlikely).
I've updated the code to stop dial from waiting for a "call init" notification for ZTE modems - the call ID is based on the current number of active calls (this appears to be what the modem uses anyway, so should be alright). Sorry about all the back-and-forward testing, and thanks again!
Am glad to be of some service not problems at all! Right here is the response so far - still getting timeout, not highlighting any response back:
Initializing modem...
INFO: Connecting to modem on port COM9 at 115200bps
DEBUG: write: ATZ
DEBUG: response: ['ATZ\r', 'ERROR']
DEBUG: write: AT+CMEE=1
DEBUG: response: ['AT+CMEE=1\r', 'OK']
DEBUG: write: AT+CPIN?
DEBUG: response: ['AT+CPIN?\r', '+CPIN: SIM PIN', 'OK']
DEBUG: write: AT+CPIN="xxxx"
DEBUG: response: ['AT+CPIN="xxxx"\r', 'OK']
DEBUG: write: ATZ
DEBUG: response: ['ATZ\r', 'OK']
DEBUG: write: ATE0
DEBUG: response: ['ATE0\r', 'OK']
DEBUG: write: AT+CFUN?
DEBUG: response: ['+CFUN: 0', 'OK']
DEBUG: write: AT+CFUN=1
DEBUG: response: ['OK']
DEBUG: write: AT+CMEE=1
DEBUG: response: ['OK']
DEBUG: write: AT+CLAC
DEBUG: response: ['ERROR']
DEBUG: write: AT+WIND?
DEBUG: response: ['ERROR']
DEBUG: write: AT+CGMI
DEBUG: response: ['QUALCOMM INCORPORATED', 'OK']
DEBUG: write: AT+ZPAS?
DEBUG: response: ['+BEARTYPE: "Limited Service"', 'OK']
INFO: Loading ZTE call state update table
DEBUG: write: AT+COPS=3,0
DEBUG: response: ['OK']
DEBUG: write: AT+CMGF=1
DEBUG: response: ['OK']
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 0.200000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 0.400000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 0.600000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 0.800000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 1.000000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: notification: ['+ZDONR: "Not Found"', '+ZPASR: "No Service"']
DEBUG: Unhandled unsolicited modem notification: ['+ZDONR: "Not Found"', '+ZPASR: "No Service"']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 1.200000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CME ERROR: 14']
DEBUG: Device/SIM busy error detected; self._writeWait adjusted to 1.400000s
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CSCA: "+353857000000",145', 'OK']
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: self_writeWait set to 0.1 because of recovering from device busy (515) error
DEBUG: write: AT+CSMP=49,167,0,0
DEBUG: response: ['OK']
DEBUG: write: AT+CSCA?
DEBUG: response: ['+CSCA: "+353857000000",145', 'OK']
DEBUG: write: AT+CPMS=?
DEBUG: response: ['+CPMS: ("ME","MT","SM","SR"),("ME","MT","SM","SR"),("ME","MT","SM","SR")', 'OK']
DEBUG: write: AT+CPMS="ME","ME","ME"
DEBUG: response: ['+CPMS: 1,100,1,100,1,100', 'OK']
DEBUG: write: AT+CNMI=2,1,0,2
DEBUG: response: ['OK']
DEBUG: write: AT+CLIP=1
DEBUG: response: ['OK']
DEBUG: write: AT+CRC=1
DEBUG: response: ['OK']
DEBUG: write: AT+CVHU=0
DEBUG: response: ['OK']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,2', 'OK']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,2', 'OK']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,2', 'OK']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,2', 'OK']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,2', 'OK']
DEBUG: notification: ['+ZDONR: "METEOR",272,3,"CS_ONLY","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: Unhandled unsolicited modem notification: ['+ZDONR: "METEOR",272,3,"CS_ONLY","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: notification: ['+ZDONR: "METEOR",272,3,"CS_ONLY","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: Unhandled unsolicited modem notification: ['+ZDONR: "METEOR",272,3,"CS_ONLY","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: write: AT+CREG?
DEBUG: response: ['+CREG: 0,1', 'OK']
DEBUG: write: AT+CSQ
DEBUG: response: ['+CSQ: 10,99', 'OK']
DEBUG: notification: ['+ZDONR: "METEOR",272,3,"CS_PS","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: Unhandled unsolicited modem notification: ['+ZDONR: "METEOR",272,3,"CS_PS","ROAM_OFF"', '+ZPASR: "UMTS"']
DEBUG: write: ATD0871111111;
DEBUG: write: AT+CLCC
DEBUG: response: ['OK']
DEBUG: write: AT+CLCC
DEBUG: response: ['OK']
.. repeating ..
DEBUG: response: ['OK']
DEBUG: write: AT+CLCC
DEBUG: response: ['OK']
Traceback (most recent call last):
File "C:\Per\Tools\raspberry pi\backup_Dev\scripts-dev\GSM2.py", line 86, in
If I put in a return right after the ATH command in def dial, the responses can be seen again: DEBUG: notification: ['CONNECT'] DEBUG: notification: ['HANGUP: 1'] DEBUG: Unhandled unsolicited modem notification: ['HANGUP: 1']
Strange:
DEBUG: write: ATD0871111111; DEBUG: write: AT+CLCC DEBUG: response: ['OK']
This should not have been there - that's the call status polling that I removed in the previous commit (it is also the reason you get a TimeoutException). Anyhow, I've added a simple log message to the dial() command just to ensure the "don't wait for response, and don't start polling" bits are actually being executed on your modem. Please test this once you get a chance? (and check that your code matches what's currently in the repository - maybe git is not playing nice)
Could very well have been an omission on my side, its not unknown for me to not do something right :)
Great now we are getting somewhere! Output is as follows now:
DEBUG: write: ATD0871111111; DEBUG: Not waiting for outgoing call init update message DEBUG: notification: ['CONNECT'] DEBUG: notification: ['HANGUP: 1']
as expected because its not waiting for call, the call.answered will be false when the code passes it in this case and continues onto modem.rxThread.join(2**31) where afterwards the notifications are received
Also just verified again when the call is rejected, the CONNECT notification comes up immediately. the HANGUP comes about 60 seconds later at the exact second when a missed call SMS is sent by the network operator to the destination mobile.
Ok, that is the expected behaviour - the fact the the notifications aren't flagged as "unhandled/unknown" means they are being interpreted (in this case, changing the call object's state parameters (setting things like "answered", etc)). I'm starting to think I should add a parameter to the dial() method that allows users to specify callback methods for these events, if they want.
The only thing that would not be detected 100% correctly in your case is that "connect" followed by "hangup" sequence when you reject the call yourself - I really think that's because one of the network services is in fact answering the call (to say something like "the subscriber you have dialed is currently not available" or whatever). That said, I can't be entirely sure without testing it - I'll write a small script to check it and post it shortly.
Ok, I've added a "dial_demo.py" script to the examples directory - it's pretty much just a generic example of how to dial and use the resulting call object - writing that made me decide to definitely add a callback mechanism for outgoing calls as well.
Anyhow, the following is a simplified version of dial_demo.py, but with some internal call state checking added (the AT+CLCC calls every half second) - could you please run this and post the output for when you reject the call without answering it first? The point here is to see what the modem thinks is happening to the call before and after its CONNECT notification during that 30 second window.
You'll need to modify the PORT, NUMBER, PIN etc variables, obviously.
from __future__ import print_function
import sys, time, logging
PORT = '/dev/ttyUSB2'
BAUDRATE = 115200
NUMBER = '00000'
PIN = None
from gsmmodem.modem import GsmModem
from gsmmodem.exceptions import InterruptedException, CommandError
def main():
print('Initializing modem...')
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.DEBUG)
modem = GsmModem(PORT, BAUDRATE, incomingCallCallbackFunc=handleIncomingCall)
modem.connect(PIN)
print('Waiting for network coverage...')
modem.waitForNetworkCoverage(30)
print('Dialing number: {0}'.format(NUMBER))
call = modem.dial(NUMBER)
i = 0
while i < 1000:
print('Checking internal call status:')
modem.write('AT+CLCC')
if not call.active:
print('Call object no longer active, exiting...')
i = 999999
else:
time.sleep(0.5)
print('Done.')
modem.close()
if __name__ == '__main__':
main()
Thanks!
OK I just gave that a go for the example above (had to take out incomingCallCallbackFunc bit) and it keeps looping without a call going to the destination mobile:
Dialing number: 0871111111 DEBUG: write: ATD0871111111; DEBUG: Not waiting for outgoing call init update message Checking internal call status: DEBUG: write: AT+CLCC DEBUG: response: ['OK'] ... keeps repeating here . . . .
Hi there, just checking in to see if there is anything I can be assistance with. Github was having issues when I attempted to to post on this last weekend.
Just a quick update to say I've not abandoned this :) - just been super-busy the last week and didn't get round to python-gsmmodem. I've gotten hold of a ZTE modem though, so I'll test with that over the weekend and see how it compares to your input.
I've completed tests using a ZTE K3565-Z modem - this modem seems to behave identical to yours. I find it especially strange that the AT+CLCC calls cause an outgoing call to be "abandoned" without any error whatsoever. If you add a "if call.answered:" check before the write('AT+CLCC') bit, you'll notice that the call status is returned correctly once the call is actually active - however, since we can rely on the modem's notifications at this point, it doesn't help much.
Anyhow, that "CONNECT" -> "HANGUP: 1" behaviour you are getting when you reject a call without answering really seems to be the network picking up the call and playing a "subscriber not available" message. In my case, I was able to reject the call without such a message being played by the network, resulting in the modem simply responding with "OK" (no "CONNECT" or even "HANGUP"). As soon as I enabled the message on the network (by putting the SIM card into a phone, and enabling "call forwarding when busy"), I also get a "CONNECT" followed by "HANGUP: 1".
Bottom line: the modem sees the call being answered - because that is what is happening. There isn't much we can do to compensate for that, as there isn't any indication that its the "wrong" party that is answering the call.
I'm going to adapt the code to listen for the "OK" upon call rejection (as currently with my ZTE modem this isn't being detected) - can you perhaps check if call forwarding is enabled on the SIM card in your modem?
Just checked and there are no diverts on the modem sim, but there is on the mobile sim - it is configured to forward to voicemail. I think what might be happening is its going to voicemail, hence the HANGUP delay. I'm not getting any voicemails on the mobile, but that could be because there was nothing transferred by the modem "over the line" so to speak while the voicemail was in progress, so the network doesn't notify of any voicemail. I remember you had pointed to this previously, but I directed you in the wrong direction.
The reason I believe this is the case, is because I just checked the credit on the modem sim, and there was about 4 Euro charged for voice calls. I didn't make any voice calls with the modem sim since purchase.
Excellent stuff as usual, that would neatly explain the HANGUP delay and the voice charges. Much appreciated.
On Sat, May 18, 2013 at 8:30 PM, Francois Aucamp notifications@github.comwrote:
I've completed tests using a ZTE K3565-Z modem - this modem seems to behave identical to yours. I find it especially strange that the AT+CLCC calls cause an outgoing call to be "abandoned" without any error whatsoever. If you add a "if call.answered:" check before the write('AT+CLCC') bit, you'll notice that the call status is returned correctly once the call is actually active - however, since we can rely on the modem's notifications at this point, it doesn't help much.
Anyhow, that "CONNECT" -> "HANGUP: 1" behaviour you are getting when you reject a call without answering really seems to be the network picking up the call and playing a "subscriber not available" message. In my case, I was able to reject the call without such a message being played by the network, resulting in the modem simply responding with "OK" (no "CONNECT" or even "HANGUP"). As soon as I enabled the message on the network (by putting the SIM card into a phone, and enabling "call forwarding when busy"), I also get a "CONNECT" followed by "HANGUP: 1".
Bottom line: the modem sees the call being answered - because that is what is happening. There isn't much we can do to compensate for that, as there isn't any indication that its the "wrong" party that is answering the call.
I'm going to adapt the code to listen for the "OK" upon call rejection (as currently with my ZTE modem this isn't being detected) - can you perhaps check if call forwarding is enabled on the SIM card in your modem?
— Reply to this email directly or view it on GitHubhttps://github.com/faucamp/python-gsmmodem/issues/12#issuecomment-18106630 .
Thanks (as always) for your assistance with this bug! :)
Ah fantastic! Just gave it a go and everything is perfect including DTMF
OK you are probably sick of all the issues my weird modem is throwing up at this stage!! I get the following timeout error when calling modem.dial - the receiving phone does get the call, however the self.write('ATD{0} . . . line hangs until the timeout:
Initializing modem... INFO: Connecting to modem on port COM9 at 115200bps DEBUG: write: ATZ DEBUG: response: ['OK'] DEBUG: write: ATE0 DEBUG: response: ['ATE0\r', 'OK'] DEBUG: write: AT+CFUN? DEBUG: response: ['+CFUN: 1', 'OK'] DEBUG: write: AT+CMEE=1 DEBUG: response: ['OK'] DEBUG: write: AT+CPIN? DEBUG: response: ['+CPIN: READY', 'OK'] DEBUG: write: AT+CLAC DEBUG: response: ['ERROR'] DEBUG: write: AT+WIND? DEBUG: response: ['ERROR'] DEBUG: write: AT+CGMI DEBUG: response: ['QUALCOMM INCORPORATED', 'OK'] INFO: Unknown modem type - will use polling for call state updates DEBUG: write: AT+COPS=3,0 DEBUG: response: ['OK'] DEBUG: write: AT+CMGF=1 DEBUG: response: ['OK'] DEBUG: write: AT+CSCA? DEBUG: response: ['+CSCA: "+353857000000",145', 'OK'] DEBUG: write: AT+CSMP=49,167,0,0 DEBUG: response: ['OK'] DEBUG: write: AT+CSCA? DEBUG: response: ['+CSCA: "+15214361000000000000000000000000000000000",145', 'OK'] DEBUG: write: AT+CSCA="+353857000000" DEBUG: response: ['OK'] DEBUG: write: AT+CPMS=? DEBUG: response: ['+CPMS: ("ME","MT","SM","SR"),("ME","MT","SM","SR"),("ME","MT","SM","SR")', 'OK'] DEBUG: write: AT+CPMS="ME","ME","ME" DEBUG: response: ['+CPMS: 1,100,1,100,1,100', 'OK'] DEBUG: write: AT+CNMI=2,1,0,2 DEBUG: response: ['OK'] DEBUG: write: AT+CLIP=1 DEBUG: response: ['OK'] DEBUG: write: AT+CRC=1 DEBUG: response: ['OK'] DEBUG: write: AT+CVHU=0 DEBUG: response: ['OK'] Waiting for network coverage... DEBUG: write: AT+CSQ DEBUG: response: ['+CSQ: 21,99', 'OK'] Waiting for SMS message... DEBUG: write: ATD08711111; Traceback (most recent call last): File "C:\Per\Tools\raspberry pi\backup_Dev\scripts-dev\GSM2.py", line 74, in
main()
File "C:\Per\Tools\raspberry pi\backup_Dev\scripts-dev\GSM2.py", line 51, in main
call = modem.dial("08711111", 20)
File "c:\python27\lib\site-packages\gsmmodem\modem.py", line 470, in dial
self.write('ATD{0};'.format(number), waitForResponse=self._waitForAtdResponse, timeout=20)
File "c:\python27\lib\site-packages\gsmmodem\modem.py", line 239, in write
responseLines = SerialComms.write(self, data + writeTerm, waitForResponse=waitForResponse, timeout=timeout, expectedRespo
nseTermSeq=expectedResponseTermSeq)
File "c:\python27\lib\site-packages\gsmmodem\serial_comms.py", line 135, in write
raise TimeoutException()
gsmmodem.exceptions.TimeoutException
After modifying waitForResponse to be False instead of True, and then return out of the dial function:
self.write('ATD{0};'.format(number), waitForResponse=not self._waitForAtdResponse, timeout=40) return
I then get the following instead of the error:
DEBUG: notification: ['CONNECT'] DEBUG: Unhandled unsolicited modem notification: ['CONNECT'] DEBUG: notification: ['HANGUP: 1'] DEBUG: Unhandled unsolicited modem notification: ['HANGUP: 1']
I'm guessing this modem is giving a different response than expected.