A periodic CLCC polling is started when there is an ongoing multiparty
call and a new call appears in the system. A simple way to reproduce
the crashing scenario is:
1. Place a call.
2. Place a second call.
3. Create a multiparty call with both calls.
4. Place a third call (incoming or outgoing does not matter).
5. Disconnect HFP from the modem.
Within the function ciev_callheld_notify, the AT+CLCC command is also
invoked, thus a new cyclic CLCC polling is started, and it overwrites
the timer resource identifier stored in voicecall_data.clcc_source.
This means that there are several timers doing the CLCC polling, but
only one of those is under control, i.e. it can be removed through its
source identifier, hence a timer source leak.
This has a fatal consequence when the HFP modem is disconnected. The
function hfp_voicecall_remove stops the timer that is under control
before freeing the voicecall_data struct. However there are other timers
that are still active and will execute its handler poll_clcc afterwards.
Inside poll_clcc the driver_data is accessed, which is already NULL.
A solution for this is to avoid starting a CLCC polling if there is
already one active, i.e. clcc_source is not 0. By doing this the
uncontrolled timers will not cycle forever.
According to the standard "3GPP 27.007 v6.8.0" Appendix C.2.11,
when sending multiple DTMF characters, these must go in individual
+VTS commands for each tone. This adopts the AT modem approach.
Before: AT+VTS=1234\r
After: AT+VTS=1;+VTS=2;+VTS=3;+VTS=4\r
The affected call types for +CHUP were set to only ACTIVE calls.
Instead the affected set should include INCOMING, DIALING, ALERTING and
ACTIVE calls.
Thanks to Ionut Dediu for the diagnosing and reporting this issue.
The SIM900 module from SIMCOM does have a AT+CGDATA command.
However, it is not possible to make a ppp connection when CGDATA
has been used to bring up the gprs context.
This patch adds a quirk that uses the alternative ATD*99***<cid>#
command instead.