Sun Oct 12 06:28:55 2008

Asterisk developer's documentation


app_adsiprog.c File Reference

Program Asterisk ADSI Scripts into phone. More...

#include "asterisk.h"
#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/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)
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Asterisk ADSI Programming Application")
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)
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)
static int load_module (void)
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)
static int unload_module (void)

Variables

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


Detailed Description

Program Asterisk ADSI Scripts into phone.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_adsiprog.c.


Define Documentation

#define ARG_NUMBER   (1 << 1)

Definition at line 115 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 114 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 112 of file app_adsiprog.c.

Referenced by process_opcode().

#define MAX_RET_CODE   20

Definition at line 110 of file app_adsiprog.c.

Referenced by process_returncode().

#define MAX_SUB_LEN   255

Definition at line 111 of file app_adsiprog.c.

Referenced by process_opcode().

#define STATE_INIF   3

Definition at line 108 of file app_adsiprog.c.

Referenced by adsi_process().

#define STATE_INKEY   1

Definition at line 106 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_INSUB   2

Definition at line 107 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_NORMAL   0

Definition at line 105 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 1549 of file app_adsiprog.c.

References adsi_prog(), ast_adsi_available(), ast_module_user_add, ast_module_user_remove, ast_strlen_zero(), ast_verbose(), ast_module_user::chan, option_verbose, and VERBOSE_PREFIX_3.

Referenced by load_module().

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

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

Definition at line 964 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, event, 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().

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

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

Definition at line 1434 of file app_adsiprog.c.

References ADSI_MSG_DOWNLOAD, ast_adsi_begin_download(), ast_adsi_load_session(), ast_adsi_transmit_message(), ast_log(), ast_verbose(), compile_script(), adsi_script::desc, adsi_script::fdn, free, adsi_script::keys, LOG_NOTICE, LOG_WARNING, 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().

01435 {
01436    struct adsi_script *scr;
01437    int x;
01438    unsigned char buf[1024];
01439    int bytes;
01440    scr = compile_script(script);
01441    if (!scr) 
01442       return -1;
01443 
01444    /* Start an empty ADSI Session */
01445    if (ast_adsi_load_session(chan, NULL, 0, 1) < 1) 
01446       return -1;
01447 
01448    /* Now begin the download attempt */
01449    if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
01450       /* User rejected us for some reason */
01451       if (option_verbose > 2)
01452          ast_verbose(VERBOSE_PREFIX_3 "User rejected download attempt\n");
01453       ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name);
01454       free(scr);
01455       return -1;
01456    }
01457 
01458    bytes = 0;
01459    /* Start with key definitions */
01460    for (x=0;x<scr->numkeys;x++) {
01461       if (bytes + scr->keys[x].retstrlen > 253) {
01462          /* Send what we've collected so far */
01463          if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01464             ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01465             return -1;
01466          }
01467          bytes =0;
01468       }
01469       memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
01470       bytes += scr->keys[x].retstrlen;
01471 #ifdef DUMP_MESSAGES
01472       dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
01473 #endif
01474    }
01475    if (bytes) {
01476       if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01477          ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01478          return -1;
01479       }
01480    }
01481 
01482    bytes = 0;
01483    /* Continue with the display messages */
01484    for (x=0;x<scr->numdisplays;x++) {
01485       if (bytes + scr->displays[x].datalen > 253) {
01486          /* Send what we've collected so far */
01487          if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01488             ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01489             return -1;
01490          }
01491          bytes =0;
01492       }
01493       memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
01494       bytes += scr->displays[x].datalen;
01495 #ifdef DUMP_MESSAGES
01496       dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
01497 #endif
01498    }
01499    if (bytes) {
01500       if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01501          ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
01502          return -1;
01503       }
01504    }
01505 
01506    bytes = 0;
01507    /* Send subroutines */
01508    for (x=0;x<scr->numsubs;x++) {
01509       if (bytes + scr->subs[x].datalen > 253) {
01510          /* Send what we've collected so far */
01511          if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
01512             ast_log(