Abilis scripting

Script developer's guide

Revision History
Revision 0 2014-04-11 TK
Document created
Revision 1 2015-02-17 TK
Added DISA API

Table of Contents

1. Overview
2. Configuration and control
2.1. Activation of SCRIPT driver
2.2. Installation of scripts
2.3. Configuration of scripts
2.4. Diagnostic information
2.5. Run time control
3. Abilis scripting language
3.1. Lua language
3.2. Abilis extensions
3.3. Abilis GPIO extensions
3.4. Abilis DISA extensions
4. Examples
4.1. Filtering
4.2. Random output
Glossary
Bibliography

List of Examples

1. Filtering script
2. Random output script

Abstract

This document explains how to activate scripting in CPX and how to write CPX scripts.

1. Overview

The SCRIPT driver allows to run Lua scripts together with CPX standard behaviour and functionality. This document shows how to configure the scripting support in CPX (Section 2, “Configuration and control”) and how to write scripts (Section 3, “Abilis scripting language”).

2. Configuration and control

This section describes how to enable scripting support in CPX, how to activate automatic loading of scripts upon startup, and how to use the Control Port interface for scripting.

2.1. Activation of SCRIPT driver

The SCRIPT driver has to be added to the CPX configuration.

[01:12:45] ABILIS: A RES:SCRIPT

The number of background sessions has to be specified. We need four sessions in this example, needed for scripts first.lua, second.lua, third.lua, and fourth.lua.

[01:12:45] ABILIS: S P RES:SCRIPT BG-SESNUM:4

2.2. Installation of scripts

The scripts first.lua, second.lua, third.lua, and fourth.lua have to be copied to the C:\APP\SCRIPT directory, in case of default configuration, or to the directory specified in the WDIR parameter of the SCRIPT configuration block.

2.3. Configuration of scripts

The scripts have to be specified in the SCRIPT configuration block.

[01:12:45] ABILIS: S P RES:SCRIPT ID:0 NAME:first.lua
[01:12:45] ABILIS: S P RES:SCRIPT ID:1 NAME:second.lua
[01:12:45] ABILIS: S P RES:SCRIPT ID:2 NAME:third.lua
[01:12:45] ABILIS: S P RES:SCRIPT ID:3 NAME:fourth.lua

After CPX restarts those scripts are started automatically.

2.4. Diagnostic information

The state of all script sessions can be displayed by this command:

[01:12:45] ABILIS: D D RES:SCRIPT

RES:Script --------------------------------------------------------------------
       Lua_scripting_service
       STATE:READY       CUR-BG-SESNUM:2      MAX-BG-SESNUM:4
       - SCRIPT Background sessions -------------------------------------------
       SES File                   State Started             Stopped
       ------------------------------------------------------------------------
       0   first.lua              STOP  2014-04-24 01:01:01 2014-04-24 01:02:03
       ------------------------------------------------------------------------
       1   second.lua             STOP  2014-04-24 01:01:01 2014-04-24 01:02:03
       ------------------------------------------------------------------------
       2   third.lua              RUN   2014-04-24 01:01:01 -
       ------------------------------------------------------------------------
       3   fourth.lua             RUN   2014-04-24 01:01:01 -
       ------------------------------------------------------------------------

This table shows the session identifier, the script file name, the script state, and the script start time and end time. The end time is shown only for terminated scripts.

The output produced by any script session can be displayed by the following command. The session is identified by the session identifier:

[01:12:45] ABILIS: SCRIPT OUTPUT SES:0

Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio

Script output ...

Alternatively it's possible to identify the script by its file name:

[01:12:45] ABILIS: SCRIPT OUTPUT FILE:first.lua

Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio

Script output ...

There is a circular buffer used for script outputs, so only the most recent outputs can be displayed.

2.5. Run time control

In addition to startup scripts, it's possible to start scripts in run time:

[01:12:45] ABILIS: SCRIPT START FILE:fifth.lua

The above command starts the script c:\app\script\fifth.lua on a free script session.

Any running session can be terminated by the following command. The session is identified by the session identifier:

[01:12:45] ABILIS: SCRIPT STOP SES:0

Alternatively it's possible to identify the script by its file name:

[01:12:45] ABILIS: SCRIPT STOP FILE:fifth.lua

3. Abilis scripting language

Abilis behaviour can be modified by scripts. The Lua programming language has been chosen for this purpose because it's simple, stable, and powerful.

3.1. Lua language

Lua is a very simple but powerful scripting language. It's specification can be found in [ref.lua-reference-manual].

3.2. Abilis extensions

In addition to functions in the standard lua library (see [ref.lua-reference-manual]) there are several functions specific for Abilis. All such functions are collected in the “abilis” name space that must be activated by this command:

local abilis = require "abilis"

The general purpose functions are collected in the “abilis.cpx” namespace.

abilis.cpx.sleep
abilis.cpx.sleep(sec)

This function suspends the script execution for sec seconds. Decimal fractions are allowed, so the value 1.5 means 1500 milliseconds. The value is internally converted to whole number of ticks, where the tick period is 10 ms. This function doesn't have any negative impact on CPX performance, as it doesn't consume any CPU time.

3.3. Abilis GPIO extensions

The functions in the “abilis.gio” namespace allow to obtain data from general purpose digital and analogue inputs, and to send data to general purpose digital and analogue outputs.

abilis.gio.get_device_handle
abilis.gio.get_device_handle(res, num)

This function takes the CPX resource name ("GPIO" or "MFIO") in the res parameter, and the resource number (i.e. 1 for GPIO-1, 2 for GPIO-2, etc.) in the num parameter. It returns the device handle that is used in subsequent functions.

abilis.gio.get_digital_input
abilis.gio.get_digital_input(device, index)

This function returns a value from the digital input of the specified device. The digital input line is selected by the index parameter. The lowest index is 1.

abilis.gio.set_digital_output
abilis.gio.set_digital_output(device, index, value)

This function writes a value to the digital output of the specified device. The digital output line is selected by the index parameter. The lowest index is 1.

abilis.gio.get_digital_output
abilis.gio.get_digital_output(device, index)

This function returns a value from the digital output of the specified device. The digital output line is selected by the index parameter. The lowest index is 1.

abilis.gio.get_analog_input
abilis.gio.get_analog_input(device, index)

This function returns a value from the analogue input of the specified device. The digital input line is selected by the index parameter. The lowest index is 1.

abilis.gio.set_analog_output
abilis.gio.set_analog_output(device, index, value)

This function writes a value to the analogue output of the specified device. The analogue output line is selected by the index parameter. The lowest index is 1.

3.4. Abilis DISA extensions

The functions of the “abilis.disa” namespace cooperate with the DISA driver and its services configured in the APP mode. These functions allow to make outgoing phone call, wait for incoming call, obtain information about the call, play sounds to the call, etc.

abilis.disa.dial
handle = abilis.disa.dial(service, cd, cg, sd, sg, rg)

This asynchronous function makes an outgoing call with the specified parameters: DISA service identifier, called number, calling number, called subaddress, calling subaddress, redirecting number. Only the first two parameters are mandatory.

This function returns a call handle, which is used as the first parameter of the other functions. The call handle must be closed by the abilis.disa.close function.

This function returns nil on failure.

abilis.disa.listen
handle = abilis.disa.listen(service)

This asynchronous function sets the selected DISA service into a listening mode, allowing its to accept incoming calls.

This function returns a call handle, which is used as the first parameter of the other functions. The call handle must be closed by the abilis.disa.close function.

This function returns nil on failure.

abilis.disa.close
ok = abilis.disa.close(handle)

This function closes an existing handle.

This function returns either true on success or false on failure.

abilis.disa.get_state
state = abilis.disa.get_state(handle)

This function returns the call state for the provided call handle. The call state is identified by a number: 0 ≡ closed, 1 ≡ calling, 2 ≡ alerting, 3 ≡ active, 4 ≡ closing, 5 ≡ listening. The value could be converted to a string by the abilis.disa.state_str function.

abilis.disa.state_str
text = abilis.disa.state_str(state)

This function converts the call state provided by the abilis.disa.get_state function into a readable text string.

abilis.disa.get_info
cg, cd, sg, sd, rg = abilis.disa.get_info(handle)

This function returns the call data for the provided call handle: Calling number, called number, calling subaddress, called subaddress, redirecting number. If some of those values is unavailable then nil is returned instead.

abilis.disa.get_dtmf
text = abilis.disa.get_dtmf(handle)

This function returns a string with all DMTF codes collected from the last call of this function.

This function returns nil on failure.

abilis.disa.play_file
ok = abilis.disa.play_file(handle, filename)

This function starts playback of the CPM file whose absolute path must be specified. The play process can be monitored with the abilis.disa.get_play_state function. The CPM file can be created from the WAV file by the abilis.disa.convert_wav function.

This function returns either true on success or false on failure.

abilis.disa.get_play_state
state = abilis.disa.get_play_state(handle)

This function returns the play state for the provided call handle. The play state is identified by a number: 0 ≡ silent, 1 ≡ playing. The value could be converted to a string by the abilis.disa.play_state_str function.

abilis.disa.play_state_str
text = abilis.disa.play_state_str(state)

This function converts the play state provided by the abilis.disa.get_play_state function into a readable text string.

abilis.disa.convert_wav
ok = abilis.convert_wav(filename)

This function converts a WAV file into the CPM file, which is used by the abilis.disa.play_file function. The full path to the CPM file must be provided.

This function returns either true on success or false on failure.

4. Examples

This second shows several basic examples of CPX scripts. They are all intended to run forever so they contain the neverending loop (while true do).

4.1. Filtering

This script works as a digital filter between digital input and digital output.

It reads the digital input periodically every POLL_TIME seconds, and changes the digital output according to the digital input value only after the input value is stable for at least LIMIT poll periods.

Example 1. Filtering script

local abilis = require "abilis"

local POLL_TIME = 1      -- polling interval in seconds
local LIMIT = 5          -- number of identical input samples required to change the output
local RES_NAME = "GPIO"  -- CPX resource name
local RES_NUMB = 1       -- CPX resource number
local DIG_INP = 1        -- digital input line
local DIG_OUT = 1        -- digital output line

local device = abilis.gio.get_device_handle(RES_NAME, RES_NUMB)
local prev_value = 0
local count = 0

while true do
  local value = abilis.gio.get_digital_input(device, DIG_INP)
  if value == prev_value then
    -- equal value
    count = 0
  else
    -- different value
    count = count + 1
    if count < LIMIT then
      -- nothing yet
    else
      -- changing the output
      abilis.gio.set_digital_output(device, DIG_OUT, value)
      prev_value = value
      count = 0
    end
  end

  abilis.cpx.sleep(POLL_TIME)
end


4.2. Random output

This script works as a random digital signal generator.

It's activated every POLL_TIME seconds and sends a random value (0 or 1) to the specified digital output.

Example 2. Random output script

local abilis = require "abilis"

local POLL_TIME = 10     -- polling interval in seconds
local RES_NAME = "GPIO"  -- CPX resource name
local RES_NUMB = 1       -- CPX resource number
local DIG_OUT = 1        -- digital output line

local device = abilis.gio.get_device_handle(RES_NAME, RES_NUMB)

while true do
  local value = math.random(0, 1)
  abilis.gio.set_digital_output(device, DIG_OUT, value)

  abilis.cpx.sleep(POLL_TIME)
end

Glossary

general-purpose inputs/outputs

Generic pins on a device whose behavior can be controlled (programmed) by the user at run time. See [ref.gpio].

Lua

A lightweight scripting language providing end users an easy way to program the behavior of a software product. See [ref.lua-language] and [ref.lua-org].

scripting language

A programming language that automate the execution of tasks which could alternatively be executed one-by-one by a human operator. See [ref.scripting-language].

source code

A collection of computer instructions (possibly with comments) written using some human-readable computer language, usually as text. See [ref.source-code].

Bibliography

[ref.gpio] General-purpose input/output, http://en.wikipedia.org/wiki/GPIO, Wikipedia, The Free Encyclopedia,

[ref.lua-language] Lua (programming language), http://en.wikipedia.org/wiki/Lua_(programming_language), Wikipedia, The Free Encyclopedia,

[ref.scripting-language] Scripting language, http://en.wikipedia.org/wiki/Scripting_language, Wikipedia, The Free Encyclopedia,

[ref.source-code] Source code, http://en.wikipedia.org/wiki/Source_code, Wikipedia, The Free Encyclopedia,

[ref.lua-org] Roberto Ierusalimschy, The Programming Language Lua, http://www.lua.org/, PUC-Rio,

[ref.lua-reference-manual] Lua 5.2 Reference Manual, http://www.lua.org/manual/5.2/, PUC-Rio,