#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_script * | compile_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_display * | getdisplaybyname (struct adsi_script *state, char *name, char *script, int lineno, int create) |
static int | geteventbyname (char *name) |
static struct adsi_flag * | getflagbyname (struct adsi_script *state, char *name, char *script, int lineno, int create) |
static int | getjustifybyname (char *name) |
static struct adsi_soft_key * | getkeybyname (struct adsi_script *state, char *name, char *script, int lineno) |
static struct adsi_state * | getstatebyname (struct adsi_script *state, char *name, char *script, int lineno, int create) |
static struct adsi_subscript * | getsubbyname (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" |
Definition in file app_adsiprog.c.
#define ARG_NUMBER (1 << 1) |
Definition at line 111 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 110 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 |
#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 |
static int adsi_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 1545 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().
01546 { 01547 int res=0; 01548 struct ast_module_user *u; 01549 01550 u = ast_module_user_add(chan); 01551 01552 if (ast_strlen_zero(data)) 01553 data = "asterisk.adsi"; 01554 01555 if (!ast_adsi_available(chan)) { 01556 if (option_verbose > 2) 01557 ast_verbose(VERBOSE_PREFIX_3 "ADSI Unavailable on CPE. Not bothering to try.\n"); 01558 } else { 01559 if (option_verbose > 2) 01560 ast_verbose(VERBOSE_PREFIX_3 "ADSI Available on CPE. Attempting Upload.\n"); 01561 res = adsi_prog(chan, data); 01562 } 01563 01564 ast_module_user_remove(u); 01565 01566 return res; 01567 }
static int adsi_process | ( | struct adsi_script * | state, | |
char * | buf, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 960 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().
00961 { 00962 char *keyword; 00963 char *args; 00964 char vname[256]; 00965 char tmp[80]; 00966 char tmp2[80]; 00967 int lrci; 00968 int wi; 00969 int event; 00970 struct adsi_display *disp; 00971 struct adsi_subscript *newsub; 00972 /* Find the first keyword */ 00973 keyword = get_token(&buf, script, lineno); 00974 if (!keyword) 00975 return 0; 00976 switch(state->state) { 00977 case STATE_NORMAL: 00978 if (!strcasecmp(keyword, "DESCRIPTION")) { 00979 args = get_token(&buf, script, lineno); 00980 if (args) { 00981 if (process_token(state->desc, args, sizeof(state->desc) - 1, ARG_STRING)) 00982 ast_log(LOG_WARNING, "'%s' is not a valid token for DESCRIPTION at line %d of %s\n", args, lineno, script); 00983 } else 00984 ast_log(LOG_WARNING, "Missing argument for DESCRIPTION at line %d of %s\n", lineno, script); 00985 } else if (!strcasecmp(keyword, "VERSION")) { 00986 args = get_token(&buf, script, lineno); 00987 if (args) { 00988 if (process_token(&state->ver, args, sizeof(state->ver) - 1, ARG_NUMBER)) 00989 ast_log(LOG_WARNING, "'%s' is not a valid token for VERSION at line %d of %s\n", args, lineno, script); 00990 } else 00991 ast_log(LOG_WARNING, "Missing argument for VERSION at line %d of %s\n", lineno, script); 00992 } else if (!strcasecmp(keyword, "SECURITY")) { 00993 args = get_token(&buf, script, lineno); 00994 if (args) { 00995 if (process_token(state->sec, args, sizeof(state->sec) - 1, ARG_STRING | ARG_NUMBER)) 00996 ast_log(LOG_WARNING, "'%s' is not a valid token for SECURITY at line %d of %s\n", args, lineno, script); 00997 } else 00998 ast_log(LOG_WARNING, "Missing argument for SECURITY at line %d of %s\n", lineno, script); 00999 } else if (!strcasecmp(keyword, "FDN")) { 01000 args = get_token(&buf, script, lineno); 01001 if (args) { 01002 if (process_token(state->fdn, args, sizeof(state->fdn) - 1, ARG_STRING | ARG_NUMBER)) 01003 ast_log(LOG_WARNING, "'%s' is not a valid token for FDN at line %d of %s\n", args, lineno, script); 01004 } else 01005 ast_log(LOG_WARNING, "Missing argument for FDN at line %d of %s\n", lineno, script); 01006 } else if (!strcasecmp(keyword, "KEY")) { 01007 args = get_token(&buf, script, lineno); 01008 if (!args) { 01009 ast_log(LOG_WARNING, "KEY definition missing name at line %d of %s\n", lineno, script); 01010 break; 01011 } 01012 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) { 01013 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script); 01014 break; 01015 } 01016 state->key = getkeybyname(state, vname, script, lineno); 01017 if (!state->key) { 01018 ast_log(LOG_WARNING, "Out of key space at line %d of %s\n", lineno, script); 01019 break; 01020 } 01021 if (state->key->defined) { 01022 ast_log(LOG_WARNING, "Cannot redefine key '%s' at line %d of %s\n", vname, lineno, script); 01023 break; 01024 } 01025 args = get_token(&buf, script, lineno); 01026 if (!args || strcasecmp(args, "IS")) { 01027 ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script); 01028 break; 01029 } 01030 args = get_token(&buf, script, lineno); 01031 if (!args) { 01032 ast_log(LOG_WARNING, "KEY definition missing short name at line %d of %s\n", lineno, script); 01033 break; 01034 } 01035 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) { 01036 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY short name at line %d of %s\n", args, lineno, script); 01037 break; 01038 } 01039 args = get_token(&buf, script, lineno); 01040 if (args) { 01041 if (strcasecmp(args, "OR")) { 01042 ast_log(LOG_WARNING, "Expecting 'OR' but got '%s' instead at line %d of %s\n", args, lineno, script); 01043 break; 01044 } 01045 args = get_token(&buf, script, lineno); 01046 if (!args) { 01047 ast_log(LOG_WARNING, "KEY definition missing optional long name at line %d of %s\n", lineno, script); 01048 break; 01049 } 01050 if (process_token(tmp2, args, sizeof(tmp2) - 1, ARG_STRING)) { 01051 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY long name at line %d of %s\n", args, lineno, script); 01052 break; 01053 } 01054 } else { 01055 ast_copy_string(tmp2, tmp, sizeof(tmp2)); 01056 } 01057 if (strlen(tmp2) > 18) { 01058 ast_log(LOG_WARNING, "Truncating full name to 18 characters at line %d of %s\n", lineno, script); 01059 tmp2[18] = '\0'; 01060 } 01061 if (strlen(tmp) > 7) { 01062 ast_log(LOG_WARNING, "Truncating short name to 7 bytes at line %d of %s\n", lineno, script); 01063 tmp[7] = '\0'; 01064 } 01065 /* Setup initial stuff */ 01066 state->key->retstr[0] = 128; 01067 /* 1 has the length */ 01068 state->key->retstr[2] = state->key->id; 01069 /* Put the Full name in */ 01070 memcpy(state->key->retstr + 3, tmp2, strlen(tmp2)); 01071 /* Update length */ 01072 state->key->retstrlen = strlen(tmp2) + 3; 01073 /* Put trailing 0xff */ 01074 state->key->retstr[state->key->retstrlen++] = 0xff; 01075 /* Put the short name */ 01076 memcpy(state->key->retstr + state->key->retstrlen, tmp, strlen(tmp)); 01077 /* Update length */ 01078 state->key->retstrlen += strlen(tmp); 01079 /* Put trailing 0xff */ 01080 state->key->retstr[state->key->retstrlen++] = 0xff; 01081 /* Record initial length */ 01082 state->key->initlen = state->key->retstrlen; 01083 state->state = STATE_INKEY; 01084 } else if (!strcasecmp(keyword, "SUB")) { 01085 args = get_token(&buf, script, lineno); 01086 if (!args) { 01087 ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script); 01088 break; 01089 } 01090 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) { 01091 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script); 01092 break; 01093 } 01094 state->sub = getsubbyname(state, vname, script, lineno); 01095 if (!state->sub) { 01096 ast_log(LOG_WARNING, "Out of subroutine space at line %d of %s\n", lineno, script); 01097 break; 01098 } 01099 if (state->sub->defined) { 01100 ast_log(LOG_WARNING, "Cannot redefine subroutine '%s' at line %d of %s\n", vname, lineno, script); 01101 break; 01102 } 01103 /* Setup sub */ 01104 state->sub->data[0] = 130; 01105 /* 1 is the length */ 01106 state->sub->data[2] = 0x0; /* Clear extensibility bit */ 01107 state->sub->datalen = 3; 01108 if (state->sub->id) { 01109 /* If this isn't the main subroutine, make a subroutine label for it */ 01110 state->sub->data[3] = 9; 01111 state->sub->data[4] = state->sub->id; 01112 /* 5 is length */ 01113 state->sub->data[6] = 0xff; 01114 state->sub->datalen = 7; 01115 } 01116 args = get_token(&buf, script, lineno); 01117 if (!args || strcasecmp(args, "IS")) { 01118 ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script); 01119 break; 01120 } 01121 state->state = STATE_INSUB; 01122 } else if (!strcasecmp(keyword, "STATE")) { 01123 args = get_token(&buf, script, lineno); 01124 if (!args) { 01125 ast_log(LOG_WARNING, "STATE definition missing name at line %d of %s\n", lineno, script); 01126 break; 01127 } 01128 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) { 01129 ast_log(LOG_WARNING, "'%s' is not a valid token for a STATE name at line %d of %s\n", args, lineno, script); 01130 break; 01131 } 01132 if (getstatebyname(state, vname, script, lineno, 0)) { 01133 ast_log(LOG_WARNING, "State '%s' is already defined at line %d of %s\n", vname, lineno, script); 01134 break; 01135 } 01136 getstatebyname(state, vname, script, lineno, 1); 01137 } else if (!strcasecmp(keyword, "FLAG")) { 01138 args = get_token(&buf, script, lineno); 01139 if (!args) { 01140 ast_log(LOG_WARNING, "FLAG definition missing name at line %d of %s\n", lineno, script); 01141 break; 01142 } 01143 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) { 01144 ast_log(LOG_WARNING, "'%s' is not a valid token for a FLAG name at line %d of %s\n", args, lineno, script); 01145 break; 01146 } 01147 if (getflagbyname(state, vname, script, lineno, 0)) { 01148 ast_log(LOG_WARNING, "Flag '%s' is already defined\n", vname); 01149 break; 01150 } 01151 getflagbyname(state, vname, script, lineno, 1); 01152 } else if (!strcasecmp(keyword, "DISPLAY")) { 01153 lrci = 0; 01154 wi = 0; 01155 args = get_token(&buf, script, lineno); 01156 if (!args) { 01157 ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script); 01158 break; 01159 } 01160 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) { 01161 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script); 01162 break; 01163 } 01164 if (getdisplaybyname(state, vname, script, lineno, 0)) { 01165 ast_log(LOG_WARNING, "State '%s' is already defined\n", vname); 01166 break; 01167 } 01168 disp = getdisplaybyname(state, vname, script, lineno, 1); 01169 if (!disp) 01170 break; 01171 args = get_token(&buf, script, lineno); 01172 if (!args || strcasecmp(args, "IS")) { 01173 ast_log(LOG_WARNING, "Missing 'IS' at line %d of %s\n", lineno, script); 01174 break; 01175 } 01176 args = get_token(&buf, script, lineno); 01177 if (!args) { 01178 ast_log(LOG_WARNING, "Missing Column 1 text at line %d of %s\n", lineno, script); 01179 break; 01180 } 01181 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) { 01182 ast_log(LOG_WARNING, "Token '%s' is not valid column 1 text at line %d of %s\n", args, lineno, script); 01183 break; 01184 } 01185 if (strlen(tmp) > 20) { 01186 ast_log(LOG_WARNING, "Truncating column one to 20 characters at line %d of %s\n", lineno, script); 01187 tmp[20] = '\0'; 01188 } 01189 memcpy(disp->data + 5, tmp, strlen(tmp)); 01190 disp->datalen = strlen(tmp) + 5; 01191 disp->data[disp->datalen++] = 0xff; 01192 01193 args = get_token(&buf, script, lineno); 01194 if (args && !process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) { 01195 /* Got a column two */ 01196 if (strlen(tmp) > 20) { 01197 ast_log(LOG_WARNING, "Truncating column two to 20 characters at line %d of %s\n", lineno, script); 01198 tmp[20] = '\0'; 01199 } 01200 memcpy(disp->data + disp->datalen, tmp, strlen(tmp)); 01201 disp->datalen += strlen(tmp); 01202 args = get_token(&buf, script, lineno); 01203 } 01204 while(args) { 01205 if (!strcasecmp(args, "JUSTIFY")) { 01206 args = get_token(&buf, script, lineno); 01207 if (!args) { 01208 ast_log(LOG_WARNING, "Qualifier 'JUSTIFY' requires an argument at line %d of %s\n", lineno, script); 01209 break; 01210 } 01211 lrci = getjustifybyname(args); 01212 if (lrci < 0) { 01213 ast_log(LOG_WARNING, "'%s' is not a valid justification at line %d of %s\n", args, lineno, script); 01214 break; 01215 } 01216 } else if (!strcasecmp(args, "WRAP")) { 01217 wi = 0x80; 01218 } else { 01219 ast_log(LOG_WARNING, "'%s' is not a known qualifier at line %d of %s\n", args, lineno, script); 01220 break; 01221 } 01222 args = get_token(&buf, script, lineno); 01223 } 01224 if (args) { 01225 /* Something bad happened */ 01226 break; 01227 } 01228 disp->data[0] = 129; 01229 disp->data[1] = disp->datalen - 2; 01230 disp->data[2] = ((lrci & 0x3) << 6) | disp->id; 01231 disp->data[3] = wi; 01232 disp->data[4] = 0xff; 01233 } else { 01234 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in PROGRAM\n", keyword); 01235 } 01236 break; 01237 case STATE_INKEY: 01238 if (process_returncode(state->key, keyword, buf, state, script, lineno)) { 01239 if (!strcasecmp(keyword, "ENDKEY")) { 01240 /* Return to normal operation and increment current key */ 01241 state->state = STATE_NORMAL; 01242 state->key->defined = 1; 01243 state->key->retstr[1] = state->key->retstrlen - 2; 01244 state->key = NULL; 01245 } else { 01246 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SOFTKEY definition at line %d of %s\n", keyword, lineno, script); 01247 } 01248 } 01249 break; 01250 case STATE_INIF: 01251 if (process_opcode(state->sub, keyword, buf, state, script, lineno)) { 01252 if (!strcasecmp(keyword, "ENDIF")) { 01253 /* Return to normal SUB operation and increment current key */ 01254 state->state = STATE_INSUB; 01255 state->sub->defined = 1; 01256 /* Store the proper number of instructions */ 01257 state->sub->ifdata[2] = state->sub->ifinscount; 01258 } else if (!strcasecmp(keyword, "GOTO")) { 01259 args = get_token(&buf, script, lineno); 01260 if (!args) { 01261 ast_log(LOG_WARNING, "GOTO clause missing Subscript name at line %d of %s\n", lineno, script); 01262 break; 01263 } 01264 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) { 01265 ast_log(LOG_WARNING, "'%s' is not a valid subscript name token at line %d of %s\n", args, lineno, script); 01266 break; 01267 } 01268 newsub = getsubbyname(state, tmp, script, lineno); 01269 if (!newsub) 01270 break; 01271 /* Somehow you use GOTO to go to another place */ 01272 state->sub->data[state->sub->datalen++] = 0x8; 01273 state->sub->data[state->sub->datalen++] = state->sub->ifdata[1]; 01274 state->sub->data[state->sub->datalen++] = newsub->id; 01275 /* Terminate */ 01276 state->sub->data[state->sub->datalen++] = 0xff; 01277 /* Increment counters */ 01278 state->sub->inscount++; 01279 state->sub->ifinscount++; 01280 } else { 01281 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in IF clause at line %d of %s\n", keyword, lineno, script); 01282 } 01283 } else 01284 state->sub->ifinscount++; 01285 break; 01286 case STATE_INSUB: 01287 if (process_opcode(state->sub, keyword, buf, state, script, lineno)) { 01288 if (!strcasecmp(keyword, "ENDSUB")) { 01289 /* Return to normal operation and increment current key */ 01290 state->state = STATE_NORMAL; 01291 state->sub->defined = 1; 01292 /* Store the proper length */ 01293 state->sub->data[1] = state->sub->datalen - 2; 01294 if (state->sub->id) { 01295 /* if this isn't main, store number of instructions, too */ 01296 state->sub->data[5] = state->sub->inscount; 01297 } 01298 state->sub = NULL; 01299 } else if (!strcasecmp(keyword, "IFEVENT")) { 01300 args = get_token(&buf, script, lineno); 01301 if (!args) { 01302 ast_log(LOG_WARNING, "IFEVENT clause missing Event name at line %d of %s\n", lineno, script); 01303 break; 01304 } 01305 event = geteventbyname(args); 01306 if (event < 1) { 01307 ast_log(LOG_WARNING, "'%s' is not a valid event\n", args); 01308 break; 01309 } 01310 args = get_token(&buf, script, lineno); 01311 if (!args || strcasecmp(args, "THEN")) { 01312 ast_log(LOG_WARNING, "IFEVENT clause missing 'THEN' at line %d of %s\n", lineno, script); 01313 break; 01314 } 01315 state->sub->ifinscount = 0; 01316 state->sub->ifdata = state->sub->data + 01317 state->sub->datalen; 01318 /* Reserve header and insert op codes */ 01319 state->sub->ifdata[0] = 0x1; 01320 state->sub->ifdata[1] = event; 01321 /* 2 is for the number of instructions */ 01322 state->sub->ifdata[3] = 0xff; 01323 state->sub->datalen += 4; 01324 /* Update Subscript instruction count */ 01325 state->sub->inscount++; 01326 state->state = STATE_INIF; 01327 } else { 01328 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SUB definition at line %d of %s\n", keyword, lineno, script); 01329 } 01330 } 01331 break; 01332 default: 01333 ast_log(LOG_WARNING, "Can't process keyword '%s' in weird state %d\n", keyword, state->state); 01334 } 01335 return 0; 01336 }
static int adsi_prog | ( | struct ast_channel * | chan, | |
char * | script | |||
) | [static] |
Definition at line 1430 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().
01431 { 01432 struct adsi_script *scr; 01433 int x; 01434 unsigned char buf[1024]; 01435 int bytes; 01436 scr = compile_script(script); 01437 if (!scr) 01438 return -1; 01439 01440 /* Start an empty ADSI Session */ 01441 if (ast_adsi_load_session(chan, NULL, 0, 1) < 1) 01442 return -1; 01443 01444 /* Now begin the download attempt */ 01445 if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) { 01446 /* User rejected us for some reason */ 01447 if (option_verbose > 2) 01448 ast_verbose(VERBOSE_PREFIX_3 "User rejected download attempt\n"); 01449 ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name); 01450 free(scr); 01451 return -1; 01452 } 01453 01454 bytes = 0; 01455 /* Start with key definitions */ 01456 for (x=0;x<scr->numkeys;x++) { 01457 if (bytes + scr->keys[x].retstrlen > 253) { 01458 /* Send what we've collected so far */ 01459 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01460 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01461 return -1; 01462 } 01463 bytes =0; 01464 } 01465 memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen); 01466 bytes += scr->keys[x].retstrlen; 01467 #ifdef DUMP_MESSAGES 01468 dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen); 01469 #endif 01470 } 01471 if (bytes) { 01472 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01473 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01474 return -1; 01475 } 01476 } 01477 01478 bytes = 0; 01479 /* Continue with the display messages */ 01480 for (x=0;x<scr->numdisplays;x++) { 01481 if (bytes + scr->displays[x].datalen > 253) { 01482 /* Send what we've collected so far */ 01483 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01484 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01485 return -1; 01486 } 01487 bytes =0; 01488 } 01489 memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen); 01490 bytes += scr->displays[x].datalen; 01491 #ifdef DUMP_MESSAGES 01492 dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen); 01493 #endif 01494 } 01495 if (bytes) { 01496 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01497 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01498 return -1; 01499 } 01500 } 01501 01502 bytes = 0; 01503 /* Send subroutines */ 01504 for (x=0;x<scr->numsubs;x++) { 01505 if (bytes + scr->subs[x].datalen > 253) { 01506 /* Send what we've collected so far */ 01507 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01508 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01509 return -1; 01510 } 01511 bytes =0; 01512 } 01513 memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen); 01514 bytes += scr->subs[x].datalen; 01515 #ifdef DUMP_MESSAGES 01516 dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen); 01517 #endif 01518 } 01519 if (bytes) { 01520 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) { 01521 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x); 01522 return -1; 01523 } 01524 } 01525 01526 01527 bytes = 0; 01528 bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", ""); 01529 bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1); 01530 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0) 01531 return -1; 01532 if (ast_adsi_end_download(chan)) { 01533 /* Download failed for some reason */ 01534 if (option_verbose > 2) 01535 ast_verbose(VERBOSE_PREFIX_3 "Download attempt failed\n"); 01536 ast_log(LOG_NOTICE, "Download failed on %s\n", chan->name); 01537 free(scr); 01538 return -1; 01539 } 01540 free(scr); 01541 ast_adsi_unload_session(chan); 01542 return 0; 01543 }
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] |
Definition at line 707 of file app_adsiprog.c.
References ast_log(), get_token(), and LOG_WARNING.
00708 { 00709 char *tok; 00710 tok = get_token(&args, script, lineno); 00711 if (tok) 00712 ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script); 00713 00714 buf[0] = id; 00715 buf[1] = 0; 00716 return 2; 00717 }
static int cleardisplay | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 683 of file app_adsiprog.c.
References ast_log(), get_token(), and LOG_WARNING.
00684 { 00685 char *tok; 00686 tok = get_token(&args, script, lineno); 00687 if (tok) 00688 ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script); 00689 00690 buf[0] = id; 00691 buf[1] = 0x00; 00692 return 2; 00693 }
static int clearflag | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 442 of file app_adsiprog.c.
References ARG_STRING, ast_log(), get_token(), getflagbyname(), adsi_flag::id, LOG_WARNING, and process_token().
00443 { 00444 char *tok; 00445 struct adsi_flag *flag; 00446 char sname[80]; 00447 tok = get_token(&args, script, lineno); 00448 if (!tok) { 00449 ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script); 00450 return 0; 00451 } 00452 if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) { 00453 ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script); 00454 return 0; 00455 } 00456 flag = getflagbyname(state, sname, script, lineno, 0); 00457 if (!flag) { 00458 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script); 00459 return 0; 00460 } 00461 buf[0] = id; 00462 buf[1] = ((flag->id & 0x7) << 4); 00463 return 2; 00464 }
static int cleartimer | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 383 of file app_adsiprog.c.
References ast_log(), get_token(), and LOG_WARNING.
00384 { 00385 char *tok; 00386 tok = get_token(&args, script, lineno); 00387 if (tok) 00388 ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script); 00389 00390 buf[0] = id; 00391 /* For some reason the clear code is different slightly */ 00392 if (id == 7) 00393 buf[1] = 0x10; 00394 else 00395 buf[1] = 0x00; 00396 return 2; 00397 }
static struct adsi_script* compile_script | ( | char * | script | ) | [static] |
Definition at line 1338 of file app_adsiprog.c.
References adsi_process(), ast_calloc, ast_config_AST_CONFIG_DIR, ast_log(), ast_strlen_zero(), f, free, getsubbyname(), lineno, LOG_WARNING, STATE_INKEY, STATE_INSUB, and STATE_NORMAL.
Referenced by adsi_prog().
01339 { 01340 FILE *f; 01341 char fn[256]; 01342 char buf[256]; 01343 char *c; 01344 int lineno=0; 01345 int x, err; 01346 struct adsi_script *scr; 01347 if (script[0] == '/') 01348 ast_copy_string(fn, script, sizeof(fn)); 01349 else 01350 snprintf(fn, sizeof(fn), "%s/%s", (char *)ast_config_AST_CONFIG_DIR, script); 01351 f = fopen(fn, "r"); 01352 if (!f) { 01353 ast_log(LOG_WARNING, "Can't open file '%s'\n", fn); 01354 return NULL; 01355 } 01356 if (!(scr = ast_calloc(1, sizeof(*scr)))) { 01357 fclose(f); 01358 return NULL; 01359 } 01360 /* Create "main" as first subroutine */ 01361 getsubbyname(scr, "main", NULL, 0); 01362 while(!feof(f)) { 01363 fgets(buf, sizeof(buf), f); 01364 if (!feof(f)) { 01365 lineno++; 01366 /* Trim off trailing return */ 01367 buf[strlen(buf) - 1] = '\0'; 01368 c = strchr(buf, ';'); 01369 /* Strip comments */ 01370 if (c) 01371 *c = '\0'; 01372 if (!ast_strlen_zero(buf)) 01373 adsi_process(scr, buf, script, lineno); 01374 } 01375 } 01376 fclose(f); 01377 /* Make sure we're in the main routine again */ 01378 switch(scr->state) { 01379 case STATE_NORMAL: 01380 break; 01381 case STATE_INSUB: 01382 ast_log(LOG_WARNING, "Missing ENDSUB at end of file %s\n", script); 01383 free(scr); 01384 return NULL; 01385 case STATE_INKEY: 01386 ast_log(LOG_WARNING, "Missing ENDKEY at end of file %s\n", script); 01387 free(scr); 01388 return NULL; 01389 } 01390 err = 0; 01391 01392 /* Resolve all keys and record their lengths */ 01393 for (x=0;x<scr->numkeys;x++) { 01394 if (!scr->keys[x].defined) { 01395 ast_log(LOG_WARNING, "Key '%s' referenced but never defined in file %s\n", scr->keys[x].vname, fn); 01396 err++; 01397 } 01398 } 01399 01400 /* Resolve all subs */ 01401 for (x=0;x<scr->numsubs;x++) { 01402 if (!scr->subs[x].defined) { 01403 ast_log(LOG_WARNING, "Subscript '%s' referenced but never defined in file %s\n", scr->subs[x].vname, fn); 01404 err++; 01405 } 01406 if (x == (scr->numsubs - 1)) { 01407 /* Clear out extension bit on last message */ 01408 scr->subs[x].data[2] = 0x80; 01409 } 01410 } 01411 01412 if (err) { 01413 free(scr); 01414 return NULL; 01415 } 01416 return scr; 01417 }
static int digitcollect | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 719 of file app_adsiprog.c.
References ast_log(), get_token(), and LOG_WARNING.
00720 { 00721 char *tok; 00722 tok = get_token(&args, script, lineno); 00723 if (tok) 00724 ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script); 00725 00726 buf[0] = id; 00727 buf[1] = 0xf; 00728 return 2; 00729 }
static int digitdirect | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 695 of file app_adsiprog.c.
References ast_log(), get_token(), and LOG_WARNING.
00696 { 00697 char *tok; 00698 tok = get_token(&args, script, lineno); 00699 if (tok) 00700 ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script); 00701 00702 buf[0] = id; 00703 buf[1] = 0x7; 00704 return 2; 00705 }
static char* get_token | ( | char ** | buf, | |
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 225 of file app_adsiprog.c.
References ast_log(), and LOG_WARNING.
Referenced by adsi_process(), clearcbone(), cleardisplay(), clearflag(), cleartimer(), digitcollect(), digitdirect(), goto_line(), goto_line_rel(), onevent(), process_opcode(), process_returncode(), send_delay(), send_dtmf(), set_state(), setflag(), showdisplay(), showkeys(), starttimer(), and subscript().
00226 { 00227 char *tmp = *buf; 00228 char *keyword; 00229 int quoted = 0; 00230 /* Advance past any white space */ 00231 while(*tmp && (*tmp < 33)) 00232 tmp++; 00233 if (!*tmp) 00234 return NULL; 00235 keyword = tmp; 00236 while(*tmp && ((*tmp > 32) || quoted)) { 00237 if (*tmp == '\"') { 00238 quoted = !quoted; 00239 } 00240 tmp++; 00241 } 00242 if (quoted) { 00243 ast_log(LOG_WARNING, "Mismatched quotes at line %d of %s\n", lineno, script); 00244 return NULL; 00245 } 00246 *tmp = '\0'; 00247 tmp++; 00248 while(*tmp && (*tmp < 33)) 00249 tmp++; 00250 /* Note where we left off */ 00251 *buf = tmp; 00252 return keyword; 00253 }
static struct adsi_display* getdisplaybyname | ( | struct adsi_script * | state, | |
char * | name, | |||
char * | script, | |||
int | lineno, | |||
int | create | |||
) | [static] |
Definition at line 556 of file app_adsiprog.c.
References ast_log(), adsi_script::displays, LOG_WARNING, adsi_script::numdisplays, and adsi_display::vname.
Referenced by adsi_process(), and showdisplay().
00557 { 00558 int x; 00559 for (x=0;x<state->numdisplays;x++) 00560 if (!strcasecmp(state->displays[x].vname, name)) 00561 return &state->displays[x]; 00562 /* Return now if we're not allowed to create */ 00563 if (!create) 00564 return NULL; 00565 if (state->numdisplays > 61) { 00566 ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script); 00567 return NULL; 00568 } 00569 ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname)); 00570 state->displays[state->numdisplays].id = state->numdisplays + 1; 00571 state->numdisplays++; 00572 return &state->displays[state->numdisplays-1]; 00573 }
static int geteventbyname | ( | char * | name | ) | [static] |
Definition at line 485 of file app_adsiprog.c.
References events.
Referenced by adsi_process(), and onevent().
00486 { 00487 int x; 00488 for (x=0;x<sizeof(events) / sizeof(events[0]); x++) { 00489 if (!strcasecmp(events[x].name, name)) 00490 return events[x].id; 00491 } 00492 return 0; 00493 }
static struct adsi_flag* getflagbyname | ( | struct adsi_script * | state, | |
char * | name, | |||
char * | script, | |||
int | lineno, | |||
int | create | |||
) | [static] |
Definition at line 399 of file app_adsiprog.c.
References ast_log(), adsi_script::flags, LOG_WARNING, adsi_script::numflags, and adsi_flag::vname.
Referenced by adsi_process(), clearflag(), setflag(), and showkeys().
00400 { 00401 int x; 00402 for (x=0;x<state->numflags;x++) 00403 if (!strcasecmp(state->flags[x].vname, name)) 00404 return &state->flags[x]; 00405 /* Return now if we're not allowed to create */ 00406 if (!create) 00407 return NULL; 00408 if (state->numflags > 6) { 00409 ast_log(LOG_WARNING, "No more flag space at line %d of %s\n", lineno, script); 00410 return NULL; 00411 } 00412 ast_copy_string(state->flags[state->numflags].vname, name, sizeof(state->flags[state->numflags].vname)); 00413 state->flags[state->numflags].id = state->numflags + 1; 00414 state->numflags++; 00415 return &state->flags[state->numflags-1]; 00416 }
static int getjustifybyname | ( | char * | name | ) | [static] |
Definition at line 495 of file app_adsiprog.c.
References justify.
Referenced by adsi_process().
00496 { 00497 int x; 00498 for (x=0;x<sizeof(justify) / sizeof(justify[0]); x++) { 00499 if (!strcasecmp(justify[x].name, name)) 00500 return justify[x].id; 00501 } 00502 return -1; 00503 }
static struct adsi_soft_key* getkeybyname | ( | struct adsi_script * | state, | |
char * | name, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 505 of file app_adsiprog.c.
References ast_log(), adsi_script::keys, LOG_WARNING, adsi_script::numkeys, and adsi_soft_key::vname.
Referenced by adsi_process(), and showkeys().
00506 { 00507 int x; 00508 for (x=0;x<state->numkeys;x++) 00509 if (!strcasecmp(state->keys[x].vname, name)) 00510 return &state->keys[x]; 00511 if (state->numkeys > 61) { 00512 ast_log(LOG_WARNING, "No more key space at line %d of %s\n", lineno, script); 00513 return NULL; 00514 } 00515 ast_copy_string(state->keys[state->numkeys].vname, name, sizeof(state->keys[state->numkeys].vname)); 00516 state->keys[state->numkeys].id = state->numkeys + 2; 00517 state->numkeys++; 00518 return &state->keys[state->numkeys-1]; 00519 }
static struct adsi_state* getstatebyname | ( | struct adsi_script * | state, | |
char * | name, | |||
char * | script, | |||
int | lineno, | |||
int | create | |||
) | [static] |
Definition at line 537 of file app_adsiprog.c.
References ast_log(), LOG_WARNING, adsi_script::numstates, adsi_script::states, and adsi_state::vname.
Referenced by adsi_process(), and onevent().
00538 { 00539 int x; 00540 for (x=0;x<state->numstates;x++) 00541 if (!strcasecmp(state->states[x].vname, name)) 00542 return &state->states[x]; 00543 /* Return now if we're not allowed to create */ 00544 if (!create) 00545 return NULL; 00546 if (state->numstates > 253) { 00547 ast_log(LOG_WARNING, "No more state space at line %d of %s\n", lineno, script); 00548 return NULL; 00549 } 00550 ast_copy_string(state->states[state->numstates].vname, name, sizeof(state->states[state->numstates].vname)); 00551 state->states[state->numstates].id = state->numstates + 1; 00552 state->numstates++; 00553 return &state->states[state->numstates-1]; 00554 }
static struct adsi_subscript* getsubbyname | ( | struct adsi_script * | state, | |
char * | name, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 521 of file app_adsiprog.c.
References ast_log(), LOG_WARNING, adsi_script::numsubs, adsi_script::subs, and adsi_subscript::vname.
Referenced by adsi_process(), compile_script(), onevent(), and subscript().
00522 { 00523 int x; 00524 for (x=0;x<state->numsubs;x++) 00525 if (!strcasecmp(state->subs[x].vname, name)) 00526 return &state->subs[x]; 00527 if (state->numsubs > 127) { 00528 ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, script); 00529 return NULL; 00530 } 00531 ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname)); 00532 state->subs[state->numsubs].id = state->numsubs; 00533 state->numsubs++; 00534 return &state->subs[state->numsubs-1]; 00535 }
static int goto_line | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 284 of file app_adsiprog.c.
References ARG_NUMBER, ast_log(), get_token(), LOG_WARNING, and process_token().
00285 { 00286 char *page; 00287 char *gline; 00288 int line; 00289 unsigned char cmd; 00290 page = get_token(&args, script, lineno); 00291 gline = get_token(&args, script, lineno); 00292 if (!page || !gline) { 00293 ast_log(LOG_WARNING, "Expecting page and line number for GOTOLINE at line %d of %s\n", lineno, script); 00294 return 0; 00295 } 00296 if (!strcasecmp(page, "INFO")) { 00297 cmd = 0; 00298 } else if (!strcasecmp(page, "COMM")) { 00299 cmd = 0x80; 00300 } else { 00301 ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got got '%s' at line %d of %s\n", page, lineno, script); 00302 return 0; 00303 } 00304 if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) { 00305 ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script); 00306 return 0; 00307 } 00308 cmd |= line; 00309 buf[0] = 0x8b; 00310 buf[1] = cmd; 00311 return 2; 00312 }
static int goto_line_rel | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 314 of file app_adsiprog.c.
References ARG_NUMBER, ast_log(), get_token(), LOG_WARNING, and process_token().
00315 { 00316 char *dir; 00317 char *gline; 00318 int line; 00319 unsigned char cmd; 00320 dir = get_token(&args, script, lineno); 00321 gline = get_token(&args, script, lineno); 00322 if (!dir || !gline) { 00323 ast_log(LOG_WARNING, "Expecting direction and number of lines for GOTOLINEREL at line %d of %s\n", lineno, script); 00324 return 0; 00325 } 00326 if (!strcasecmp(dir, "UP")) { 00327 cmd = 0; 00328 } else if (!strcasecmp(dir, "DOWN")) { 00329 cmd = 0x20; 00330 } else { 00331 ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script); 00332 return 0; 00333 } 00334 if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) { 00335 ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script); 00336 return 0; 00337 } 00338 cmd |= line; 00339 buf[0] = 0x8c; 00340 buf[1] = cmd; 00341 return 2; 00342 }
static int load_module | ( | void | ) | [static] |
Definition at line 1581 of file app_adsiprog.c.
References adsi_exec(), app, ast_register_application(), descrip, and synopsis.
01582 { 01583 return ast_register_application(app, adsi_exec, synopsis, descrip); 01584 }
static int onevent | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 753 of file app_adsiprog.c.
References ARG_STRING, ast_log(), event, get_token(), geteventbyname(), getstatebyname(), getsubbyname(), adsi_subscript::id, LOG_WARNING, process_token(), and subscript().
00754 { 00755 char *tok; 00756 char subscript[80]; 00757 char sname[80]; 00758 int sawin=0; 00759 int event; 00760 int snums[8]; 00761 int scnt = 0; 00762 int x; 00763 struct adsi_subscript *sub; 00764 tok = get_token(&args, script, lineno); 00765 if (!tok) { 00766 ast_log(LOG_WARNING, "Missing event for 'ONEVENT' at line %d of %s\n", lineno, script); 00767 return 0; 00768 } 00769 event = geteventbyname(tok); 00770 if (event < 1) { 00771 ast_log(LOG_WARNING, "'%s' is not a valid event name, at line %d of %s\n", args, lineno, script); 00772 return 0; 00773 } 00774 tok = get_token(&args, script, lineno); 00775 while ((!sawin && !strcasecmp(tok, "IN")) || 00776 (sawin && !strcasecmp(tok, "OR"))) { 00777 sawin = 1; 00778 if (scnt > 7) { 00779 ast_log(LOG_WARNING, "No more than 8 states may be specified for inclusion at line %d of %s\n", lineno, script); 00780 return 0; 00781 } 00782 /* Process 'in' things */ 00783 tok = get_token(&args, script, lineno); 00784 if (process_token(sname, tok, sizeof(sname), ARG_STRING)) { 00785 ast_log(LOG_WARNING, "'%s' is not a valid state name at line %d of %s\n", tok, lineno, script); 00786 return 0; 00787 } 00788 if ((snums[scnt] = getstatebyname(state, sname, script, lineno, 0) < 0)) { 00789 ast_log(LOG_WARNING, "State '%s' not declared at line %d of %s\n", sname, lineno, script); 00790 return 0; 00791 } 00792 scnt++; 00793 tok = get_token(&args, script, lineno); 00794 if (!tok) 00795 break; 00796 } 00797 if (!tok || strcasecmp(tok, "GOTO")) { 00798 if (!tok) 00799 tok = "<nothing>"; 00800 if (sawin) 00801 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script); 00802 else 00803 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script); 00804 } 00805 tok = get_token(&args, script, lineno); 00806 if (!tok) { 00807 ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script); 00808 return 0; 00809 } 00810 if (process_token(subscript, tok, sizeof(subscript) - 1, ARG_STRING)) { 00811 ast_log(LOG_WARNING, "Invalid subscript '%s' at line %d of %s\n", tok, lineno, script); 00812 return 0; 00813 } 00814 sub = getsubbyname(state, subscript, script, lineno); 00815 if (!sub) 00816 return 0; 00817 buf[0] = 8; 00818 buf[1] = event; 00819 buf[2] = sub->id | 0x80; 00820 for (x=0;x<scnt;x++) 00821 buf[3 + x] = snums[x]; 00822 return 3 + scnt; 00823 }
static int process_opcode | ( | struct adsi_subscript * | sub, | |
char * | code, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 922 of file app_adsiprog.c.
References adsi_key_cmd::add_args, ast_log(), adsi_subscript::data, adsi_subscript::datalen, get_token(), adsi_subscript::id, adsi_subscript::inscount, LOG_WARNING, MAX_MAIN_LEN, MAX_SUB_LEN, name, opcmds, and adsi_subscript::vname.
Referenced by adsi_process().
00923 { 00924 int x; 00925 char *unused; 00926 int res; 00927 int max = sub->id ? MAX_SUB_LEN : MAX_MAIN_LEN; 00928 for (x=0;x<sizeof(opcmds) / sizeof(opcmds[0]);x++) { 00929 if ((opcmds[x].id > -1) && !strcasecmp(opcmds[x].name, code)) { 00930 if (opcmds[x].add_args) { 00931 res = opcmds[x].add_args(sub->data + sub->datalen, 00932 code, opcmds[x].id, args, state, script, lineno); 00933 if ((sub->datalen + res + 1) <= max) 00934 sub->datalen += res; 00935 else { 00936 ast_log(LOG_WARNING, "No space for '%s' code in subscript '%s' at line %d of %s\n", opcmds[x].name, sub->vname, lineno, script); 00937 return -1; 00938 } 00939 } else { 00940 if ((unused = get_token(&args, script, lineno))) 00941 ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", opcmds[x].name, lineno, script, unused); 00942 if ((sub->datalen + 2) <= max) { 00943 sub->data[sub->datalen] = opcmds[x].id; 00944 sub->datalen++; 00945 } else { 00946 ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", opcmds[x].name, sub->vname, lineno, script); 00947 return -1; 00948 } 00949 } 00950 /* Separate commands with 0xff */ 00951 sub->data[sub->datalen] = 0xff; 00952 sub->datalen++; 00953 sub->inscount++; 00954 return 0; 00955 } 00956 } 00957 return -1; 00958 }
static int process_returncode | ( | struct adsi_soft_key * | key, | |
char * | code, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 893 of file app_adsiprog.c.
References adsi_key_cmd::add_args, ast_log(), get_token(), kcmds, key(), LOG_WARNING, MAX_RET_CODE, and name.
Referenced by adsi_process().
00894 { 00895 int x; 00896 char *unused; 00897 int res; 00898 for (x=0;x<sizeof(kcmds) / sizeof(kcmds[0]);x++) { 00899 if ((kcmds[x].id > -1) && !strcasecmp(kcmds[x].name, code)) { 00900 if (kcmds[x].add_args) { 00901 res = kcmds[x].add_args(key->retstr + key->retstrlen, 00902 code, kcmds[x].id, args, state, script, lineno); 00903 if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE) 00904 key->retstrlen += res; 00905 else 00906 ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script); 00907 } else { 00908 if ((unused = get_token(&args, script, lineno))) 00909 ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused); 00910 if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) { 00911 key->retstr[key->retstrlen] = kcmds[x].id; 00912 key->retstrlen++; 00913 } else 00914 ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script); 00915 } 00916 return 0; 00917 } 00918 } 00919 return -1; 00920 }
static int process_token | ( | void * | out, | |
char * | src, | |||
int | maxlen, | |||
int | argtype | |||
) | [static] |
Definition at line 178 of file app_adsiprog.c.
References ARG_NUMBER, ARG_STRING, and ast_strlen_zero().
Referenced by adsi_process(), clearflag(), goto_line(), goto_line_rel(), onevent(), send_delay(), send_dtmf(), set_state(), setflag(), showdisplay(), showkeys(), starttimer(), and subscript().
00179 { 00180 if ((strlen(src) > 1) && src[0] == '\"') { 00181 /* This is a quoted string */ 00182 if (!(argtype & ARG_STRING)) 00183 return -1; 00184 src++; 00185 /* Don't take more than what's there */ 00186 if (maxlen > strlen(src) - 1) 00187 maxlen = strlen(src) - 1; 00188 memcpy(out, src, maxlen); 00189 ((char *)out)[maxlen] = '\0'; 00190 } else if (!ast_strlen_zero(src) && (src[0] == '\\')) { 00191 if (!(argtype & ARG_NUMBER)) 00192 return -1; 00193 /* Octal value */ 00194 if (sscanf(src, "%o", (int *)out) != 1) 00195 return -1; 00196 if (argtype & ARG_STRING) { 00197 /* Convert */ 00198 *((unsigned int *)out) = htonl(*((unsigned int *)out)); 00199 } 00200 } else if ((strlen(src) > 2) && (src[0] == '0') && (tolower(src[1]) == 'x')) { 00201 if (!(argtype & ARG_NUMBER)) 00202 return -1; 00203 /* Hex value */ 00204 if (sscanf(src + 2, "%x", (unsigned int *)out) != 1) 00205 return -1; 00206 if (argtype & ARG_STRING) { 00207 /* Convert */ 00208 *((unsigned int *)out) = htonl(*((unsigned int *)out)); 00209 } 00210 } else if ((!ast_strlen_zero(src) && isdigit(src[0]))) { 00211 if (!(argtype & ARG_NUMBER)) 00212 return -1; 00213 /* Hex value */ 00214 if (sscanf(src, "%d", (int *)out) != 1) 00215 return -1; 00216 if (argtype & ARG_STRING) { 00217 /* Convert */ 00218 *((unsigned int *)out) = htonl(*((unsigned int *)out)); 00219 } 00220 } else 00221 return -1; 00222 return 0; 00223 }
static int send_delay | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 344 of file app_adsiprog.c.
References ARG_NUMBER, ast_log(), get_token(), LOG_WARNING, and process_token().
00345 { 00346 char *gtime; 00347 int ms; 00348 gtime = get_token(&args, script, lineno); 00349 if (!gtime) { 00350 ast_log(LOG_WARNING, "Expecting number of milliseconds to wait at line %d of %s\n", lineno, script); 00351 return 0; 00352 } 00353 if (process_token(&ms, gtime, sizeof(ms), ARG_NUMBER)) { 00354 ast_log(LOG_WARNING, "Invalid delay milliseconds '%s' at line %d of %s\n", gtime, lineno, script); 00355 return 0; 00356 } 00357 buf[0] = 0x90; 00358 if (id == 11) 00359 buf[1] = ms / 100; 00360 else 00361 buf[1] = ms / 10; 00362 return 2; 00363 }
static int send_dtmf | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 257 of file app_adsiprog.c.
References ARG_STRING, ast_log(), get_token(), LOG_WARNING, and process_token().
00258 { 00259 char dtmfstr[80]; 00260 char *a; 00261 int bytes=0; 00262 a = get_token(&args, script, lineno); 00263 if (!a) { 00264 ast_log(LOG_WARNING, "Expecting something to send for SENDDTMF at line %d of %s\n", lineno, script); 00265 return 0; 00266 } 00267 if (process_token(dtmfstr, a, sizeof(dtmfstr) - 1, ARG_STRING)) { 00268 ast_log(LOG_WARNING, "Invalid token for SENDDTMF at line %d of %s\n", lineno, script); 00269 return 0; 00270 } 00271 a = dtmfstr; 00272 while(*a) { 00273 if (strchr(validdtmf, *a)) { 00274 *buf = *a; 00275 buf++; 00276 bytes++; 00277 } else 00278 ast_log(LOG_WARNING, "'%c' is not a valid DTMF tone at line %d of %s\n", *a, lineno, script); 00279 a++; 00280 } 00281 return bytes; 00282 }
static int set_state | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 365 of file app_adsiprog.c.
References ARG_NUMBER, ast_log(), get_token(), LOG_WARNING, and process_token().
00366 { 00367 char *gstate; 00368 int state; 00369 gstate = get_token(&args, script, lineno); 00370 if (!gstate) { 00371 ast_log(LOG_WARNING, "Expecting state number at line %d of %s\n", lineno, script); 00372 return 0; 00373 } 00374 if (process_token(&state, gstate, sizeof(state), ARG_NUMBER)) { 00375 ast_log(LOG_WARNING, "Invalid state number '%s' at line %d of %s\n", gstate, lineno, script); 00376 return 0; 00377 } 00378 buf[0] = id; 00379 buf[1] = state; 00380 return 2; 00381 }
static int setflag | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 418 of file app_adsiprog.c.
References ARG_STRING, ast_log(), get_token(), getflagbyname(), adsi_flag::id, LOG_WARNING, and process_token().
00419 { 00420 char *tok; 00421 char sname[80]; 00422 struct adsi_flag *flag; 00423 tok = get_token(&args, script, lineno); 00424 if (!tok) { 00425 ast_log(LOG_WARNING, "Setting flag requires a flag number at line %d of %s\n", lineno, script); 00426 return 0; 00427 } 00428 if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) { 00429 ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script); 00430 return 0; 00431 } 00432 flag = getflagbyname(state, sname, script, lineno, 0); 00433 if (!flag) { 00434 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script); 00435 return 0; 00436 } 00437 buf[0] = id; 00438 buf[1] = ((flag->id & 0x7) << 4) | 1; 00439 return 2; 00440 }
static int showdisplay | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 628 of file app_adsiprog.c.
References ARG_NUMBER, ARG_STRING, ast_log(), get_token(), getdisplaybyname(), adsi_display::id, LOG_WARNING, and process_token().
00629 { 00630 char *tok; 00631 char dispname[80]; 00632 int line=0; 00633 int flag=0; 00634 int cmd = 3; 00635 struct adsi_display *disp; 00636 00637 /* Get display */ 00638 tok = get_token(&args, script, lineno); 00639 if (!tok || process_token(dispname, tok, sizeof(dispname) - 1, ARG_STRING)) { 00640 ast_log(LOG_WARNING, "Invalid display name: %s at line %d of %s\n", tok ? tok : "<nothing>", lineno, script); 00641 return 0; 00642 } 00643 disp = getdisplaybyname(state, dispname, script, lineno, 0); 00644 if (!disp) { 00645 ast_log(LOG_WARNING, "Display '%s' is undefined at line %d of %s\n", dispname, lineno, script); 00646 return 0; 00647 } 00648 00649 tok = get_token(&args, script, lineno); 00650 if (!tok || strcasecmp(tok, "AT")) { 00651 ast_log(LOG_WARNING, "Missing token 'AT' at line %d of %s\n", lineno, script); 00652 return 0; 00653 } 00654 /* Get line number */ 00655 tok = get_token(&args, script, lineno); 00656 if (!tok || process_token(&line, tok, sizeof(line), ARG_NUMBER)) { 00657 ast_log(LOG_WARNING, "Invalid line: '%s' at line %d of %s\n", tok ? tok : "<nothing>", lineno, script); 00658 return 0; 00659 } 00660 tok = get_token(&args, script, lineno); 00661 if (tok && !strcasecmp(tok, "NOUPDATE")) { 00662 cmd = 1; 00663 tok = get_token(&args, script, lineno); 00664 } 00665 if (tok && !strcasecmp(tok, "UNLESS")) { 00666 /* Check for trailing UNLESS flag */ 00667 tok = get_token(&args, script, lineno); 00668 if (!tok) { 00669 ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script); 00670 } else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER)) { 00671 ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script); 00672 } 00673 if ((tok = get_token(&args, script, lineno))) 00674 ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script); 00675 } 00676 00677 buf[0] = id; 00678 buf[1] = (cmd << 6) | (disp->id & 0x3f); 00679 buf[2] = ((line & 0x1f) << 3) | (flag & 0x7); 00680 return 3; 00681 }
static int showkeys | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 575 of file app_adsiprog.c.
References ARG_STRING, ast_log(), get_token(), getflagbyname(), getkeybyname(), adsi_flag::id, key(), LOG_WARNING, and process_token().
00576 { 00577 char *tok; 00578 char newkey[80]; 00579 int bytes; 00580 unsigned char keyid[6]; 00581 int x; 00582 int flagid=0; 00583 struct adsi_soft_key *key; 00584 struct adsi_flag *flag; 00585 00586 for (x=0;x<7;x++) { 00587 /* Up to 6 key arguments */ 00588 tok = get_token(&args, script, lineno); 00589 if (!tok) 00590 break; 00591 if (!strcasecmp(tok, "UNLESS")) { 00592 /* Check for trailing UNLESS flag */ 00593 tok = get_token(&args, script, lineno); 00594 if (!tok) { 00595 ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script); 00596 } else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) { 00597 ast_log(LOG_WARNING, "Invalid flag name '%s' at line %d of %s\n", tok, lineno, script); 00598 } else if (!(flag = getflagbyname(state, newkey, script, lineno, 0))) { 00599 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", newkey, lineno, script); 00600 } else 00601 flagid = flag->id; 00602 if ((tok = get_token(&args, script, lineno))) 00603 ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script); 00604 break; 00605 } 00606 if (x > 5) { 00607 ast_log(LOG_WARNING, "Only 6 keys can be defined, ignoring '%s' at line %d of %s\n", tok, lineno, script); 00608 break; 00609 } 00610 if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) { 00611 ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok); 00612 continue; 00613 } 00614 00615 key = getkeybyname(state, newkey, script, lineno); 00616 if (!key) 00617 break; 00618 keyid[x] = key->id; 00619 } 00620 buf[0] = id; 00621 buf[1] = (flagid & 0x7) << 3 | (x & 0x7); 00622 for (bytes=0;bytes<x;bytes++) { 00623 buf[bytes + 2] = keyid[bytes]; 00624 } 00625 return 2 + x; 00626 }
static int starttimer | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | istate, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 466 of file app_adsiprog.c.
References ARG_NUMBER, ast_log(), get_token(), LOG_WARNING, and process_token().
00467 { 00468 char *tok; 00469 int secs; 00470 tok = get_token(&args, script, lineno); 00471 if (!tok) { 00472 ast_log(LOG_WARNING, "Missing number of seconds at line %d of %s\n", lineno, script); 00473 return 0; 00474 } 00475 if (process_token(&secs, tok, sizeof(secs), ARG_NUMBER)) { 00476 ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script); 00477 return 0; 00478 } 00479 buf[0] = id; 00480 buf[1] = 0x1; 00481 buf[2] = secs; 00482 return 3; 00483 }
static int subscript | ( | char * | buf, | |
char * | name, | |||
int | id, | |||
char * | args, | |||
struct adsi_script * | state, | |||
char * | script, | |||
int | lineno | |||
) | [static] |
Definition at line 731 of file app_adsiprog.c.
References ARG_STRING, ast_log(), get_token(), getsubbyname(), adsi_subscript::id, LOG_WARNING, and process_token().
Referenced by onevent().
00732 { 00733 char *tok; 00734 char subscript[80]; 00735 struct adsi_subscript *sub; 00736 tok = get_token(&args, script, lineno); 00737 if (!tok) { 00738 ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script); 00739 return 0; 00740 } 00741 if (process_token(subscript, tok, sizeof(subscript) - 1, ARG_STRING)) { 00742 ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script); 00743 return 0; 00744 } 00745 sub = getsubbyname(state, subscript, script, lineno); 00746 if (!sub) 00747 return 0; 00748 buf[0] = 0x9d; 00749 buf[1] = sub->id; 00750 return 2; 00751 }
static int unload_module | ( | void | ) | [static] |
Definition at line 1569 of file app_adsiprog.c.
References app, ast_module_user_hangup_all, and ast_unregister_application().
01570 { 01571 int res; 01572 01573 ast_module_user_hangup_all(); 01574 01575 res = ast_unregister_application(app); 01576 01577 01578 return res; 01579 }
char* app = "ADSIProg" [static] |
Definition at line 52 of file app_adsiprog.c.
char* descrip [static] |
Initial value:
" ADSIProg(script): This application programs an ADSI Phone with the given\n" "script. If nothing is specified, the default script (asterisk.adsi) is used.\n"
Definition at line 58 of file app_adsiprog.c.
struct adsi_event events[] [static] |
Definition at line 67 of file app_adsiprog.c.
struct adsi_event justify[] [static] |
Definition at line 94 of file app_adsiprog.c.
Referenced by adsi_announce_park(), cpeid_setstatus(), and getjustifybyname().
struct adsi_key_cmd kcmds[] [static] |
struct adsi_key_cmd opcmds[] [static] |
Definition at line 54 of file app_adsiprog.c.
char* validdtmf = "123456789*0#ABCD" [static] |
Definition at line 255 of file app_adsiprog.c.