The in-call unsolicited events and the in-call audio settings are
managed exclusively at modem level, and no longer at call object
level. This is because these two things are applicable to all calls
that may be active at the same time.
Instead of providing a method to exclusively provide incoming call
updates, make it more generic so that we allow plugins to provide
state updates for any kind of call, not just incoming ones.
The logic to match the call info provided by URCs is updated so that
it can be reused also by the single call reports, in addition to the
full call list reports.
We cannot handle in-call state at call level because the state may
apply to multiple active calls at the same time:
* the modem is in-call if there is at least one ongoing call (>=1).
* the modem is not in-call if there are no ongoing calls (==0).
The new logic implements call state monitoring for all available call
objects, and whenever the state of one or more calls change, we'll go
over all of them to see how many of the calls can be considered to be
ongoing (i.e. not terminated, not unknown). If we have at least one
call ongoing, we'll setup the in-call state and otherwise, we'll clean
it up.
Setting up and cleaning up the in-call state involves unsolicited
message and audio channel settings management operations.
This method will join all active and held calls into a single
multiparty call, and then request the network to terminate the call on
the subscriber's end and transfer the control of the call to the
parties that are still in the call.
This method will put the currently active call on hold, and right away
accept the next available call.
The user of the API does not need to specify explicitly which is the
next call to accept, because that is decided automatically:
* If there is any waiting call, it will accept it right away.
* If there is no waiting call but there is a held call, it will make
the held call active again.
This method will hangup the currently active call and right away
accept the next available call.
The user of the API does not need to specify explicitly which is the
next call to accept, because that is decided automatically:
* If there is any waiting call, it will accept it right away.
* If there is no waiting call but there is a held call, it will make
the held call active again.
If the modem supports call list polling, we'll setup a timeout to poll
for the full call list periodically, in order to get detailed call
states.
The timeout is setup as soon as a new call is created, and it will be
kept enabled as long as there is a call being established (i.e. not
unknown, not terminated, not active).
The previous logic would end up returning an error if either +CLIP or
+CRC reported an error, and we should really avoid that, because our
setup is able to manage the voice calls even without those settings.
So, convert the logic into a small state machine and try to configure
the settings both in the primary and secondary ports, instead of just
in the primary one.
This CL converts a few g_regex_match_full() expressions to their
equivalent g_regex_match() in order to simplify the code, i.e.
g_regex_match_full (regex, str, strlen (str), 0, 0, &match_info, NULL)
is equivalent to:
g_regex_match_full (regex, str, -1, 0, 0, &match_info, NULL)
or simply:
g_regex_match (regex, str, 0, &match_info)
The operation sending the raw data of the SMS may timeout because the
current value of 10s is too low.
When this happens, we may end up marking the modem as invalid if the
operation takes much longer, as in
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/133
<debug> [1561707204.192676] (ttyUSB3): --> 'AT+CMGS=22<CR>'
<debug> [1561707204.207212] (ttyUSB3): <-- '<CR><LF>> '
<debug> [1561707204.207562] (ttyUSB3) device open count is 3 (open)
<debug> [1561707204.207695] (ttyUSB3) device open count is 2 (close)
<debug> [1561707204.207841] (ttyUSB3): --> '0021000B9164xxxxxxxxFx00000AEDF6989D06D1CB733A\26'
<debug> [1561707204.261028] (ttyUSB3): <-- '<CR><LF>'
<debug> [1561707205.197464] (ttyUSB3) device open count is 3 (open)
<debug> [1561707207.197763] loading signal quality...
<debug> [1561707207.197990] (ttyUSB3) device open count is 4 (open)
<debug> [1561707210.199337] (ttyUSB3) device open count is 5 (open)
<debug> [1561707214.197198] (ttyUSB3) device open count is 4 (close)
<debug> [1561707214.197443] (ttyUSB3): --> 'AT+CGACT?<CR>'
<debug> [1561707215.196530] (ttyUSB3) device open count is 5 (open)
<warn> [1561707217.196750] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707217.196928] (ttyUSB3) device open count is 4 (close)
<warn> [1561707217.197065] (tty/ttyUSB3) at port timed out 2 consecutive times
<debug> [1561707217.197187] (ttyUSB3): --> 'AT+CIND?<CR>'
<debug> [1561707220.198180] (ttyUSB3) device open count is 5 (open)
<debug> [1561707222.196792] (ttyUSB3) device open count is 6 (open)
<debug> [1561707222.196983] (ttyUSB3) device open count is 5 (close)
<warn> [1561707222.197125] (tty/ttyUSB3) at port timed out 3 consecutive times
<debug> [1561707222.197257] (ttyUSB3): --> 'AT+CGACT?<CR>'
<debug> [1561707225.198384] (ttyUSB3) device open count is 6 (open)
<warn> [1561707225.198616] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707225.198703] (ttyUSB3) device open count is 5 (close)
<warn> [1561707225.198814] (tty/ttyUSB3) at port timed out 4 consecutive times
<debug> [1561707225.199437] (ttyUSB3): --> 'AT+CGACT?<CR>'
<warn> [1561707228.196747] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707228.196915] (ttyUSB3) device open count is 4 (close)
<warn> [1561707228.197050] (tty/ttyUSB3) at port timed out 5 consecutive times
<debug> [1561707228.197175] (ttyUSB3): --> 'AT+CGACT?<CR>'
<debug> [1561707230.197709] (ttyUSB3) device open count is 5 (open)
<warn> [1561707231.197089] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707231.197256] (ttyUSB3) device open count is 4 (close)
<warn> [1561707231.197387] (tty/ttyUSB3) at port timed out 6 consecutive times
<debug> [1561707231.197519] (ttyUSB3): --> 'AT+CSQ<CR>'
<debug> [1561707234.199671] Couldn't refresh signal quality: 'Serial command timed out'
<debug> [1561707234.199897] (ttyUSB3) device open count is 5 (open)
<debug> [1561707234.200038] (ttyUSB3) device open count is 4 (close)
<warn> [1561707234.200161] (tty/ttyUSB3) at port timed out 7 consecutive times
<debug> [1561707234.200291] (ttyUSB3): --> 'AT+CGACT?<CR>'
<debug> [1561707235.197071] (ttyUSB3) device open count is 5 (open)
<debug> [1561707237.198460] Signal quality value not updated in 60s, marking as not being recent
<warn> [1561707237.198846] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707237.198949] (ttyUSB3) device open count is 4 (close)
<warn> [1561707237.199060] (tty/ttyUSB3) at port timed out 8 consecutive times
<debug> [1561707237.199636] (ttyUSB3): --> 'AT+CGACT?<CR>'
<debug> [1561707240.198778] (ttyUSB3) device open count is 5 (open)
<warn> [1561707240.199031] checking if connected failed: Couldn't check current list of active PDP contexts: Serial command timed out
<debug> [1561707240.199127] (ttyUSB3) device open count is 4 (close)
<warn> [1561707240.199244] (tty/ttyUSB3) at port timed out 9 consecutive times
<debug> [1561707240.199363] (ttyUSB3): --> 'AT+CNSMOD?<CR>'
<debug> [1561707243.198163] Couldn't refresh access technologies: 'Serial command timed out'
<debug> [1561707243.198294] Periodic signal quality checks scheduled in 30s
<debug> [1561707243.198402] (ttyUSB3) device open count is 3 (close)
<error> [1561707243.198528] (tty/ttyUSB3) at port timed out 10 consecutive times, marking modem '/org/freedesktop/ModemManager1/Modem/0' as invalid
<debug> [1561707243.198699] (ttyUSB3): --> 'AT+CGACT?<CR>'
Or we may end up aborting other actions that the modem is doing...
<debug> [1560473069.956036] (ttyACM2): --> 'AT+CMGS=70<CR>'
<debug> [1560473069.963667] Added CALL at '/org/freedesktop/ModemManager1/Call/1'
<debug> [1560473069.977937] (ttyACM2): <-- '<CR><LF>> '
<debug> [1560473069.978558] (ttyACM2) device open count is 3 (open)
<debug> [1560473069.978812] (ttyACM2) device open count is 2 (close)
<debug> [1560473069.979152] (ttyACM2): --> '0001000D8......................\26'
<debug> [1560473080.317049] (ttyACM2): --> 'ATD123456789;<CR>'
<debug> [1560473092.293458] (ttyACM2): <-- '<CR><LF>+CMGS: 1<CR><LF><CR><LF>OK<CR><LF>'
<warn> [1560473092.293854] Couldn't start call : 'Couldn't start the call: Unhandled response '+CMGS: 1''
<info> [1560473092.293936] Call state changed: dialing -> terminated (unknown)
<debug> [1560473092.293987] Cleaning up in-call unsolicited events...
So, update the raw data sending timeout to a much longer value.
The regex was expecting empty values in several of the fields, which
is wrong. Instead of matching empty fields, just ignore all fields
that we don't require in our logic.
We use the raw commands exclusively when we're sending SMS data to the
device. Until this change, all raw commands were added at the tail of
the queue of pending commands, and that meant that if any unrelated AT
command was interleaved between e.g. our AT+CGMS and the actual SMS
data sent, the operation would have failed.
With this fix, we're making sure that all raw commands are added at
the head of the queue, so we're making sure that the next command
picked after e.g. CGMS is actually the raw SMS data to be sent.
We would be avoiding issues like this one, where an outgoing voice
call attempt gets in the way before we send the SMS data:
[1556246081.786284] (ttyACM2): --> 'AT+CMGS=70<CR>'
[1556246081.814861] (ttyACM2): <-- '<CR><LF>> '
[1556246081.819382] (ttyACM2): --> 'ATD1234567890;<CR>'
[1556246081.839685] (ttyACM2): <-- '<CR><LF>> '
[1556246081.840123] Couldn't start call : 'Couldn't start the call: Unhandled response '> ''
[1556246081.856254] (ttyACM2): --> '0001000D810..............
[1556246081.922470] (ttyACM2): <-- '<CR><LF>+CME ERROR: 4<CR><LF>'
By default all the commands we were sending through the serial port
were added at the tail of the pending queue, but we may want to queue
them at the head in very specific cases (e.g. while sending an SMS).