Skip to content

Rewrite the CLI and CLD with an external script

Translation rules cover prefixes, lengths and formats. When the decision needs data from outside the call, a lookup table, a time of day or a database, the switch can hand the numbers to a script of your own. This tutorial installs a small inbound script that removes a leading + from the CLI and rejects calls to 1900 numbers with 403. Allow about 20 minutes.

  • You have root shell access to the switch and know the number of the environment: the Env # column of System Management → Environments. The examples use environment 1.
  • Rules & Lists is not in use on the environment. It installs its own script at the same path; see the caution in step 3.
  • You know where the script runs in the call flow. It is step 5 of Number translation: after the translation rules of the authentication rule, post-authentication rule and account, before rating and routing.

The switch starts the script once and keeps it running. For every call it writes lines NAME=value to the script’s standard input, followed by an empty line:

I_ACCOUNT=123
ORIG_CLI=+442079460123
ORIG_CLD=0012125550123
CLI=+442079460123
CLD=12125550123
CALLER_NAME=Reception
P_ASSERTED_ID=
REMOTE_PARTY_ID=
REMOTE_IP=203.0.113.10
DIVERSION=
DIVERSION_PARAMS=
Field Value
I_ACCOUNT ID of the account the call is authenticated to
ORIG_CLI, ORIG_CLD The numbers as received, before any translation rule
CLI, CLD The numbers after the translation rules
CALLER_NAME Display name from the From header
P_ASSERTED_ID, REMOTE_PARTY_ID Caller identity headers, if present
REMOTE_IP IP address the call came from
DIVERSION, DIVERSION_PARAMS Number and parameters of the Diversion header, if present

The script answers with lines of its own and an empty line. CLI and CLD are required: send them back unchanged when the script has nothing to do. A missing CLD is an empty number, and the switch rejects the call.

Field Effect
CLI, CLD The numbers the switch rates and routes
CALLER_NAME New display name
FAIL=yes Reject the call
RESULT SIP code for a rejected call, 400 to 699 except 401 and 407. Any other value gives 500
COST Amount added to the cost of the call, also charged when the script rejects it
ADD_HEADER A SIP header added to the outgoing INVITE, for example ADD_HEADER=X-Customer: 42. Repeat the line for more headers
RURI_PARAMS, TO_URI_PARAMS, FROM_URI_PARAMS Parameters added to the request URI and to the URIs of To and From, for example user=phone
P_ASSERTED_ID_PARAMS, P_ASSERTED_ID_URI_PARAMS, REMOTE_PARTY_ID_PARAMS, REMOTE_PARTY_ID_URI_PARAMS, DIVERSION_PARAMS, DIVERSION_URI_PARAMS Parameters of the identity and diversion headers

Result: you know what the script receives and what it must return.

Any language works if the program reads standard input line by line, never exits, and flushes its output after every answer. The switch ships a minimal shell example at /home/ssp/scripts/external_translator.sample. This version adds the two rules of the tutorial:

external_translator
#!/bin/sh
# Inbound external translator:
# - removes a leading + from the CLI;
# - rejects calls to numbers that start with 1900 with 403.
while true; do
read -r LINE || exit 0
case "$LINE" in
CLI=*) CLI=${LINE#CLI=} ;;
CLD=*) CLD=${LINE#CLD=} ;;
"")
CLI=${CLI#+}
case "$CLD" in
1900*)
echo "FAIL=yes"
echo "RESULT=403"
;;
esac
echo "CLI=$CLI"
echo "CLD=$CLD"
echo
CLI=""
CLD=""
;;
esac
done
  1. Save the script on the switch, for example as /root/external_translator.

  2. Test it from the shell before the switch uses it:

    Terminal window
    printf 'CLI=+442079460123\nCLD=19005550123\n\n' | sh /root/external_translator

    The output is FAIL=yes, RESULT=403, CLI=442079460123, CLD=19005550123 and an empty line.

Result: the script answers correctly in the shell.

The switch looks for /var/env<N>/scripts/external_translator, where <N> is the environment number.

  1. Copy the script into place:

    Terminal window
    cp /root/external_translator /var/env1/scripts/external_translator
  2. Make it executable for everyone; the switch ignores a file without all three execute bits:

    Terminal window
    chmod 755 /var/env1/scripts/external_translator
  3. Wait one minute. The switch checks the file every minute, starts the script when it appears and restarts it when the file changes. Each call-processing process runs up to five copies of it.

Result: new calls of the environment pass through the script.

  1. Make a test call from an account to a 1900 number. The caller receives 403.
  2. Open Tools & Debugs → SIP Logs Viewer, find the call and check that the switch answered 403 Invalid Destination Number.
  3. Make a call with a CLI that starts with +, then open Reports → Call Records (CDRs) and the call’s details. The billed CLI has no +, and External Translator under Call Authentication shows that the script handled the call.

To switch the script off, remove it or clear its execute bit (chmod 644). The switch stops it within a minute.

A second script, /var/env<N>/scripts/external_translator_outbound, runs for every connection the switch tries, after the connection’s translation rules. It receives I_ACCOUNT, I_VENDOR, I_CONNECTION, ORIG_CLI, ORIG_CLD, CLI1 and CLD1 (the numbers before the connection’s rules), CLI and CLD (after them) and CALLER_NAME. It answers with CLI, CLD, and optionally CALLER_NAME and ADD_HEADER; it cannot reject the call. The shell example is /home/ssp/scripts/external_translator_outbound.sample.