Non blocking AT command handling | Thales IoT Developer Community
March 27, 2015 - 12:10pm, 5469 views
Hello!
I am currently trying to implement non-blocking AT calls on the Cinterion concept board, by using:
public void send(String command, ATCommandResponseListener Listener)
I've implemented a locking mechanism where the sending thread waits until the response listener notifies it or timeout occurs. The whole point is to avoid situations where a corrupted call to send() breaks this functionality. The issue I'm having is that the cancelCommand() method seems to also be a blocking call, which behaves weird for me. The documentation states :
If there are strings sent to the AT command interpreter by this method which are not valid AT commands because they don't start with "AT" they will be ignored by the AT command interpreter, no response will be sent and the waiting listener will never be called! If an invalid AT command is cancelled with the cancelCommand() function the waiting response listener will be called with an "ERROR" as response.
I've done this intentionally, I've called the function with a random string to simulate improper AT requests. This is the call:
m_ATCommand.send("aaaaaaa", m_ATResponseListener);
When I send the improper string, I detect a timeout because the response listener is never called. However, to use this ATCommand member again I have to call cancelCommand(), and here's where the error occurs. This call blocks, and doesn't ever return. From what I understand, the call should end by the ATResponse() being called with ERROR as argument. Is this the correct approach to handling timeout on the AT interface? Is there anything else that ***** to be done before sending the ATCommand.cancelCommand()?
Hello,
I've checked what you described.
I've found out that it is only true when the command string does not contain "AT" string.
Trying to release the command has the same result as cancelling in this case.
I must agree that it's not the good behaviour.
As a work around for now I'd recommend adding some command validation before sending if it is possible that the dummy command may be sent by some other API or user.
Best regards,
Bartłomiej
Thank you for your response, I do check for "AT" string in my code, I was just using this to test the timeout behaviour of my app. There are different situations where a timeout can occur, unrelated to sending the command without the "AT" string. If the modem doesn't respond and the command should be reissued, I would like to be able to interrupt the command currently being processed. As far as I can tell, the cancelCommand() is not doing this, and it's a problem for me. A work around would be resetting this AT channel in some way. Do you have any suggestions on how to do this other than cancelCommand()?
Best regards,
Nikša
Hello Niksa,
If you would like to cancel some long lasting command like AT+COPS=? the cancelCommand() should do the job.
The situation when the module does not reply at all should not happen unless you have issued some dummy command or '\r' is missing in the end.
Does it happen in other situations? If you have the evidence that it happens this might be the application fault. If you're sure it's not and additionally cancelCommand() does not return at that time this might be reported as potential defect.
Workaround: If cancelCommand() does not return the release() may also not. So you could try to use another ATCommand instance. I know that it's not the best work around.
Please check the firmware version of your module (ATI1) and AT^SCFG? response.
Regards,
Bartłomiej
Thank you for the info, Bartłomiej,
This is just a precaution I would like to have, even though I haven't noticed any random timeouts yet. I consider a blocking write to a physical communication layer without a no-response-timeout option a liability (what happens if the modem IC physically stops working?). Hopefully, this doesn't happen on the ehs6 but I see no other path then to reset the midlet if and when this happens, and if and when the cancelCommand() blocks. I would not report this as a defect, rather then maybe a lacking functionality, which (in my opinion) should be added to the api in the future.
Best regards,
Nikša
Bartolomiej,
The situation when the module does not reply at all should not happen unless you have issued some dummy command or '\r' is missing in the end.
The idea is to detect when something isn't executing as expected. Sure Niksa is not going to use invalid commands as that would seem pointless. However, you want to design your application in such a way that it detects and handles a non-responsive system in a correct way, even though Gemalto has done its very best to develop a bullet-proof system.
Niksa is working on a personal alarming device (the same as I'm working on) and a device which is misbehaving out of control is not an option. The device must return to a defined state in any case after which normal behavior resumes. Retrying the at command is one way, if that fails consistingly, then there is no other option than to reboot the GSM ic.
Hello,
We assume that unless we issue correctly formatted commands the system must always reply in a reasonable time.
But if we want to be 100% sure that the system will not stuck in some time critical place for some unexpected reason the watchdog could be worth consideration.
And if we assume that the system might stuck during sending a command and not return from the sending method a no-response timeout might be a good idea. And in such case to recover from that hypothetical situation we could take another fresh instance of ATCommand and issue the critical commands (this might also include sending some configuration commands again, adding listeners or taking some other actions). After that we could reset the module.
Regards,
Bartłomiej