0

I have a RNDIS USB modem that allows AT commands through a telnet port (5510). I want to use it to read and send SMS messages from a script. I've used a variant of a similar question posted here but I'm using socat instead of netcat.

  1. I have a helper script called atread.sh:
#!/bin/sh

echo -e $@ 

IFS=$'\n' 
while read line; do
    echo $line >&3
    if [ "${line::2}" = "OK" ] || [ "${line::5}" = "ERROR" ] ; then
        break
    fi
done
  1. I then have a function in my main script:
smsio() {
    response=$(3>&1 socat -T 2 exec:"./atread.sh '$1'" tcp:xxx.xxx.xxx.xxx:5510,crlf)
    ... (some other code to check for a timeout or broken pipe)
}
  1. I invoke the function in the main script like so: smsio "AT+CMGF=1".

This works extremely well as long as the parameter does not include special characters, specifically:

  • Quotation marks (") as in smsio 'AT+CMGL="ALL"' to read all SMS messages
  • Backslash (\) as in smsio 'AT+CMGS="123456789"' ; smsio "Text Message\x1A" to send an SMS

I've tried to escape the special character using backslash (\") and/or adding double quoting ("".."") but it appears that socat is stripping all special characters before it calls the exec script. Any suggestions how to get these special characters through socat?

PS: I've temporarily bypassed the problem via character substitution (i.e using ! for " in the parameter string, then using tr '!' '"' in atread.sh, but I'm looking for a more elegant solution.

Rob P
  • 3
  • 2
  • Check your script with shellcheck. This is overall kind of an odd approach. And you tagged bash and ash - which one are you using? Anyway, use `coproc socat - tcp:...` and communicate with coproc. And consider using python. Writing that in Bash will just be harder. For transferring properly quoted values, use `printf "%q"`, or just use environment variables. `it appears that socat is stripping` How "it appears"? Have you debugged it? Run `tcpdump` and see what is beeing sent. – KamilCuk Mar 20 '22 at 10:19
  • Sorry, yes using ash. Its running in a router (OpenWRT) so can't use anything as heavy as Python. I added some trace prints to both the call and caller, and tried various options. I expected the special character to come through when I used the escape backslash. I will investigate coproc and tcpdump. – Rob P Mar 21 '22 at 04:53

1 Answers1

0

Socats address parser interpretes a few characters specially, these are for example:

: , ! " ' \ ( [ {

You have to escape them with backslash. Please note that you also need to escape a few special characters including \ from the shell parser.

Use options -d -d -d -d to see the parameters socat receives and uses; try something like

socat -u /tmp/nonexistingdir/x\\\\x -

to see in the error message what is left of the special characters when socat performs the final system call.

dest-unreach
  • 186
  • 1
  • 9
  • The option -d -d -d -d really helped. Let me see what was being passed by socat. I was really close. Needed 3 escapes (backslash) to work. So the call to read SMS messages is SMS ```smsio 'AT+CMGL=\\\"ALL\\\"'```. – Rob P Mar 24 '22 at 05:45
  • The send message was a little more complex: ```smsio 'AT+CMGS=\\\"123456789\\\"' ; smsio "Text Message"'\\\\x1A'``` Thanks for your help. – Rob P Mar 24 '22 at 05:53