~mil/sxmo-tickets#584: 
Incoming SMS that are slow to finish arriving are missed

If my phone receives a text, it's seemingly completely random whether I'll be alerted to it or not until another text arrives or I wake the phone manually later.

I've had this problem every time I've tried using SXMO on my pinephone, but only had the time/inclination to track it down recently (I use it as my actual phone and need to receive texts on time most of the time), but I have now tracked down the cause of the issue and have a solution.

I've written a standalone monitor script that I've been testing after removing the default text handling from smxo_modemmonitor.sh and it's been working really well, but I don't know how to best incorporate the method into the current SXMO code, and it needs some way to handle stuck SMS. So rather than submit a patch I've explained everything below.
I've probably given much more detail than needed.

Here's a link to my script: https://paste.sr.ht/~rgybmc/10b91ce0719977e23ebb8fb3ed8dcba2a327c170


How I understand SXMO to handle receiving texts currently:

  • sxmo_modemmonitor.sh runs sxmo_modem.sh checkfornewtexts when modemmanager sends a dbus signal that a new SMS object has been added.

  • sxmo_modem.sh checkfornewtexts checks for SMS objects that have state 'received', and ignores any others.

  • sxmo_modem.sh checkfornewtexts is run by sxmo_run_aligned.sh every 5 minutes real time.

The cause of my problems:

  • When an incoming SMS is first added (triggering checkfornewtexts) it has the state 'receiving' and this only changes to 'received' when the full SMS has finished arriving.

  • If the phone is suspended when the SMS arrives and has been suspended long enough for the 5 minute check to occur then it will be run immediately upon waking.

  • Whether the SMS state is 'received' at the time(s) checkfornewtexts runs the mmcli command to list the SMS objects is effectively a race condition.

  • checkfornewtexts will not be run again until another SMS is added, or the next time a 5 minute check is run (likely when the phone is woken manually much later), and the incoming SMS will not be processed until then.

The solution (in my opinion):

If we know we're receiving an SMS, we should wait until it's fully received before trying to read and process it.

The dbus signal that sxmo_modemmonitor.sh monitors conveniently contains the object path of the SMS (including the ID), and whether the SMS is incoming or outgoing. The code to collect that information is simple thanks to the predictable nature of the signal.

dbus itself sends a signal when the properties of a modemmanager object are changed, and using the SMS object path we can monitor for the state to change to received. However, when testing I found that signal rather slow to be sent after the state is actually changed, and sometimes was never sent.

So, my script enters a loop to keep checking the state of the SMS (using mmcli) after a sleep until it's 'received'. It's worked really well for me for more than a week using text messages extensively.

Issues:

If an SMS becomes stuck, which still happens to me occasionally, the state will perpetually be 'receiving' until it's handled some way (normally modemmanager or the modem itself restarting, I think), meaning my method will loop indefinitely unless we put in some sort of timeout, and I have no idea how long would be reasonable, or what to do when it runs out.

As far as potentially integrating this method into SXMO goes, I don't know whether it would be better to add it to sxmo_modemmonitor.sh or to sxmo_modem.sh, and it might make sense to change checkfornewtexts either way to use the known id rather than starting from scratch looking for received texts (and presumably put that part in a seperate function for running manual/periodic checks).

Status
REPORTED
Submitter
~rgybmc
Assigned to
No-one
Submitted
8 months ago
Updated
8 months ago
Labels
No labels applied.

~noneofyourbusiness 8 months ago*

another option is to also notify when one is receiving a new sms, not doing that loop with mmcli

one can decide do that polling for when the sms will finally arrive anyway, still having that issue, but not in base sxmo (turing halting problem)

kiss, keep it simple and straightforward

~rgybmc 8 months ago*

Just having a notification that an sms is being received and then carrying on as it currently is would certainly be the simplest change that would help with this issue.

In my case I'd definitely want more than that since this affects at least half of the texts I receive and I wouldn't want to have to wait a bit and manually check each one, but as you say that doesn't necessarily need to be in sxmo-utils.

Actually, if this isn't decided to be a big enough problem to fully solve in base sxmo then maybe the best answer would be creating an sxmo_hook_sms_added.sh* to be executed alongside checkfornewtexts in sxmo_modemmonitor.sh. It could either be empty by default, or notify the user if there are any sms that have been received but not processed (and deleted) by sxmo_modem.sh after a short sleep.
I can then put whatever I want in there, or anyone else with similar issues.

For what it's worth, with my method the only time it'll ever hit the sleep and loop again is if it's an sms that would have been missed with the current system. Any sms that wasn't missed when it arrived was fully received in the time it took to run "echo $line | grep -qE '^signal' && sxmo_modem.sh checkfornewtexts", after all.
What I've written can definitely be tweaked so that if the text is already fully received then as little extra code is executed as possible compared to now if it is decided to include something like this in sxmo-utils.


* Called sms_added not sms_incoming because it would be run for outgoing texts as well as incoming, unless sxmo_modemmonitor.sh was changed, which maybe it should be but that's probably a separate question.

Register here or Log in to comment, or comment via email.