Wed Aug 20 06:37:21 2008

Asterisk developer's documentation


app_adsiprog.c File Reference

Program Asterisk ADSI Scripts into phone. More...

#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/adsi.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"

Include dependency graph for app_adsiprog.c:

Go to the source code of this file.

Data Structures

struct  adsi_display
struct  adsi_event
struct  adsi_flag
struct  adsi_key_cmd
struct  adsi_script
struct  adsi_soft_key
struct  adsi_state
struct  adsi_subscript

Defines

#define ARG_NUMBER   (1 << 1)
#define ARG_STRING   (1 << 0)
#define MAX_MAIN_LEN   1600
#define MAX_RET_CODE   20
#define MAX_SUB_LEN   255
#define STATE_INIF   3
#define STATE_INKEY   1
#define STATE_INSUB   2
#define STATE_NORMAL   0

Functions

static int adsi_exec (struct ast_channel *chan, void *data)
static int adsi_process (struct adsi_script *state, char *buf, char *script, int lineno)
static int adsi_prog (struct ast_channel *chan, char *script)
static int clearcbone (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static int cleardisplay (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static int clearflag (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int cleartimer (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static struct adsi_scriptcompile_script (char *script)
char * description (void)
 Provides a description of the module.
static int digitcollect (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static int digitdirect (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static char * get_token (char **buf, char *script, int lineno)
static struct adsi_displaygetdisplaybyname (struct adsi_script *state, char *name, char *script, int lineno, int create)
static int geteventbyname (char *name)
static struct adsi_flaggetflagbyname (struct adsi_script *state, char *name, char *script, int lineno, int create)
static int getjustifybyname (char *name)
static struct adsi_soft_keygetkeybyname (struct adsi_script *state, char *name, char *script, int lineno)
static struct adsi_stategetstatebyname (struct adsi_script *state, char *name, char *script, int lineno, int create)
static struct adsi_subscriptgetsubbyname (struct adsi_script *state, char *name, char *script, int lineno)
static int goto_line (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int goto_line_rel (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int onevent (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int process_opcode (struct adsi_subscript *sub, char *code, char *args, struct adsi_script *state, char *script, int lineno)
static int process_returncode (struct adsi_soft_key *key, char *code, char *args, struct adsi_script *state, char *script, int lineno)
static int process_token (void *out, char *src, int maxlen, int argtype)
static int send_delay (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int send_dtmf (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int set_state (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static int setflag (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int showdisplay (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int showkeys (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
static int starttimer (char *buf, char *name, int id, char *args, struct adsi_script *istate, char *script, int lineno)
static int subscript (char *buf, char *name, int id, char *args, struct adsi_script *state, char *script, int lineno)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static char * app = "ADSIProg"
static char * descrip
static struct adsi_event events []
static struct adsi_event justify []
static struct adsi_key_cmd kcmds []
 LOCAL_USER_DECL
static struct adsi_key_cmd opcmds []
 STANDARD_LOCAL_USER
static char * synopsis = "Load Asterisk ADSI Scripts into phone"
static char * tdesc = "Asterisk ADSI Programming Application"
static char * validdtmf = "123456789*0#ABCD"


Detailed Description

Program Asterisk ADSI Scripts into phone.

Definition in file app_adsiprog.c.


Define Documentation

#define ARG_NUMBER   (1 << 1)

Definition at line 114 of file app_adsiprog.c.

Referenced by adsi_process(), goto_line(), goto_line_rel(), process_token(), send_delay(), set_state(), showdisplay(), and starttimer().

#define ARG_STRING   (1 << 0)

Definition at line 113 of file app_adsiprog.c.

Referenced by adsi_process(), clearflag(), onevent(), process_token(), send_dtmf(), setflag(), showdisplay(), showkeys(), and subscript().

#define MAX_MAIN_LEN   1600

Definition at line 111 of file app_adsiprog.c.

Referenced by process_opcode().

#define MAX_RET_CODE   20

Definition at line 109 of file app_adsiprog.c.

Referenced by process_returncode().

#define MAX_SUB_LEN   255

Definition at line 110 of file app_adsiprog.c.

Referenced by process_opcode().

#define STATE_INIF   3

Definition at line 107 of file app_adsiprog.c.

Referenced by adsi_process().

#define STATE_INKEY   1

Definition at line 105 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_INSUB   2

Definition at line 106 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_NORMAL   0

Definition at line 104 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().


Function Documentation

static int adsi_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 1551 of file app_adsiprog.c.

References adsi_available(), adsi_prog(), ast_strlen_zero(), ast_verbose(), localuser::chan, LOCAL_USER_ADD, LOCAL_USER_REMOVE, option_verbose, and VERBOSE_PREFIX_3.

Referenced by load_module().

01552 {
01553    int res=0;
01554    struct localuser *u;
01555 
01556    LOCAL_USER_ADD(u);
01557    
01558    if (ast_strlen_zero(data))
01559       data = "asterisk.adsi";
01560    
01561    if (!adsi_available(chan)) {
01562       if (option_verbose > 2)
01563          ast_verbose(VERBOSE_PREFIX_3 "ADSI Unavailable on CPE.  Not bothering to try.\n");
01564    } else {
01565       if (option_verbose > 2)
01566          ast_verbose(VERBOSE_PREFIX_3 "ADSI Available on CPE.  Attempting Upload.\n");
01567       res = adsi_prog(chan, data);
01568    }
01569 
01570    LOCAL_USER_REMOVE(u);
01571    
01572    return res;
01573 }

static int adsi_process ( struct adsi_script state,
char *  buf,
char *  script,
int  lineno 
) [static]

Definition at line 963 of file app_adsiprog.c.

References ARG_NUMBER, ARG_STRING, ast_log(), adsi_display::data, adsi_subscript::data, adsi_display::datalen, adsi_subscript::datalen, adsi_subscript::defined, adsi_soft_key::defined, adsi_script::desc, adsi_script::fdn, get_token(), getdisplaybyname(), geteventbyname(), getflagbyname(), getjustifybyname(), getkeybyname(), getstatebyname(), getsubbyname(), adsi_display::id, adsi_subscript::id, adsi_soft_key::id, adsi_subscript::ifdata, adsi_subscript::ifinscount, adsi_soft_key::initlen, adsi_subscript::inscount, adsi_script::key, LOG_WARNING, process_opcode(), process_returncode(), process_token(), adsi_soft_key::retstr, adsi_soft_key::retstrlen, adsi_script::sec, adsi_script::state, STATE_INIF, STATE_INKEY, STATE_INSUB, STATE_NORMAL, adsi_script::sub, and adsi_script::ver.

Referenced by compile_script().

00964 {
00965    char *keyword;
00966    char *args;
00967    char vname[256];
00968    char tmp[80];
00969    char tmp2[80];
00970    int lrci;
00971    int wi;
00972    int event;
00973    struct adsi_display *disp;
00974    struct adsi_subscript *newsub;
00975    /* Find the first keyword */
00976    keyword = get_token(&buf, script, lineno);
00977    if (!keyword) 
00978       return 0;
00979    switch(state->state) {
00980    case STATE_NORMAL:
00981       if (!strcasecmp(keyword, "DESCRIPTION")) {
00982          args = get_token(&buf, script, lineno);
00983          if (args) {
00984             if (process_token(state->desc, args, sizeof(state->desc) - 1, ARG_STRING))
00985                ast_log(LOG_WARNING, "'%s' is not a valid token for DESCRIPTION at line %d of %s\n", args, lineno, script);
00986          } else
00987             ast_log(LOG_WARNING, "Missing argument for DESCRIPTION at line %d of %s\n", lineno, script);
00988       } else if (!strcasecmp(keyword, "VERSION")) {
00989          args = get_token(&buf, script, lineno);
00990          if (args) {
00991             if (process_token(&state->ver, args, sizeof(state->ver) - 1, ARG_NUMBER))
00992                ast_log(LOG_WARNING, "'%s' is not a valid token for VERSION at line %d of %s\n", args, lineno, script);
00993          } else
00994             ast_log(LOG_WARNING, "Missing argument for VERSION at line %d of %s\n", lineno, script);
00995       } else if (!strcasecmp(keyword, "SECURITY")) {
00996          args = get_token(&buf, script, lineno);
00997          if (args) {
00998             if (process_token(state->sec, args, sizeof(state->sec) - 1, ARG_STRING | ARG_NUMBER))
00999                ast_log(LOG_WARNING, "'%s' is not a valid token for SECURITY at line %d of %s\n", args, lineno, script);
01000          } else
01001             ast_log(LOG_WARNING, "Missing argument for SECURITY at line %d of %s\n", lineno, script);
01002       } else if (!strcasecmp(keyword, "FDN")) {
01003          args = get_token(&buf, script, lineno);
01004          if (args) {
01005             if (process_token(state->fdn, args, sizeof(state->fdn) - 1, ARG_STRING | ARG_NUMBER))
01006                ast_log(LOG_WARNING, "'%s' is not a valid token for FDN at line %d of %s\n", args, lineno, script);
01007          } else
01008             ast_log(LOG_WARNING, "Missing argument for FDN at line %d of %s\n", lineno, script);
01009       } else if (!strcasecmp(keyword, "KEY")) {
01010          args = get_token(&buf, script, lineno);
01011          if (!args) {
01012             ast_log(LOG_WARNING, "KEY definition missing name at line %d of %s\n", lineno, script);
01013             break;
01014          }
01015          if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
01016             ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
01017             break;
01018          }
01019          state->key = getkeybyname(state, vname, script, lineno);
01020          if (!state->key) {
01021             ast_log(LOG_WARNING, "Out of key space at line %d of %s\n", lineno, script);
01022             break;
01023          }
01024          if (state->key->defined) {
01025             ast_log(LOG_WARNING, "Cannot redefine key '%s' at line %d of %s\n", vname, lineno, script);
01026             break;
01027          }
01028          args = get_token(&buf, script, lineno);
01029          if (!args || strcasecmp(args, "IS")) {
01030             ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
01031             break;
01032          }
01033          args = get_token(&buf, script, lineno);
01034          if (!args) {
01035             ast_log(LOG_WARNING, "KEY definition missing short name at line %d of %s\n", lineno, script);
01036             break;
01037          }
01038          if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
01039             ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY short name at line %d of %s\n", args, lineno, script);
01040             break;
01041          }
01042          args = get_token(&buf, script, lineno);
01043          if (args) {
01044             if (strcasecmp(args, "OR")) {
01045                ast_log(LOG_WARNING, "Expecting 'OR' but got '%s' instead at line %d of %s\n", args, lineno, script);
01046                break;
01047             }
01048             args = get_token(&buf, script, lineno);
01049             if (!args) {
01050                ast_log(LOG_WARNING, "KEY definition missing optional long name at line %d of %s\n", lineno, script);
01051                break;
01052             }
01053             if (process_token(tmp2, args, sizeof(tmp2) - 1, ARG_STRING)) {
01054                ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY long name at line %d of %s\n", args, lineno, script);
01055                break;
01056             }
01057          } else {
01058             ast_copy_string(tmp2, tmp, sizeof(tmp2));
01059          }
01060          if (strlen(tmp2) > 18) {
01061             ast_log(LOG_WARNING, "Truncating full name to 18 characters at line %d of %s\n", lineno, script);
01062             tmp2[18] = '\0';
01063          }
01064          if (strlen(tmp) > 7) {
01065             ast_log(LOG_WARNING, "Truncating short name to 7 bytes at line %d of %s\n", lineno, script);
01066             tmp[7] = '\0';
01067          }
01068          /* Setup initial stuff */
01069          state->key->retstr[0] = 128;
01070          /* 1 has the length */
01071          state->key->retstr[2] = state->key->id;
01072          /* Put the Full name in */
01073          memcpy(state->key->retstr + 3, tmp2, strlen(tmp2));
01074          /* Update length */
01075          state->key->retstrlen = strlen(tmp2) + 3;
01076          /* Put trailing 0xff */
01077          state->key->retstr[state->key->retstrlen++] = 0xff;
01078          /* Put the short name */
01079          memcpy(state->key->retstr + state->key->retstrlen, tmp, strlen(tmp));
01080          /* Update length */
01081          state->key->retstrlen += strlen(tmp);
01082          /* Put trailing 0xff */
01083          state->key->retstr[state->key->retstrlen++] = 0xff;
01084          /* Record initial length */
01085          state->key->initlen = state->key->retstrlen;
01086          state->state = STATE_INKEY;
01087       } else if (!strcasecmp(keyword, "SUB")) {
01088          args = get_token(&buf, script, lineno);
01089          if (!args) {
01090             ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
01091             break;
01092          }
01093          if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
01094             ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
01095             break;
01096          }
01097          state->sub = getsubbyname(state, vname, script, lineno);
01098          if (!state->sub) {
01099             ast_log(LOG_WARNING, "Out of subroutine space at line %d of %s\n", lineno, script);
01100             break;
01101          }
01102          if (state->sub->defined) {
01103             ast_log(LOG_WARNING, "Cannot redefine subroutine '%s' at line %d of %s\n", vname, lineno, script);
01104             break;
01105          }
01106          /* Setup sub */
01107          state->sub->data[0] = 130;
01108          /* 1 is the length */
01109          state->sub->data[2] = 0x0; /* Clear extensibility bit */
01110          state->sub->datalen = 3;
01111          if (state->sub->id) {
01112             /* If this isn't the main subroutine, make a subroutine label for it */
01113             state->sub->data[3] = 9;
01114             state->sub->data[4] = state->sub->id;
01115             /* 5 is length */
01116             state->sub->data[6] = 0xff;
01117             state->sub->datalen = 7;
01118          }
01119          args = get_token(&buf, script, lineno);
01120          if (!args || strcasecmp(args, "IS")) {
01121             ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
01122             break;
01123          }
01124          state->state = STATE_INSUB;
01125       } else if (!strcasecmp(keyword, "STATE")) {
01126          args = get_token(&buf, script, lineno);
01127          if (!args) {
01128             ast_log(LOG_WARNING, "STATE definition missing name at line %d of %s\n", lineno, script);
01129             break;
01130          }
01131          if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
01132             ast_log(LOG_WARNING, "'%s' is not a valid token for a STATE name at line %d of %s\n", args, lineno, script);
01133             break;
01134          }
01135          if (getstatebyname(state, vname, script, lineno, 0)) {
01136             ast_log(LOG_WARNING, "State '%s' is already defined at line %d of %s\n", vname, lineno, script);
01137             break;
01138          }
01139          getstatebyname(state, vname, script, lineno, 1);
01140       } else if (!strcasecmp(keyword, "FLAG")) {
01141          args = get_token(&buf, script, lineno);
01142          if (!args) {
01143             ast_log(LOG_WARNING, "FLAG definition missing name at line %d of %s\n", lineno, script);
01144             break;
01145          }
01146          if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
01147             ast_log(LOG_WARNING, "'%s' is not a valid token for a FLAG name at line %d of %s\n", args, lineno, script);
01148             break;
01149          }
01150          if (getflagbyname(state, vname, script, lineno, 0)) {
01151             ast_log(LOG_WARNING, "Flag '%s' is already defined\n", vname);
01152             break;
01153          }
01154          getflagbyname(state, vname, script, lineno, 1);
01155       } else if (!strcasecmp(keyword, "DISPLAY")) {
01156          lrci = 0;
01157          wi = 0;
01158          args = get_token(&buf, script, lineno);
01159          if (!args) {
01160             ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
01161             break;
01162          }
01163          if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
01164             ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
01165             break;
01166          }
01167          if (getdisplaybyname(state, vname, script, lineno, 0)) {
01168             ast_log(LOG_WARNING, "State '%s' is already defined\n", vname);
01169             break;
01170          }
01171          disp = getdisplaybyname(state, vname, script, lineno, 1);
01172          if (!disp)
01173             break;
01174          args = get_token(&buf, script, lineno);
01175          if (!args || strcasecmp(args, "IS")) {
01176             ast_log(LOG_WARNING, "Missing 'IS' at line %d of %s\n", lineno, script);
01177             break;
01178          }
01179          args = get_token(&buf, script, lineno);
01180          if (!args) {
01181             ast_log(LOG_WARNING, "Missing Column 1 text at line %d of %s\n", lineno, script);
01182             break;
01183          }
01184          if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
01185             ast_log(LOG_WARNING, "Token '%s' is not valid column 1 text at line %d of %s\n", args, lineno, script);
01186             break;
01187          }
01188          if (strlen(tmp) > 20) {
01189             ast_log(LOG_WARNING, "Truncating column one to 20 characters at line %d of %s\n", lineno, script);
01190             tmp[20] = '\0';
01191          }
01192          memcpy(disp->data + 5, tmp, strlen(tmp));
01193          disp->datalen = strlen(tmp) + 5;
01194          disp->data[disp->datalen++] = 0xff;
01195 
01196          args = get_token(&buf, script, lineno);
01197          if (args && !process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
01198             /* Got a column two */
01199             if (strlen(tmp) > 20) {
01200                ast_log(LOG_WARNING, "Truncating column two to 20 characters at line %d of %s\n", lineno, script);
01201                tmp[20] = '\0';
01202             }
01203             memcpy(disp->data + disp->datalen, tmp, strlen(tmp));
01204             disp->datalen += strlen(tmp);
01205             args = get_token(&buf, script, lineno);
01206          }
01207          while(args) {
01208             if (!strcasecmp(args, "JUSTIFY")) {
01209                args = get_token(&buf, script, lineno);
01210                if (!args) {
01211                   ast_log(LOG_WARNING, "Qualifier 'JUSTIFY' requires an argument at line %d of %s\n", lineno, script);
01212                   break;
01213                }
01214                lrci = getjustifybyname(args);
01215                if (lrci < 0) {
01216                   ast_log(LOG_WARNING, "'%s' is not a valid justification at line %d of %s\n", args, lineno, script);
01217                   break;
01218                }
01219             } else if (!strcasecmp(args, "WRAP")) {
01220                wi = 0x80;
01221             } else {
01222                ast_log(LOG_WARNING, "'%s' is not a known qualifier at line %d of %s\n", args, lineno, script);
01223                break;
01224             }
01225             args = get_token(&buf, script, lineno);
01226          }
01227          if (args) {
01228             /* Something bad happened */
01229             break;
01230          }
01231          disp->data[0] = 129;
01232          disp->data[1] = disp->datalen - 2;
01233          disp->data[2] = ((lrci & 0x3) << 6) | disp->id;
01234          disp->data[3] = wi;
01235          disp->data[4] = 0xff;
01236       } else {
01237          ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in PROGRAM\n", keyword);
01238       }
01239       break;
01240    case STATE_INKEY:
01241       if (process_returncode(state->key, keyword, buf, state, script, lineno)) {
01242          if (!strcasecmp(keyword, "ENDKEY")) {
01243             /* Return to normal operation and increment current key */
01244             state->state = STATE_NORMAL;
01245             state->key->defined = 1;
01246             state->key->retstr[1] = state->key->retstrlen - 2;
01247             state->key = NULL;
01248          } else {
01249             ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SOFTKEY definition at line %d of %s\n", keyword, lineno, script);
01250          }
01251       }
01252       break;
01253    case STATE_INIF:
01254       if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
01255          if (!strcasecmp(keyword, "ENDIF")) {
01256             /* Return to normal SUB operation and increment current key */
01257             state->state = STATE_INSUB;
01258             state->sub->defined = 1;
01259             /* Store the proper number of instructions */
01260             state->sub->ifdata[2] = state->sub->ifinscount;
01261          } else if (!strcasecmp(keyword, "GOTO")) {
01262             args = get_token(&buf, script, lineno);
01263             if (!args) {
01264                ast_log(LOG_WARNING, "GOTO clause missing Subscript name at line %d of %s\n", lineno, script);
01265                break;
01266             }
01267             if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
01268                ast_log(LOG_WARNING, "'%s' is not a valid subscript name token at line %d of %s\n", args, lineno, script);
01269                break;
01270             }
01271             newsub = getsubbyname(state, tmp, script, lineno);
01272             if (!newsub) 
01273                break;
01274             /* Somehow you use GOTO to go to another place */
01275             state->sub->data[state->sub->datalen++] = 0x8;
01276             state->sub->data[state->sub->datalen++] = state->sub->ifdata[1];
01277             state->sub->data[state->sub->datalen++] = newsub->id;
01278             /* Terminate */
01279             state->sub->data[state->sub->datalen++] = 0xff;
01280             /* Increment counters */
01281             state->sub->inscount++;
01282             state->sub->ifinscount++;
01283          } else {
01284             ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in IF clause at line %d of %s\n", keyword, lineno, script);
01285          }
01286       } else
01287          state->sub->ifinscount++;
01288       break;
01289    case STATE_INSUB:
01290       if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
01291          if (!strcasecmp(keyword, "ENDSUB")) {
01292             /* Return to normal operation and increment current key */
01293             state->state = STATE_NORMAL;
01294             state->sub->defined = 1;
01295             /* Store the proper length */
01296             state->sub->data[1] = state->sub->datalen - 2;
01297             if (state->sub->id) {
01298                /* if this isn't main, store number of instructions, too */
01299                state->sub->data[5] = state->sub->inscount;
01300             }
01301             state->sub = NULL;
01302          } else if (!strcasecmp(keyword, "IFEVENT")) {
01303             args = get_token(&buf, script, lineno);
01304             if (!args) {
01305                ast_log(LOG_WARNING, "IFEVENT clause missing Event name at line %d of %s\n", lineno, script);
01306                break;
01307             }
01308             event = geteventbyname(args);
01309             if (event < 1) {
01310                ast_log(LOG_WARNING, "'%s' is not a valid event\n", args);
01311                break;
01312             }
01313             args = get_token(&buf, script, lineno);
01314             if (!args || strcasecmp(args, "THEN")) {
01315                ast_log(LOG_WARNING, "IFEVENT clause missing 'THEN' at line %d of %s\n", lineno, script);
01316                break;
01317             }
01318             state->sub->ifinscount = 0;
01319             state->sub->ifdata = state->sub->data + 
01320                   state->sub->datalen;
01321             /* Reserve header and insert op codes */
01322             state->sub->ifdata[0] = 0x1;
01323             state->sub->ifdata[1] = event;
01324             /* 2 is for the number of instructions */
01325             state->sub->ifdata[3] = 0xff;
01326             state->sub->datalen += 4;
01327             /* Update Subscript instruction count */
01328             state->sub->inscount++;
01329             state->state = STATE_INIF;
01330          } else {
01331             ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SUB definition at line %d of %s\n", keyword, lineno, script);
01332          }
01333       }
01334       break;
01335    default:
01336       ast_log(LOG_WARNING, "Can't process keyword '%s' in weird state %d\n", keyword, state->state);
01337    }
01338    return 0;
01339 }

static int adsi_prog ( struct ast_channel chan,
char *  script 
) [static]

Definition at line 1436 of file app_adsiprog.c.

References adsi_begin_download(), adsi_load_session(), ADSI_MSG_DOWNLOAD, adsi_transmit_message(), ast_log(), ast_verbose(), compile_script(), adsi_script::desc, adsi_script::fdn, free, adsi_script::keys, LOG_NOTICE, LOG_WARNING, ast_channel::name, adsi_script::numkeys, option_verbose, adsi_soft_key::retstr, adsi_soft_key::retstrlen, adsi_script::sec, adsi_script::ver, VERBOSE_PREFIX_3, and adsi_soft_key::vname.

Referenced by adsi_exec().

01437 {
01438    struct adsi_script *scr;
01439    int x;
01440    unsigned char buf[1024];
01441    int bytes;
01442    scr = compile_script(script);
01443    if (!scr) 
01444       return -1;
01445 
01446    /* Start an empty ADSI Session */
01447    if (adsi_load_session(chan, NULL, 0, 1) < 1) 
01448       return -1;
01449 
01450    /* Now begin the download attempt */
01451    if (adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
01452       /* User rejected us for some reason */
01453       if (option_verbose > 2)
01454          ast_verbose(VERBOSE_PREFIX_3 "User rejected download attempt\n");
01455       ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name);
01456       free(scr);
01457       return -1;
01458    }
01459 
01460    bytes = 0;
01461    /* Start with key definitions */
01462    for (x=0;x<scr->numkeys;x++) {
01463       if (bytes + scr->keys[x].retstrlen > 253) {
01464          /* Send what we've collected so far */
01465          if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01466             ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01467             return -1;
01468          }
01469          bytes =0;
01470       }
01471       memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
01472       bytes += scr->keys[x].retstrlen;
01473 #ifdef DUMP_MESSAGES
01474       dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
01475 #endif
01476    }
01477    if (bytes) {
01478       if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01479          ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01480          return -1;
01481       }
01482    }
01483 
01484    bytes = 0;
01485    /* Continue with the display messages */
01486    for (x=0;x<scr->numdisplays;x++) {
01487       if (bytes + scr->displays[x].datalen > 253) {
01488          /* Send what we've collected so far */
01489          if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01490             ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01491             return -1;
01492          }
01493          bytes =0;
01494       }
01495       memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
01496       bytes += scr->displays[x].datalen;
01497 #ifdef DUMP_MESSAGES
01498       dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
01499 #endif
01500    }
01501    if (bytes) {
01502       if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01503          ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01504          return -1;
01505       }
01506    }
01507 
01508    bytes = 0;
01509    /* Send subroutines */
01510    for (x=0;x<scr->numsubs;x++) {
01511       if (bytes + scr->subs[x].datalen > 253) {
01512          /* Send what we've collected so far */
01513          if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01514             ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01515             return -1;
01516          }
01517          bytes =0;
01518       }
01519       memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
01520       bytes += scr->subs[x].datalen;
01521 #ifdef DUMP_MESSAGES
01522       dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
01523 #endif
01524    }
01525    if (bytes) {
01526       if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01527          ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01528          return -1;
01529       }
01530    }
01531 
01532 
01533    bytes = 0;
01534    bytes += adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
01535    bytes += adsi_set_line(buf, ADSI_INFO_PAGE, 1);
01536    if (adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
01537       return -1;
01538    if (adsi_end_download(chan)) {
01539       /* Download failed for some reason */
01540       if (option_verbose > 2)
01541          ast_verbose(VERBOSE_PREFIX_3 "Download attempt failed\n");
01542       ast_log(LOG_NOTICE, "Download failed on %s\n", chan->name);
01543       free(scr);
01544       return -1;
01545    }
01546    free(scr);
01547    adsi_unload_session(chan);
01548    return 0;
01549 }

static int clearcbone ( char *  buf,
char *  name,