In Sending a binary message - Part 1 we learned how to send a MT binary SMS from command line. Based on that we can add this functionality to the send.sh
script.
Usage
Lets see what new command line switches we can add. Out with the old – in with the new (this output is from the diff
utility):
37c37
< echo "Usage: $1 -s sender -r recipient [-m message] [-f filename] [-hex message in hex]" >/dev/stderr
---
> echo "Usage: $1 -s sender -r recipient [-bin|-text] [-m message] [-smart smart port] [-udh udh in hex] [-f filename] [-hex message in hex]" >/dev/stderr
Documentation from the send
script README:
Parameter | Value | Definition |
---|---|---|
[-bin | -text] |
Bin | text | The message content is a binary or text message. |
[-smart] | Smart messaging port number | The smart messaging destination and originator ports. Remember to use the bin parameter if the content is a binary message. |
[-udh] | UDH in hex | The User Data Header information in hexadecimal format To find out more about the UDH parameter, see the Nokia Smart Messaging documentation. Do not use this parameter if you do not know how it affects the mobile terminal’s functions. |
So we can specify whether it is a text or binary message. But lets first agree that using -smart or -udh switches implies that this is a binary message. And if both -smart and -udh switches are present the last one will override the earlier. (…in other words: Don’t use both of them!)
Yes – I’m slightly changing the semantics to something that makes more sense in Opaali API context. I’d better remember to update the README…
Parsing the arguments
Lets add a new global variable MODE to choose between TEXT and BIN (and FLASH which we will probably also add, but later, not now).
# message sending mode: TEXT|BIN|FLASH (TEXT is default)
MODE="TEXT"
We will also rewrite the -hex switch parsing which we added last time. Lets introduce another global variable HEX where we will store the hex string if it was given (and we’ll move decoding the hex string somewhere later in the script).
-hex)
shift
if [[ -n "$1" ]]; then
# HEX will contain MESSAGE as hex encoded
HEX="$1"
else
error_exit "$0" "missing hex message" "$1"
fi
shift
;;
We will put the UDH (User Data Header) into global variable UDH and also set MODE to binary:
-udh)
shift
if [[ -n "$1" ]]; then
# User Data Header
UDH="$1"
# UDH implies MODE BIN
MODE="BIN"
else
error_exit "$0" "missing UDH" "$1"
fi
shift
;;
I believe the CGW version of send
only supported decimal values for smart messaging port number, so we won’t bother with hex values, either. We’ll construct a UDH containing just the port addressing IE and overwrite any possibly existing UDH value (because if you can construct a UDH then what would you need the -smart parameter for?)
If the port number is less than 256 we can fit it into 8 bits, otherwise we’ll use 16-bit addressing:
-smart)
shift
declare -i SMART
if [[ -n "$1" ]]; then
# smart messaging port number (in decimal)
SMART="$1"
# SMART implies MODE BIN
MODE="BIN"
# SMART is implemented as UDH (overwrites possibly existing UDH)
if [[ $1 -lt 256 ]]; then
# 8-bit port number
UDH=$(printf '040402%02x%02x' $SMART $SMART)
else
# 16-bit port number
UDH=$(printf '060504%04x%04x' $SMART $SMART)
fi
else
error_exit "$0" "missing port in -smart" "$1"
fi
shift
;;
(Like last time you can check Wikipedia for more details: Wikipedia: User Data Header.)
And if the mode is specified we will store it into variable MODE:
-bin)
MODE="BIN"
shift
;;
-text)
MODE="TEXT"
shift
;;
We will also make minor adjustments to the argument post processing and add a call to a new function that will build the text or binary message:
145c184
< if [ -z "${MESSAGE}" ]; then
---
> if [[ -z "${MESSAGE}" && -z "${HEX}" ]]; then
164a204,205
> # build final MESSAGE (including UDH if needed)
> buildMessage "${MESSAGE}" "${HEX}" "${MODE}" "${UDH}"
Building a Text or Binary Message
Before that last buildMessage function call in parseArguments we have
- MESSAGE in text form from file, command line or read from stdin
- alternatively HEX containing a text or binary message as hex encoded
- for a binary message UDH as given on command line or generated from -smart parameter
- we also have MODE but we could guess that from UDH already
If we have
- a HEX encoded TEXT MODE message we need to decode it into MESSAGE
- a UDH we need to append to it the MESSAGE base64 encoded (or HEX which we first decode into binary data)
So the function buildMessage would look like this:
# build a message and store it in global variable MESSAGE
function buildMessage {
#param 1: message in TEXT format
#param 2: message in HEX format
#param 3: MODE
#param 4: UDH or (null)
if [[ -n "$4" || "$3" == BIN ]]; then
# UDH implies binary message
UDH="$4"
if [[ -z "$2" ]]; then
# hex encode text
HEX=$(echo -n "$1" | xxd -p | tr -d "\n")
else
HEX="$2"
fi
MESSAGE=$(echo -n "$UDH$HEX" | xxd -r -p | base64 | tr -d "\n")
else
# text message
if [[ -z "$1" && -n "$2" ]]; then
# decode hex message into text
MESSAGE=$(echo -n "$2" | xxd -r -p)
else
MESSAGE="$1"
fi
fi
return 0
}
And when we return from the function call the global variable MESSAGE will contain either the text to be sent or a UDH followed by the binary data.
outboundMessageRequest
It turns out that the only change we need to make to our existing outboundMessageRequest function is choosing the JSON parameter name between “outboundSMSTextMessage” and “outboundSMSBinaryMessage”.
So we will add a third parameter mode to our existing outboundMessageRequest function:
# make an outboundMessageRequest
function outboundMessageRequest {
#param 1: recipientAddress
#param 2: message
#param 3: mode - BIN or TEXT
#global: senderAddress - sender address string
#global: senderNameString - sender name string with comma or empty string
#global: access_token - access token string
#global: deli - resource URL to be used when querying status
# urlencode + and :
local sender=$(echo -n "$senderAddress" | sed -e s/\+/%2B/g -e s/\:/%3A/g)
local outboundSMStype=""
# choose a text or binary message
if [[ $3 == "BIN" ]]; then
outboundSMStype="outboundSMSBinaryMessage"
else
outboundSMStype="outboundSMSTextMessage"
fi
# call Opaali API and capture the interesting parts from the output"
local output=$(curl -k -s -d "{\"outboundMessageRequest\":{\"address\":[\"$1\"],\"senderAddress\":\"$senderAddress\",\"$outboundSMStype\":{\"message\":\"$2\"}$senderNameString}}" --header 'Content-Type:application/json' --header "Authorization: Bearer $access_token" https://api.opaali.telia.fi/production/messaging/v1/outbound/$sender/requests | grep -E 'resourceURL|error')
# the rest of the function is not shown here as there will be no changes to it!
# ...
And finally we will add the new mode parameter to our function call:
284c363
< outboundMessageRequest "${RECIPIENT}" "${MESSAGE}"
---
> outboundMessageRequest "${RECIPIENT}" "${MESSAGE}" "${MODE}"
Examples
Lets use our old vCalendar example and set vcal_udh and vcal_msg:
$ vcal_udh=06050423f50000
$ vcal_msg=$(cat example.vcal | xxd -p | tr -d "\n")
$ ./send.sh -s '$JPLa' -r '+358401234567' -udh $vcal_udh -hex $vcal_msg
SENT: tel:+358401234567 DeliveredToNetwork
$
The data received at the other end looked similar to that which we got the last time when sending from command line using curl
.
Because -udh implies -bin we don’t necessarily need to give the vCalendar data (which is text anyway) hex encoded:
$ ./send.sh -s '$JPLa' -r '+358401234567' -udh $vcal_udh -m "$(cat example.vcal)"
SENT: tel:+358401234567 DeliveredToNetwork
$
The data received is almost identical to the first example, but as bash
is a unix-style command shell the line endings were just LF instead of CR+LF (depending on the receiving terminal this may or may not be significant).
Or we can use the -smart parameter and avoid constructing a UDH:
$ ./send.sh -s '$JPLa' -r '+358401234567' -smart 9205 -m "$(cat example.vcal)"
SENT: tel:+358401234567 DeliveredToNetwork
$ ./send.sh -s '$JPLa' -r '+358401234567' -bin -smart 9205 -m "$(cat example.vcal)"
SENT: tel:+358401234567 DeliveredToNetwork
$
We can even abuse the syntax a bit by leaving out the -udh parameter, adding the -bin parameter and giving UDH+data together as a single hex string:
$ ./send.sh -s '$JPLa' -r '+358401234567' -bin -hex 06050423f50000424547494e3a5643414c454e4441520d0a56455253494f4e3a312e300d0a424547494e3a564556454e540d0a4445534352495054494f4e3a5374656572696e672047726f7570206d656574696e6720696e20506f7274616c0d0a445453544152543a3230303030393036543130303030300d0a4454454e443a3230303030393036543132303030300d0a454e443a564556454e540d0a454e443a5643414c454e4441520d0a
SENT: tel:+358401234567 DeliveredToNetwork
$
This works with Opaali API because it is assumed that the binary message always starts with a UDH so the UDH present flag is always set for binary messages.
This BTW does not work with CGW where UDH is separately provided to the API. You can send the message, but the UDH flag is not set, which will confuse the receiving end. Yes, I ran the test on the original send.exe
of CGW:
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -bin -hex 06050423f50000424547494e3a5643414c454e4441520d0a56455253494f4e3a312e300d0a424547494e3a564556454e540d0a4445534352495054494f4e3a5374656572696e672047726f7570206d656574696e6720696e20506f7274616c0d0a445453544152543a3230303030393036543130303030300d0a4454454e443a3230303030393036543132303030300d0a454e443a564556454e540d0a454e443a5643414c454e4441520d0a
SENT: 00358401234567 Delivered to the SMSC
Also, the following syntax doesn’t seem to work on CGW (although our send.sh script accepts it):
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -bin -smart 9205 -m "$(cat example.vcal)"
FAIL: 00358401234567 No message to send
Looks like you shouldn’t give the message in text format with the -bin parameter. Giving it as a hex string works:
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -bin -smart 9205 -hex $vcal_msg
SENT: 00358401234567 Delivered to the SMSC
The rest of the examples worked on CGW also:
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -smart 9205 -m "$(cat example.vcal)"
SENT: 00358401234567 Delivered to the SMSC
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -udh $vcal_udh -m "$(cat example.vcal)"
SENT: 00358401234567 Delivered to the SMSC
$ /c/Program\ Files\ \(x86\)/CGW/send.exe -s '$JPLa' -r '+358401234567' -udh $vcal_udh -hex $vcal_msg
SENT: 00358401234567 Delivered to the SMSC
See Extending send.sh with -hex switch for the previous related episode.
