Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Functions | Variables
app_adsiprog.c File Reference

Program Asterisk ADSI Scripts into phone. More...

#include "asterisk.h"
#include <netinet/in.h>
#include <ctype.h>
#include "asterisk/paths.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/adsi.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
 

Macros

#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 void __reg_module (void)
 
static void __unreg_module (void)
 
static int adsi_exec (struct ast_channel *chan, const char *data)
 
static int adsi_process (struct adsi_script *state, char *buf, const char *script, int lineno)
 
static int adsi_prog (struct ast_channel *chan, const char *script)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int clearcbone (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static int cleardisplay (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static int clearflag (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int cleartimer (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static struct adsi_scriptcompile_script (const char *script)
 
static int digitcollect (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static int digitdirect (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static char * get_token (char **buf, const char *script, int lineno)
 
static struct adsi_displaygetdisplaybyname (struct adsi_script *state, char *name, const char *script, int lineno, int create)
 
static int geteventbyname (char *name)
 
static struct adsi_flaggetflagbyname (struct adsi_script *state, char *name, const char *script, int lineno, int create)
 
static int getjustifybyname (char *name)
 
static struct adsi_soft_keygetkeybyname (struct adsi_script *state, char *name, const char *script, int lineno)
 
static struct adsi_stategetstatebyname (struct adsi_script *state, char *name, const char *script, int lineno, int create)
 
static struct adsi_subscriptgetsubbyname (struct adsi_script *state, char *name, const char *script, int lineno)
 
static int goto_line (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int goto_line_rel (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int load_module (void)
 Load the module. More...
 
static int onevent (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int process_opcode (struct adsi_subscript *sub, char *code, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int process_returncode (struct adsi_soft_key *key, char *code, char *args, struct adsi_script *state, const 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, const char *script, int lineno)
 
static int send_dtmf (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int set_state (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static int setflag (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int showdisplay (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int showkeys (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int starttimer (char *buf, char *name, int id, char *args, struct adsi_script *istate, const char *script, int lineno)
 
static int subscript (char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Asterisk ADSI Programming Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .requires = "res_adsi", }
 
static const char app [] = "ADSIProg"
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const struct adsi_event events []
 
static const struct adsi_event justify []
 
static const struct adsi_key_cmd kcmds []
 
static const struct adsi_key_cmd opcmds []
 
static char * validdtmf = "123456789*0#ABCD"
 

Detailed Description

Program Asterisk ADSI Scripts into phone.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file app_adsiprog.c.

Macro Definition Documentation

◆ ARG_NUMBER

#define ARG_NUMBER   (1 << 1)

Definition at line 129 of file app_adsiprog.c.

◆ ARG_STRING

#define ARG_STRING   (1 << 0)

Definition at line 128 of file app_adsiprog.c.

◆ MAX_MAIN_LEN

#define MAX_MAIN_LEN   1600

Definition at line 126 of file app_adsiprog.c.

◆ MAX_RET_CODE

#define MAX_RET_CODE   20

Definition at line 124 of file app_adsiprog.c.

◆ MAX_SUB_LEN

#define MAX_SUB_LEN   255

Definition at line 125 of file app_adsiprog.c.

◆ STATE_INIF

#define STATE_INIF   3

Definition at line 122 of file app_adsiprog.c.

◆ STATE_INKEY

#define STATE_INKEY   1

Definition at line 120 of file app_adsiprog.c.

◆ STATE_INSUB

#define STATE_INSUB   2

Definition at line 121 of file app_adsiprog.c.

◆ STATE_NORMAL

#define STATE_NORMAL   0

Definition at line 119 of file app_adsiprog.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1617 of file app_adsiprog.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1617 of file app_adsiprog.c.

◆ adsi_exec()

static int adsi_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 1573 of file app_adsiprog.c.

1574{
1575 int res = 0;
1576
1577 if (ast_strlen_zero(data))
1578 data = "asterisk.adsi";
1579
1580 if (!ast_adsi_available(chan)) {
1581 ast_verb(3, "ADSI Unavailable on CPE. Not bothering to try.\n");
1582 } else {
1583 ast_verb(3, "ADSI Available on CPE. Attempting Upload.\n");
1584 res = adsi_prog(chan, data);
1585 }
1586
1587 return res;
1588}
int ast_adsi_available(struct ast_channel *chan)
Returns non-zero if Channel does or might support ADSI.
Definition: adsi.c:263
static int adsi_prog(struct ast_channel *chan, const char *script)
#define ast_verb(level,...)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References adsi_prog(), ast_adsi_available(), ast_strlen_zero(), and ast_verb.

Referenced by load_module().

◆ adsi_process()

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

Definition at line 1021 of file app_adsiprog.c.

1022{
1023 char *keyword = get_token(&buf, script, lineno);
1024 char *args, vname[256], tmp[80], tmp2[80];
1025 int lrci, wi, event;
1026 struct adsi_display *disp;
1027 struct adsi_subscript *newsub;
1028
1029 if (!keyword)
1030 return 0;
1031
1032 switch(state->state) {
1033 case STATE_NORMAL:
1034 if (!strcasecmp(keyword, "DESCRIPTION")) {
1035 if ((args = get_token(&buf, script, lineno))) {
1036 if (process_token(state->desc, args, sizeof(state->desc) - 1, ARG_STRING))
1037 ast_log(LOG_WARNING, "'%s' is not a valid token for DESCRIPTION at line %d of %s\n", args, lineno, script);
1038 } else
1039 ast_log(LOG_WARNING, "Missing argument for DESCRIPTION at line %d of %s\n", lineno, script);
1040 } else if (!strcasecmp(keyword, "VERSION")) {
1041 if ((args = get_token(&buf, script, lineno))) {
1042 if (process_token(&state->ver, args, sizeof(state->ver) - 1, ARG_NUMBER))
1043 ast_log(LOG_WARNING, "'%s' is not a valid token for VERSION at line %d of %s\n", args, lineno, script);
1044 } else
1045 ast_log(LOG_WARNING, "Missing argument for VERSION at line %d of %s\n", lineno, script);
1046 } else if (!strcasecmp(keyword, "SECURITY")) {
1047 if ((args = get_token(&buf, script, lineno))) {
1048 if (process_token(state->sec, args, sizeof(state->sec) - 1, ARG_STRING | ARG_NUMBER))
1049 ast_log(LOG_WARNING, "'%s' is not a valid token for SECURITY at line %d of %s\n", args, lineno, script);
1050 } else
1051 ast_log(LOG_WARNING, "Missing argument for SECURITY at line %d of %s\n", lineno, script);
1052 } else if (!strcasecmp(keyword, "FDN")) {
1053 if ((args = get_token(&buf, script, lineno))) {
1054 if (process_token(state->fdn, args, sizeof(state->fdn) - 1, ARG_STRING | ARG_NUMBER))
1055 ast_log(LOG_WARNING, "'%s' is not a valid token for FDN at line %d of %s\n", args, lineno, script);
1056 } else
1057 ast_log(LOG_WARNING, "Missing argument for FDN at line %d of %s\n", lineno, script);
1058 } else if (!strcasecmp(keyword, "KEY")) {
1059 if (!(args = get_token(&buf, script, lineno))) {
1060 ast_log(LOG_WARNING, "KEY definition missing name at line %d of %s\n", lineno, script);
1061 break;
1062 }
1063 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
1064 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
1065 break;
1066 }
1067 if (!(state->key = getkeybyname(state, vname, script, lineno))) {
1068 ast_log(LOG_WARNING, "Out of key space at line %d of %s\n", lineno, script);
1069 break;
1070 }
1071 if (state->key->defined) {
1072 ast_log(LOG_WARNING, "Cannot redefine key '%s' at line %d of %s\n", vname, lineno, script);
1073 break;
1074 }
1075 if (!(args = get_token(&buf, script, lineno)) || strcasecmp(args, "IS")) {
1076 ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
1077 break;
1078 }
1079 if (!(args = get_token(&buf, script, lineno))) {
1080 ast_log(LOG_WARNING, "KEY definition missing short name at line %d of %s\n", lineno, script);
1081 break;
1082 }
1083 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
1084 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY short name at line %d of %s\n", args, lineno, script);
1085 break;
1086 }
1087 if ((args = get_token(&buf, script, lineno))) {
1088 if (strcasecmp(args, "OR")) {
1089 ast_log(LOG_WARNING, "Expecting 'OR' but got '%s' instead at line %d of %s\n", args, lineno, script);
1090 break;
1091 }
1092 if (!(args = get_token(&buf, script, lineno))) {
1093 ast_log(LOG_WARNING, "KEY definition missing optional long name at line %d of %s\n", lineno, script);
1094 break;
1095 }
1096 if (process_token(tmp2, args, sizeof(tmp2) - 1, ARG_STRING)) {
1097 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY long name at line %d of %s\n", args, lineno, script);
1098 break;
1099 }
1100 } else {
1101 ast_copy_string(tmp2, tmp, sizeof(tmp2));
1102 }
1103 if (strlen(tmp2) > 18) {
1104 ast_log(LOG_WARNING, "Truncating full name to 18 characters at line %d of %s\n", lineno, script);
1105 tmp2[18] = '\0';
1106 }
1107 if (strlen(tmp) > 7) {
1108 ast_log(LOG_WARNING, "Truncating short name to 7 bytes at line %d of %s\n", lineno, script);
1109 tmp[7] = '\0';
1110 }
1111 /* Setup initial stuff */
1112 state->key->retstr[0] = 0x80;
1113 /* 1 has the length */
1114 state->key->retstr[2] = state->key->id;
1115 /* Put the Full name in */
1116 memcpy(state->key->retstr + 3, tmp2, strlen(tmp2));
1117 /* Update length */
1118 state->key->retstrlen = strlen(tmp2) + 3;
1119 /* Put trailing 0xff */
1120 state->key->retstr[state->key->retstrlen++] = 0xff;
1121 /* Put the short name */
1122 memcpy(state->key->retstr + state->key->retstrlen, tmp, strlen(tmp));
1123 /* Update length */
1124 state->key->retstrlen += strlen(tmp);
1125 /* Put trailing 0xff */
1126 state->key->retstr[state->key->retstrlen++] = 0xff;
1127 /* Record initial length */
1128 state->key->initlen = state->key->retstrlen;
1129 state->state = STATE_INKEY;
1130 } else if (!strcasecmp(keyword, "SUB")) {
1131 if (!(args = get_token(&buf, script, lineno))) {
1132 ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
1133 break;
1134 }
1135 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
1136 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
1137 break;
1138 }
1139 if (!(state->sub = getsubbyname(state, vname, script, lineno))) {
1140 ast_log(LOG_WARNING, "Out of subroutine space at line %d of %s\n", lineno, script);
1141 break;
1142 }
1143 if (state->sub->defined) {
1144 ast_log(LOG_WARNING, "Cannot redefine subroutine '%s' at line %d of %s\n", vname, lineno, script);
1145 break;
1146 }
1147 /* Setup sub */
1148 state->sub->data[0] = 0x82;
1149 /* 1 is the length */
1150 state->sub->data[2] = 0x0; /* Clear extensibility bit */
1151 state->sub->datalen = 3;
1152 if (state->sub->id) {
1153 /* If this isn't the main subroutine, make a subroutine label for it */
1154 state->sub->data[3] = 9;
1155 state->sub->data[4] = state->sub->id;
1156 /* 5 is length */
1157 state->sub->data[6] = 0xff;
1158 state->sub->datalen = 7;
1159 }
1160 if (!(args = get_token(&buf, script, lineno)) || strcasecmp(args, "IS")) {
1161 ast_log(LOG_WARNING, "Expecting 'IS', but got '%s' at line %d of %s\n", args ? args : "<nothing>", lineno, script);
1162 break;
1163 }
1164 state->state = STATE_INSUB;
1165 } else if (!strcasecmp(keyword, "STATE")) {
1166 if (!(args = get_token(&buf, script, lineno))) {
1167 ast_log(LOG_WARNING, "STATE definition missing name at line %d of %s\n", lineno, script);
1168 break;
1169 }
1170 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
1171 ast_log(LOG_WARNING, "'%s' is not a valid token for a STATE name at line %d of %s\n", args, lineno, script);
1172 break;
1173 }
1174 if (getstatebyname(state, vname, script, lineno, 0)) {
1175 ast_log(LOG_WARNING, "State '%s' is already defined at line %d of %s\n", vname, lineno, script);
1176 break;
1177 }
1178 getstatebyname(state, vname, script, lineno, 1);
1179 } else if (!strcasecmp(keyword, "FLAG")) {
1180 if (!(args = get_token(&buf, script, lineno))) {
1181 ast_log(LOG_WARNING, "FLAG definition missing name at line %d of %s\n", lineno, script);
1182 break;
1183 }
1184 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
1185 ast_log(LOG_WARNING, "'%s' is not a valid token for a FLAG name at line %d of %s\n", args, lineno, script);
1186 break;
1187 }
1188 if (getflagbyname(state, vname, script, lineno, 0)) {
1189 ast_log(LOG_WARNING, "Flag '%s' is already defined\n", vname);
1190 break;
1191 }
1192 getflagbyname(state, vname, script, lineno, 1);
1193 } else if (!strcasecmp(keyword, "DISPLAY")) {
1194 lrci = 0;
1195 wi = 0;
1196 if (!(args = get_token(&buf, script, lineno))) {
1197 ast_log(LOG_WARNING, "SUB definition missing name at line %d of %s\n", lineno, script);
1198 break;
1199 }
1200 if (process_token(vname, args, sizeof(vname) - 1, ARG_STRING)) {
1201 ast_log(LOG_WARNING, "'%s' is not a valid token for a KEY name at line %d of %s\n", args, lineno, script);
1202 break;
1203 }
1204 if (getdisplaybyname(state, vname, script, lineno, 0)) {
1205 ast_log(LOG_WARNING, "State '%s' is already defined\n", vname);
1206 break;
1207 }
1208 if (!(disp = getdisplaybyname(state, vname, script, lineno, 1)))
1209 break;
1210 if (!(args = get_token(&buf, script, lineno)) || strcasecmp(args, "IS")) {
1211 ast_log(LOG_WARNING, "Missing 'IS' at line %d of %s\n", lineno, script);
1212 break;
1213 }
1214 if (!(args = get_token(&buf, script, lineno))) {
1215 ast_log(LOG_WARNING, "Missing Column 1 text at line %d of %s\n", lineno, script);
1216 break;
1217 }
1218 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
1219 ast_log(LOG_WARNING, "Token '%s' is not valid column 1 text at line %d of %s\n", args, lineno, script);
1220 break;
1221 }
1222 if (strlen(tmp) > 20) {
1223 ast_log(LOG_WARNING, "Truncating column one to 20 characters at line %d of %s\n", lineno, script);
1224 tmp[20] = '\0';
1225 }
1226 memcpy(disp->data + 5, tmp, strlen(tmp));
1227 disp->datalen = strlen(tmp) + 5;
1228 disp->data[disp->datalen++] = 0xff;
1229
1230 args = get_token(&buf, script, lineno);
1231 if (args && !process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
1232 /* Got a column two */
1233 if (strlen(tmp) > 20) {
1234 ast_log(LOG_WARNING, "Truncating column two to 20 characters at line %d of %s\n", lineno, script);
1235 tmp[20] = '\0';
1236 }
1237 memcpy(disp->data + disp->datalen, tmp, strlen(tmp));
1238 disp->datalen += strlen(tmp);
1239 args = get_token(&buf, script, lineno);
1240 }
1241 while (args) {
1242 if (!strcasecmp(args, "JUSTIFY")) {
1243 args = get_token(&buf, script, lineno);
1244 if (!args) {
1245 ast_log(LOG_WARNING, "Qualifier 'JUSTIFY' requires an argument at line %d of %s\n", lineno, script);
1246 break;
1247 }
1248 lrci = getjustifybyname(args);
1249 if (lrci < 0) {
1250 ast_log(LOG_WARNING, "'%s' is not a valid justification at line %d of %s\n", args, lineno, script);
1251 break;
1252 }
1253 } else if (!strcasecmp(args, "WRAP")) {
1254 wi = 0x80;
1255 } else {
1256 ast_log(LOG_WARNING, "'%s' is not a known qualifier at line %d of %s\n", args, lineno, script);
1257 break;
1258 }
1259 args = get_token(&buf, script, lineno);
1260 }
1261 if (args) {
1262 /* Something bad happened */
1263 break;
1264 }
1265 disp->data[0] = 0x81;
1266 disp->data[1] = disp->datalen - 2;
1267 disp->data[2] = ((lrci & 0x3) << 6) | disp->id;
1268 disp->data[3] = wi;
1269 disp->data[4] = 0xff;
1270 } else {
1271 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in PROGRAM\n", keyword);
1272 }
1273 break;
1274 case STATE_INKEY:
1275 if (process_returncode(state->key, keyword, buf, state, script, lineno)) {
1276 if (!strcasecmp(keyword, "ENDKEY")) {
1277 /* Return to normal operation and increment current key */
1278 state->state = STATE_NORMAL;
1279 state->key->defined = 1;
1280 state->key->retstr[1] = state->key->retstrlen - 2;
1281 state->key = NULL;
1282 } else {
1283 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SOFTKEY definition at line %d of %s\n", keyword, lineno, script);
1284 }
1285 }
1286 break;
1287 case STATE_INIF:
1288 if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
1289 if (!strcasecmp(keyword, "ENDIF")) {
1290 /* Return to normal SUB operation and increment current key */
1291 state->state = STATE_INSUB;
1292 state->sub->defined = 1;
1293 /* Store the proper number of instructions */
1294 state->sub->ifdata[2] = state->sub->ifinscount;
1295 } else if (!strcasecmp(keyword, "GOTO")) {
1296 if (!(args = get_token(&buf, script, lineno))) {
1297 ast_log(LOG_WARNING, "GOTO clause missing Subscript name at line %d of %s\n", lineno, script);
1298 break;
1299 }
1300 if (process_token(tmp, args, sizeof(tmp) - 1, ARG_STRING)) {
1301 ast_log(LOG_WARNING, "'%s' is not a valid subscript name token at line %d of %s\n", args, lineno, script);
1302 break;
1303 }
1304 if (!(newsub = getsubbyname(state, tmp, script, lineno)))
1305 break;
1306 /* Somehow you use GOTO to go to another place */
1307 state->sub->data[state->sub->datalen++] = 0x8;
1308 state->sub->data[state->sub->datalen++] = state->sub->ifdata[1];
1309 state->sub->data[state->sub->datalen++] = newsub->id;
1310 /* Terminate */
1311 state->sub->data[state->sub->datalen++] = 0xff;
1312 /* Increment counters */
1313 state->sub->inscount++;
1314 state->sub->ifinscount++;
1315 } else {
1316 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in IF clause at line %d of %s\n", keyword, lineno, script);
1317 }
1318 } else
1319 state->sub->ifinscount++;
1320 break;
1321 case STATE_INSUB:
1322 if (process_opcode(state->sub, keyword, buf, state, script, lineno)) {
1323 if (!strcasecmp(keyword, "ENDSUB")) {
1324 /* Return to normal operation and increment current key */
1325 state->state = STATE_NORMAL;
1326 state->sub->defined = 1;
1327 /* Store the proper length */
1328 state->sub->data[1] = state->sub->datalen - 2;
1329 if (state->sub->id) {
1330 /* if this isn't main, store number of instructions, too */
1331 state->sub->data[5] = state->sub->inscount;
1332 }
1333 state->sub = NULL;
1334 } else if (!strcasecmp(keyword, "IFEVENT")) {
1335 if (!(args = get_token(&buf, script, lineno))) {
1336 ast_log(LOG_WARNING, "IFEVENT clause missing Event name at line %d of %s\n", lineno, script);
1337 break;
1338 }
1339 if ((event = geteventbyname(args)) < 1) {
1340 ast_log(LOG_WARNING, "'%s' is not a valid event\n", args);
1341 break;
1342 }
1343 if (!(args = get_token(&buf, script, lineno)) || strcasecmp(args, "THEN")) {
1344 ast_log(LOG_WARNING, "IFEVENT clause missing 'THEN' at line %d of %s\n", lineno, script);
1345 break;
1346 }
1347 state->sub->ifinscount = 0;
1348 state->sub->ifdata = state->sub->data + state->sub->datalen;
1349 /* Reserve header and insert op codes */
1350 state->sub->ifdata[0] = 0x1;
1351 state->sub->ifdata[1] = event;
1352 /* 2 is for the number of instructions */
1353 state->sub->ifdata[3] = 0xff;
1354 state->sub->datalen += 4;
1355 /* Update Subscript instruction count */
1356 state->sub->inscount++;
1357 state->state = STATE_INIF;
1358 } else {
1359 ast_log(LOG_WARNING, "Invalid or Unknown keyword '%s' in SUB definition at line %d of %s\n", keyword, lineno, script);
1360 }
1361 }
1362 break;
1363 default:
1364 ast_log(LOG_WARNING, "Can't process keyword '%s' in weird state %d\n", keyword, state->state);
1365 }
1366 return 0;
1367}
static int process_returncode(struct adsi_soft_key *key, char *code, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:955
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:435
#define ARG_NUMBER
Definition: app_adsiprog.c:129
static struct adsi_soft_key * getkeybyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:560
#define ARG_STRING
Definition: app_adsiprog.c:128
static struct adsi_subscript * getsubbyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:581
static int geteventbyname(char *name)
Definition: app_adsiprog.c:536
static int process_opcode(struct adsi_subscript *sub, char *code, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:984
#define STATE_INIF
Definition: app_adsiprog.c:122
static struct adsi_display * getdisplaybyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:627
static int getjustifybyname(char *name)
Definition: app_adsiprog.c:548
#define STATE_INKEY
Definition: app_adsiprog.c:120
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
static struct adsi_state * getstatebyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:602
#define STATE_NORMAL
Definition: app_adsiprog.c:119
#define STATE_INSUB
Definition: app_adsiprog.c:121
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
#define NULL
Definition: resample.c:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char data[70]
Definition: app_adsiprog.c:164
char vname[40]
Definition: app_adsiprog.c:141
Definition: astman.c:222
const char * args

References ARG_NUMBER, ARG_STRING, args, ast_copy_string(), ast_log, buf, adsi_display::data, adsi_display::datalen, get_token(), getdisplaybyname(), geteventbyname(), getflagbyname(), getjustifybyname(), getkeybyname(), getstatebyname(), getsubbyname(), adsi_subscript::id, adsi_display::id, LOG_WARNING, NULL, process_opcode(), process_returncode(), process_token(), STATE_INIF, STATE_INKEY, STATE_INSUB, STATE_NORMAL, tmp(), and adsi_subscript::vname.

Referenced by compile_script().

◆ adsi_prog()

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

Definition at line 1462 of file app_adsiprog.c.

1463{
1464 struct adsi_script *scr;
1465 int x, bytes;
1466 unsigned char buf[1024];
1467
1468 if (!(scr = compile_script(script)))
1469 return -1;
1470
1471 /* Start an empty ADSI Session */
1472 if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
1473 return -1;
1474
1475 /* Now begin the download attempt */
1476 if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
1477 /* User rejected us for some reason */
1478 ast_verb(3, "User rejected download attempt\n");
1479 ast_log(LOG_NOTICE, "User rejected download on channel %s\n", ast_channel_name(chan));
1480 ast_free(scr);
1481 return -1;
1482 }
1483
1484 bytes = 0;
1485 /* Start with key definitions */
1486 for (x = 0; x < scr->numkeys; x++) {
1487 if (bytes + scr->keys[x].retstrlen > 253) {
1488 /* Send what we've collected so far */
1489 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1490 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1491 return -1;
1492 }
1493 bytes =0;
1494 }
1495 memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
1496 bytes += scr->keys[x].retstrlen;
1497#ifdef DUMP_MESSAGES
1498 dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
1499#endif
1500 }
1501 if (bytes) {
1502 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1503 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1504 return -1;
1505 }
1506 }
1507
1508 bytes = 0;
1509 /* Continue with the display messages */
1510 for (x = 0; x < scr->numdisplays; x++) {
1511 if (bytes + scr->displays[x].datalen > 253) {
1512 /* Send what we've collected so far */
1513 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1514 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1515 return -1;
1516 }
1517 bytes =0;
1518 }
1519 memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
1520 bytes += scr->displays[x].datalen;
1521#ifdef DUMP_MESSAGES
1522 dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
1523#endif
1524 }
1525 if (bytes) {
1526 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1527 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1528 return -1;
1529 }
1530 }
1531
1532 bytes = 0;
1533 /* Send subroutines */
1534 for (x = 0; x < scr->numsubs; x++) {
1535 if (bytes + scr->subs[x].datalen > 253) {
1536 /* Send what we've collected so far */
1537 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1538 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1539 return -1;
1540 }
1541 bytes =0;
1542 }
1543 memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
1544 bytes += scr->subs[x].datalen;
1545#ifdef DUMP_MESSAGES
1546 dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
1547#endif
1548 }
1549 if (bytes) {
1550 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1551 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1552 return -1;
1553 }
1554 }
1555
1556 bytes = 0;
1557 bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
1558 bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
1559 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
1560 return -1;
1561 if (ast_adsi_end_download(chan)) {
1562 /* Download failed for some reason */
1563 ast_verb(3, "Download attempt failed\n");
1564 ast_log(LOG_NOTICE, "Download failed on %s\n", ast_channel_name(chan));
1565 ast_free(scr);
1566 return -1;
1567 }
1568 ast_free(scr);
1570 return 0;
1571}
int ast_adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Loads a line of info into the display.
Definition: adsi.c:274
#define ADSI_INFO_PAGE
Definition: adsi.h:106
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
int ast_adsi_unload_session(struct ast_channel *chan)
Definition: adsi.c:87
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
int ast_adsi_begin_download(struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
Definition: adsi.c:32
#define ADSI_JUST_LEFT
Definition: adsi.h:112
int ast_adsi_set_line(unsigned char *buf, int page, int line)
Sets the current line and page.
Definition: adsi.c:285
int ast_adsi_load_session(struct ast_channel *chan, unsigned char *app, int ver, int data)
Check if scripts for a given app are already loaded. Version may be -1, if any version is okay,...
Definition: adsi.c:76
int ast_adsi_end_download(struct ast_channel *chan)
Definition: adsi.c:43
int ast_adsi_transmit_message(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
Definition: adsi.c:98
static struct adsi_script * compile_script(const char *script)
#define ast_free(a)
Definition: astmm.h:180
const char * ast_channel_name(const struct ast_channel *chan)
#define LOG_NOTICE
char vname[40]
Definition: app_adsiprog.c:162
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:184
unsigned char fdn[5]
Definition: app_adsiprog.c:191
char desc[19]
Definition: app_adsiprog.c:190
unsigned char sec[5]
Definition: app_adsiprog.c:189
struct adsi_display displays[63]
Definition: app_adsiprog.c:178
struct adsi_soft_key keys[62]
Definition: app_adsiprog.c:182
char retstr[80]
Definition: app_adsiprog.c:137
char vname[40]
Definition: app_adsiprog.c:132
char data[2048]
Definition: app_adsiprog.c:148

References ADSI_INFO_PAGE, ADSI_JUST_LEFT, ADSI_MSG_DISPLAY, ADSI_MSG_DOWNLOAD, ast_adsi_begin_download(), ast_adsi_display(), ast_adsi_end_download(), ast_adsi_load_session(), ast_adsi_set_line(), ast_adsi_transmit_message(), ast_adsi_unload_session(), ast_channel_name(), ast_free, ast_log, ast_verb, buf, compile_script(), adsi_subscript::data, adsi_display::data, adsi_subscript::datalen, adsi_display::datalen, adsi_script::desc, adsi_script::displays, adsi_script::fdn, adsi_script::keys, LOG_NOTICE, LOG_WARNING, NULL, adsi_script::numdisplays, adsi_script::numkeys, adsi_script::numsubs, adsi_soft_key::retstr, adsi_soft_key::retstrlen, adsi_script::sec, adsi_script::subs, adsi_script::ver, adsi_soft_key::vname, adsi_subscript::vname, and adsi_display::vname.

Referenced by adsi_exec().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1617 of file app_adsiprog.c.

◆ clearcbone()

static int clearcbone ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 774 of file app_adsiprog.c.

775{
776 char *tok = get_token(&args, script, lineno);
777
778 if (tok)
779 ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
780
781 buf[0] = id;
782 buf[1] = 0;
783 return 2;
784}
enum queue_result id
Definition: app_queue.c:1638

References args, ast_log, buf, get_token(), id, and LOG_WARNING.

◆ cleardisplay()

static int cleardisplay ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 750 of file app_adsiprog.c.

751{
752 char *tok = get_token(&args, script, lineno);
753
754 if (tok)
755 ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
756
757 buf[0] = id;
758 buf[1] = 0x00;
759 return 2;
760}

References args, ast_log, buf, get_token(), id, and LOG_WARNING.

◆ clearflag()

static int clearflag ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 487 of file app_adsiprog.c.

488{
489 char *tok = get_token(&args, script, lineno);
490 struct adsi_flag *flag;
491 char sname[80];
492
493 if (!tok) {
494 ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script);
495 return 0;
496 }
497
498 if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
499 ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
500 return 0;
501 }
502
503 if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
504 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
505 return 0;
506 }
507
508 buf[0] = id;
509 buf[1] = ((flag->id & 0x7) << 4);
510
511 return 2;
512}
long int flag
Definition: f2c.h:83

References ARG_STRING, args, ast_log, buf, get_token(), getflagbyname(), id, LOG_WARNING, and process_token().

◆ cleartimer()

static int cleartimer ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 417 of file app_adsiprog.c.

418{
419 char *tok = get_token(&args, script, lineno);
420
421 if (tok)
422 ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
423
424 buf[0] = id;
425
426 /* For some reason the clear code is different slightly */
427 if (id == 7)
428 buf[1] = 0x10;
429 else
430 buf[1] = 0x00;
431
432 return 2;
433}

References args, ast_log, buf, get_token(), id, and LOG_WARNING.

◆ compile_script()

static struct adsi_script * compile_script ( const char *  script)
static

Definition at line 1369 of file app_adsiprog.c.

1370{
1371 FILE *f;
1372 char fn[256], buf[256], *c;
1373 int lineno = 0, x, err;
1374 struct adsi_script *scr;
1375
1376 if (script[0] == '/')
1377 ast_copy_string(fn, script, sizeof(fn));
1378 else
1379 snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, script);
1380
1381 if (!(f = fopen(fn, "r"))) {
1382 ast_log(LOG_WARNING, "Can't open file '%s'\n", fn);
1383 return NULL;
1384 }
1385
1386 if (!(scr = ast_calloc(1, sizeof(*scr)))) {
1387 fclose(f);
1388 return NULL;
1389 }
1390
1391 /* Create "main" as first subroutine */
1392 getsubbyname(scr, "main", NULL, 0);
1393 while (!feof(f)) {
1394 if (!fgets(buf, sizeof(buf), f)) {
1395 continue;
1396 }
1397 if (!feof(f)) {
1398 lineno++;
1399 /* Trim off trailing return */
1400 buf[strlen(buf) - 1] = '\0';
1401 /* Strip comments */
1402 if ((c = strchr(buf, ';')))
1403 *c = '\0';
1404 if (!ast_strlen_zero(buf))
1405 adsi_process(scr, buf, script, lineno);
1406 }
1407 }
1408 fclose(f);
1409 /* Make sure we're in the main routine again */
1410 switch(scr->state) {
1411 case STATE_NORMAL:
1412 break;
1413 case STATE_INSUB:
1414 ast_log(LOG_WARNING, "Missing ENDSUB at end of file %s\n", script);
1415 ast_free(scr);
1416 return NULL;
1417 case STATE_INKEY:
1418 ast_log(LOG_WARNING, "Missing ENDKEY at end of file %s\n", script);
1419 ast_free(scr);
1420 return NULL;
1421 }
1422 err = 0;
1423
1424 /* Resolve all keys and record their lengths */
1425 for (x = 0; x < scr->numkeys; x++) {
1426 if (!scr->keys[x].defined) {
1427 ast_log(LOG_WARNING, "Key '%s' referenced but never defined in file %s\n", scr->keys[x].vname, fn);
1428 err++;
1429 }
1430 }
1431
1432 /* Resolve all subs */
1433 for (x = 0; x < scr->numsubs; x++) {
1434 if (!scr->subs[x].defined) {
1435 ast_log(LOG_WARNING, "Subscript '%s' referenced but never defined in file %s\n", scr->subs[x].vname, fn);
1436 err++;
1437 }
1438 if (x == (scr->numsubs - 1)) {
1439 /* Clear out extension bit on last message */
1440 scr->subs[x].data[2] = 0x80;
1441 }
1442 }
1443
1444 if (err) {
1445 ast_free(scr);
1446 return NULL;
1447 }
1448 return scr;
1449}
static int adsi_process(struct adsi_script *state, char *buf, const char *script, int lineno)
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
const char * ast_config_AST_CONFIG_DIR
Definition: options.c:151
static struct test_val c

References adsi_process(), ast_calloc, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_free, ast_log, ast_strlen_zero(), buf, c, adsi_subscript::data, adsi_soft_key::defined, adsi_subscript::defined, getsubbyname(), adsi_script::keys, LOG_WARNING, NULL, adsi_script::numkeys, adsi_script::numsubs, adsi_script::state, STATE_INKEY, STATE_INSUB, STATE_NORMAL, adsi_script::subs, adsi_soft_key::vname, and adsi_subscript::vname.

Referenced by adsi_prog().

◆ digitcollect()

static int digitcollect ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 786 of file app_adsiprog.c.

787{
788 char *tok = get_token(&args, script, lineno);
789
790 if (tok)
791 ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
792
793 buf[0] = id;
794 buf[1] = 0xf;
795 return 2;
796}

References args, ast_log, buf, get_token(), id, and LOG_WARNING.

◆ digitdirect()

static int digitdirect ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 762 of file app_adsiprog.c.

763{
764 char *tok = get_token(&args, script, lineno);
765
766 if (tok)
767 ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
768
769 buf[0] = id;
770 buf[1] = 0x7;
771 return 2;
772}

References args, ast_log, buf, get_token(), id, and LOG_WARNING.

◆ get_token()

static char * get_token ( char **  buf,
const char *  script,
int  lineno 
)
static

Definition at line 243 of file app_adsiprog.c.

244{
245 char *tmp = *buf, *keyword;
246 int quoted = 0;
247
248 /* Advance past any white space */
249 while(*tmp && (*tmp < 33))
250 tmp++;
251 if (!*tmp)
252 return NULL;
253 keyword = tmp;
254 while(*tmp && ((*tmp > 32) || quoted)) {
255 if (*tmp == '\"') {
256 quoted = !quoted;
257 }
258 tmp++;
259 }
260 if (quoted) {
261 ast_log(LOG_WARNING, "Mismatched quotes at line %d of %s\n", lineno, script);
262 return NULL;
263 }
264 *tmp = '\0';
265 tmp++;
266 while(*tmp && (*tmp < 33))
267 tmp++;
268 /* Note where we left off */
269 *buf = tmp;
270 return keyword;
271}

References ast_log, buf, LOG_WARNING, NULL, and tmp().

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().

◆ getdisplaybyname()

static struct adsi_display * getdisplaybyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 627 of file app_adsiprog.c.

628{
629 int x;
630
631 for (x = 0; x < state->numdisplays; x++) {
632 if (!strcasecmp(state->displays[x].vname, name))
633 return &state->displays[x];
634 }
635
636 /* Return now if we're not allowed to create */
637 if (!create)
638 return NULL;
639
640 if (state->numdisplays > 61) {
641 ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script);
642 return NULL;
643 }
644
645 ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname));
646 state->displays[state->numdisplays].id = state->numdisplays + 1;
647 state->numdisplays++;
648
649 return &state->displays[state->numdisplays-1];
650}
static const char name[]
Definition: format_mp3.c:68

References ast_copy_string(), ast_log, LOG_WARNING, name, and NULL.

Referenced by adsi_process(), and showdisplay().

◆ geteventbyname()

static int geteventbyname ( char *  name)
static

Definition at line 536 of file app_adsiprog.c.

537{
538 int x;
539
540 for (x = 0; x < ARRAY_LEN(events); x++) {
541 if (!strcasecmp(events[x].name, name))
542 return events[x].id;
543 }
544
545 return 0;
546}
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, events, and name.

Referenced by adsi_process(), and onevent().

◆ getflagbyname()

static struct adsi_flag * getflagbyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 435 of file app_adsiprog.c.

436{
437 int x;
438
439 for (x = 0; x < state->numflags; x++) {
440 if (!strcasecmp(state->flags[x].vname, name))
441 return &state->flags[x];
442 }
443
444 /* Return now if we're not allowed to create */
445 if (!create)
446 return NULL;
447
448 if (state->numflags > 6) {
449 ast_log(LOG_WARNING, "No more flag space at line %d of %s\n", lineno, script);
450 return NULL;
451 }
452
453 ast_copy_string(state->flags[state->numflags].vname, name, sizeof(state->flags[state->numflags].vname));
454 state->flags[state->numflags].id = state->numflags + 1;
455 state->numflags++;
456
457 return &state->flags[state->numflags-1];
458}

References ast_copy_string(), ast_log, LOG_WARNING, name, and NULL.

Referenced by adsi_process(), clearflag(), setflag(), and showkeys().

◆ getjustifybyname()

static int getjustifybyname ( char *  name)
static

Definition at line 548 of file app_adsiprog.c.

549{
550 int x;
551
552 for (x = 0; x < ARRAY_LEN(justify); x++) {
553 if (!strcasecmp(justify[x].name, name))
554 return justify[x].id;
555 }
556
557 return -1;
558}
static const struct adsi_event justify[]
Definition: app_adsiprog.c:112

References ARRAY_LEN, justify, and name.

Referenced by adsi_process().

◆ getkeybyname()

static struct adsi_soft_key * getkeybyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno 
)
static

Definition at line 560 of file app_adsiprog.c.

561{
562 int x;
563
564 for (x = 0; x < state->numkeys; x++) {
565 if (!strcasecmp(state->keys[x].vname, name))
566 return &state->keys[x];
567 }
568
569 if (state->numkeys > 61) {
570 ast_log(LOG_WARNING, "No more key space at line %d of %s\n", lineno, script);
571 return NULL;
572 }
573
574 ast_copy_string(state->keys[state->numkeys].vname, name, sizeof(state->keys[state->numkeys].vname));
575 state->keys[state->numkeys].id = state->numkeys + 2;
576 state->numkeys++;
577
578 return &state->keys[state->numkeys-1];
579}

References ast_copy_string(), ast_log, LOG_WARNING, name, and NULL.

Referenced by adsi_process(), and showkeys().

◆ getstatebyname()

static struct adsi_state * getstatebyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 602 of file app_adsiprog.c.

603{
604 int x;
605
606 for (x = 0; x <state->numstates; x++) {
607 if (!strcasecmp(state->states[x].vname, name))
608 return &state->states[x];
609 }
610
611 /* Return now if we're not allowed to create */
612 if (!create)
613 return NULL;
614
615 if (state->numstates > 253) {
616 ast_log(LOG_WARNING, "No more state space at line %d of %s\n", lineno, script);
617 return NULL;
618 }
619
620 ast_copy_string(state->states[state->numstates].vname, name, sizeof(state->states[state->numstates].vname));
621 state->states[state->numstates].id = state->numstates + 1;
622 state->numstates++;
623
624 return &state->states[state->numstates-1];
625}

References ast_copy_string(), ast_log, LOG_WARNING, name, and NULL.

Referenced by adsi_process(), and onevent().

◆ getsubbyname()

static struct adsi_subscript * getsubbyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno 
)
static

Definition at line 581 of file app_adsiprog.c.

582{
583 int x;
584
585 for (x = 0; x < state->numsubs; x++) {
586 if (!strcasecmp(state->subs[x].vname, name))
587 return &state->subs[x];
588 }
589
590 if (state->numsubs > 127) {
591 ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, S_OR(script, "unknown"));
592 return NULL;
593 }
594
595 ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname));
596 state->subs[state->numsubs].id = state->numsubs;
597 state->numsubs++;
598
599 return &state->subs[state->numsubs-1];
600}
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80

References ast_copy_string(), ast_log, LOG_WARNING, name, NULL, and S_OR.

Referenced by adsi_process(), compile_script(), onevent(), and subscript().

◆ goto_line()

static int goto_line ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 305 of file app_adsiprog.c.

306{
307 char *page = get_token(&args, script, lineno);
308 char *gline = get_token(&args, script, lineno);
309 int line;
310 unsigned char cmd;
311
312 if (!page || !gline) {
313 ast_log(LOG_WARNING, "Expecting page and line number for GOTOLINE at line %d of %s\n", lineno, script);
314 return 0;
315 }
316
317 if (!strcasecmp(page, "INFO"))
318 cmd = 0;
319 else if (!strcasecmp(page, "COMM"))
320 cmd = 0x80;
321 else {
322 ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got '%s' at line %d of %s\n", page, lineno, script);
323 return 0;
324 }
325
326 if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
327 ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
328 return 0;
329 }
330
331 cmd |= line;
332 buf[0] = 0x8b;
333 buf[1] = cmd;
334
335 return 2;
336}

References ARG_NUMBER, args, ast_log, buf, get_token(), LOG_WARNING, and process_token().

◆ goto_line_rel()

static int goto_line_rel ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 338 of file app_adsiprog.c.

339{
340 char *dir = get_token(&args, script, lineno);
341 char *gline = get_token(&args, script, lineno);
342 int line;
343 unsigned char cmd;
344
345 if (!dir || !gline) {
346 ast_log(LOG_WARNING, "Expecting direction and number of lines for GOTOLINEREL at line %d of %s\n", lineno, script);
347 return 0;
348 }
349
350 if (!strcasecmp(dir, "UP"))
351 cmd = 0;
352 else if (!strcasecmp(dir, "DOWN"))
353 cmd = 0x20;
354 else {
355 ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script);
356 return 0;
357 }
358
359 if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
360 ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
361 return 0;
362 }
363
364 cmd |= line;
365 buf[0] = 0x8c;
366 buf[1] = cmd;
367
368 return 2;
369}

References ARG_NUMBER, args, ast_log, buf, get_token(), LOG_WARNING, and process_token().

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Definition at line 1605 of file app_adsiprog.c.

1606{
1610}
static const char app[]
Definition: app_adsiprog.c:56
static int adsi_exec(struct ast_channel *chan, const char *data)
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:626

References adsi_exec(), app, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and ast_register_application_xml.

◆ onevent()

static int onevent ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 823 of file app_adsiprog.c.

824{
825 char *tok = get_token(&args, script, lineno);
826 char subscr[80], sname[80];
827 int sawin = 0, event, snums[8], scnt = 0, x;
828 struct adsi_subscript *sub;
829
830 if (!tok) {
831 ast_log(LOG_WARNING, "Missing event for 'ONEVENT' at line %d of %s\n", lineno, script);
832 return 0;
833 }
834
835 if ((event = geteventbyname(tok)) < 1) {
836 ast_log(LOG_WARNING, "'%s' is not a valid event name, at line %d of %s\n", args, lineno, script);
837 return 0;
838 }
839
840 tok = get_token(&args, script, lineno);
841 while ((!sawin && !strcasecmp(tok, "IN")) || (sawin && !strcasecmp(tok, "OR"))) {
842 sawin = 1;
843 if (scnt > 7) {
844 ast_log(LOG_WARNING, "No more than 8 states may be specified for inclusion at line %d of %s\n", lineno, script);
845 return 0;
846 }
847 /* Process 'in' things */
848 tok = get_token(&args, script, lineno);
849 if (process_token(sname, tok, sizeof(sname), ARG_STRING)) {
850 ast_log(LOG_WARNING, "'%s' is not a valid state name at line %d of %s\n", tok, lineno, script);
851 return 0;
852 }
853 if ((snums[scnt] = getstatebyname(state, sname, script, lineno, 0) == NULL)) {
854 ast_log(LOG_WARNING, "State '%s' not declared at line %d of %s\n", sname, lineno, script);
855 return 0;
856 }
857 scnt++;
858 if (!(tok = get_token(&args, script, lineno)))
859 break;
860 }
861 if (!tok || strcasecmp(tok, "GOTO")) {
862 if (!tok)
863 tok = "<nothing>";
864 if (sawin)
865 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script);
866 else
867 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script);
868 }
869 if (!(tok = get_token(&args, script, lineno))) {
870 ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
871 return 0;
872 }
873 if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
874 ast_log(LOG_WARNING, "Invalid subscript '%s' at line %d of %s\n", tok, lineno, script);
875 return 0;
876 }
877 if (!(sub = getsubbyname(state, subscr, script, lineno)))
878 return 0;
879 buf[0] = 8;
880 buf[1] = event;
881 buf[2] = sub->id | 0x80;
882 for (x = 0; x < scnt; x++)
883 buf[3 + x] = snums[x];
884 return 3 + scnt;
885}
struct stasis_forward * sub
Definition: res_corosync.c:240

References ARG_STRING, args, ast_log, buf, get_token(), geteventbyname(), getstatebyname(), getsubbyname(), LOG_WARNING, NULL, process_token(), and sub.

◆ process_opcode()

static int process_opcode ( struct adsi_subscript sub,
char *  code,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 984 of file app_adsiprog.c.

985{
986 int x, res, max = sub->id ? MAX_SUB_LEN : MAX_MAIN_LEN;
987 char *unused;
988
989 for (x = 0; x < ARRAY_LEN(opcmds); x++) {
990 if ((opcmds[x].id > -1) && !strcasecmp(opcmds[x].name, code)) {
991 if (opcmds[x].add_args) {
992 res = opcmds[x].add_args(sub->data + sub->datalen,
993 code, opcmds[x].id, args, state, script, lineno);
994 if ((sub->datalen + res + 1) <= max)
995 sub->datalen += res;
996 else {
997 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);
998 return -1;
999 }
1000 } else {
1001 if ((unused = get_token(&args, script, lineno)))
1002 ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", opcmds[x].name, lineno, script, unused);
1003 if ((sub->datalen + 2) <= max) {
1004 sub->data[sub->datalen] = opcmds[x].id;
1005 sub->datalen++;
1006 } else {
1007 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);
1008 return -1;
1009 }
1010 }
1011 /* Separate commands with 0xff */
1012 sub->data[sub->datalen] = 0xff;
1013 sub->datalen++;
1014 sub->inscount++;
1015 return 0;
1016 }
1017 }
1018 return -1;
1019}
#define MAX_MAIN_LEN
Definition: app_adsiprog.c:126
static const struct adsi_key_cmd opcmds[]
Definition: app_adsiprog.c:935
#define MAX_SUB_LEN
Definition: app_adsiprog.c:125
#define max(a, b)
Definition: f2c.h:198
int(* add_args)(char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:890

References adsi_key_cmd::add_args, args, ARRAY_LEN, ast_log, get_token(), adsi_key_cmd::id, LOG_WARNING, max, MAX_MAIN_LEN, MAX_SUB_LEN, name, opcmds, and sub.

Referenced by adsi_process().

◆ process_returncode()

static int process_returncode ( struct adsi_soft_key key,
char *  code,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 955 of file app_adsiprog.c.

956{
957 int x, res;
958 char *unused;
959
960 for (x = 0; x < ARRAY_LEN(kcmds); x++) {
961 if ((kcmds[x].id > -1) && !strcasecmp(kcmds[x].name, code)) {
962 if (kcmds[x].add_args) {
963 res = kcmds[x].add_args(key->retstr + key->retstrlen,
964 code, kcmds[x].id, args, state, script, lineno);
965 if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
966 key->retstrlen += res;
967 else
968 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);
969 } else {
970 if ((unused = get_token(&args, script, lineno)))
971 ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused);
972 if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) {
973 key->retstr[key->retstrlen] = kcmds[x].id;
974 key->retstrlen++;
975 } else
976 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);
977 }
978 return 0;
979 }
980 }
981 return -1;
982}
static const struct adsi_key_cmd kcmds[]
Definition: app_adsiprog.c:893
#define MAX_RET_CODE
Definition: app_adsiprog.c:124

References adsi_key_cmd::add_args, args, ARRAY_LEN, ast_log, get_token(), adsi_key_cmd::id, adsi_soft_key::initlen, kcmds, LOG_WARNING, MAX_RET_CODE, name, adsi_soft_key::retstr, adsi_soft_key::retstrlen, and adsi_soft_key::vname.

Referenced by adsi_process().

◆ process_token()

static int process_token ( void *  out,
char *  src,
int  maxlen,
int  argtype 
)
static

Definition at line 196 of file app_adsiprog.c.

197{
198 if ((strlen(src) > 1) && src[0] == '\"') {
199 /* This is a quoted string */
200 if (!(argtype & ARG_STRING))
201 return -1;
202 src++;
203 /* Don't take more than what's there */
204 if (maxlen > strlen(src) - 1)
205 maxlen = strlen(src) - 1;
206 memcpy(out, src, maxlen);
207 ((char *)out)[maxlen] = '\0';
208 } else if (!ast_strlen_zero(src) && (src[0] == '\\')) {
209 if (!(argtype & ARG_NUMBER))
210 return -1;
211 /* Octal value */
212 if (sscanf(src, "%30o", (unsigned *)out) != 1)
213 return -1;
214 if (argtype & ARG_STRING) {
215 /* Convert */
216 *((unsigned int *)out) = htonl(*((unsigned int *)out));
217 }
218 } else if ((strlen(src) > 2) && (src[0] == '0') && (tolower(src[1]) == 'x')) {
219 if (!(argtype & ARG_NUMBER))
220 return -1;
221 /* Hex value */
222 if (sscanf(src + 2, "%30x", (unsigned int *)out) != 1)
223 return -1;
224 if (argtype & ARG_STRING) {
225 /* Convert */
226 *((unsigned int *)out) = htonl(*((unsigned int *)out));
227 }
228 } else if ((!ast_strlen_zero(src) && isdigit(src[0]))) {
229 if (!(argtype & ARG_NUMBER))
230 return -1;
231 /* Hex value */
232 if (sscanf(src, "%30d", (int *)out) != 1)
233 return -1;
234 if (argtype & ARG_STRING) {
235 /* Convert */
236 *((unsigned int *)out) = htonl(*((unsigned int *)out));
237 }
238 } else
239 return -1;
240 return 0;
241}
FILE * out
Definition: utils/frame.c:33

References ARG_NUMBER, ARG_STRING, ast_strlen_zero(), and out.

Referenced by adsi_process(), clearflag(), goto_line(), goto_line_rel(), onevent(), send_delay(), send_dtmf(), set_state(), setflag(), showdisplay(), showkeys(), starttimer(), and subscript().

◆ send_delay()

static int send_delay ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 371 of file app_adsiprog.c.

372{
373 char *gtime = get_token(&args, script, lineno);
374 int ms;
375
376 if (!gtime) {
377 ast_log(LOG_WARNING, "Expecting number of milliseconds to wait at line %d of %s\n", lineno, script);
378 return 0;
379 }
380
381 if (process_token(&ms, gtime, sizeof(ms), ARG_NUMBER)) {
382 ast_log(LOG_WARNING, "Invalid delay milliseconds '%s' at line %d of %s\n", gtime, lineno, script);
383 return 0;
384 }
385
386 buf[0] = 0x90;
387
388 if (id == 11)
389 buf[1] = ms / 100;
390 else
391 buf[1] = ms / 10;
392
393 return 2;
394}

References ARG_NUMBER, args, ast_log, buf, get_token(), LOG_WARNING, and process_token().

◆ send_dtmf()

static int send_dtmf ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 275 of file app_adsiprog.c.

276{
277 char dtmfstr[80], *a;
278 int bytes = 0;
279
280 if (!(a = get_token(&args, script, lineno))) {
281 ast_log(LOG_WARNING, "Expecting something to send for SENDDTMF at line %d of %s\n", lineno, script);
282 return 0;
283 }
284
285 if (process_token(dtmfstr, a, sizeof(dtmfstr) - 1, ARG_STRING)) {
286 ast_log(LOG_WARNING, "Invalid token for SENDDTMF at line %d of %s\n", lineno, script);
287 return 0;
288 }
289
290 a = dtmfstr;
291
292 while (*a) {
293 if (strchr(validdtmf, *a)) {
294 *buf = *a;
295 buf++;
296 bytes++;
297 } else
298 ast_log(LOG_WARNING, "'%c' is not a valid DTMF tone at line %d of %s\n", *a, lineno, script);
299 a++;
300 }
301
302 return bytes;
303}
static char * validdtmf
Definition: app_adsiprog.c:273
static struct test_val a

References a, ARG_STRING, args, ast_log, buf, get_token(), LOG_WARNING, process_token(), and validdtmf.

◆ set_state()

static int set_state ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 396 of file app_adsiprog.c.

397{
398 char *gstate = get_token(&args, script, lineno);
399 int state;
400
401 if (!gstate) {
402 ast_log(LOG_WARNING, "Expecting state number at line %d of %s\n", lineno, script);
403 return 0;
404 }
405
406 if (process_token(&state, gstate, sizeof(state), ARG_NUMBER)) {
407 ast_log(LOG_WARNING, "Invalid state number '%s' at line %d of %s\n", gstate, lineno, script);
408 return 0;
409 }
410
411 buf[0] = id;
412 buf[1] = state;
413
414 return 2;
415}
enum cc_state state
Definition: ccss.c:393

References ARG_NUMBER, args, ast_log, buf, get_token(), id, LOG_WARNING, process_token(), and state.

◆ setflag()

static int setflag ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 460 of file app_adsiprog.c.

461{
462 char *tok = get_token(&args, script, lineno);
463 char sname[80];
464 struct adsi_flag *flag;
465
466 if (!tok) {
467 ast_log(LOG_WARNING, "Setting flag requires a flag number at line %d of %s\n", lineno, script);
468 return 0;
469 }
470
471 if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
472 ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
473 return 0;
474 }
475
476 if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
477 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
478 return 0;
479 }
480
481 buf[0] = id;
482 buf[1] = ((flag->id & 0x7) << 4) | 1;
483
484 return 2;
485}

References ARG_STRING, args, ast_log, buf, get_token(), getflagbyname(), id, LOG_WARNING, and process_token().

◆ showdisplay()

static int showdisplay ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 699 of file app_adsiprog.c.

700{
701 char *tok, dispname[80];
702 int line = 0, flag = 0, cmd = 3;
703 struct adsi_display *disp;
704
705 /* Get display */
706 if (!(tok = get_token(&args, script, lineno)) || process_token(dispname, tok, sizeof(dispname) - 1, ARG_STRING)) {
707 ast_log(LOG_WARNING, "Invalid display name: %s at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
708 return 0;
709 }
710
711 if (!(disp = getdisplaybyname(state, dispname, script, lineno, 0))) {
712 ast_log(LOG_WARNING, "Display '%s' is undefined at line %d of %s\n", dispname, lineno, script);
713 return 0;
714 }
715
716 if (!(tok = get_token(&args, script, lineno)) || strcasecmp(tok, "AT")) {
717 ast_log(LOG_WARNING, "Missing token 'AT' at line %d of %s\n", lineno, script);
718 return 0;
719 }
720
721 /* Get line number */
722 if (!(tok = get_token(&args, script, lineno)) || process_token(&line, tok, sizeof(line), ARG_NUMBER)) {
723 ast_log(LOG_WARNING, "Invalid line: '%s' at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
724 return 0;
725 }
726
727 if ((tok = get_token(&args, script, lineno)) && !strcasecmp(tok, "NOUPDATE")) {
728 cmd = 1;
729 tok = get_token(&args, script, lineno);
730 }
731
732 if (tok && !strcasecmp(tok, "UNLESS")) {
733 /* Check for trailing UNLESS flag */
734 if (!(tok = get_token(&args, script, lineno)))
735 ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
736 else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER))
737 ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script);
738
739 if ((tok = get_token(&args, script, lineno)))
740 ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
741 }
742
743 buf[0] = id;
744 buf[1] = (cmd << 6) | (disp->id & 0x3f);
745 buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
746
747 return 3;
748}

References ARG_NUMBER, ARG_STRING, args, ast_log, buf, get_token(), getdisplaybyname(), adsi_display::id, id, LOG_WARNING, and process_token().

◆ showkeys()

static int showkeys ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 652 of file app_adsiprog.c.

653{
654 char *tok, newkey[80];
655 int bytes, x, flagid = 0;
656 unsigned char keyid[6];
657 struct adsi_soft_key *key;
658 struct adsi_flag *flag;
659
660 for (x = 0; x < 7; x++) {
661 /* Up to 6 key arguments */
662 if (!(tok = get_token(&args, script, lineno)))
663 break;
664 if (!strcasecmp(tok, "UNLESS")) {
665 /* Check for trailing UNLESS flag */
666 if (!(tok = get_token(&args, script, lineno)))
667 ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
668 else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING))
669 ast_log(LOG_WARNING, "Invalid flag name '%s' at line %d of %s\n", tok, lineno, script);
670 else if (!(flag = getflagbyname(state, newkey, script, lineno, 0)))
671 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", newkey, lineno, script);
672 else
673 flagid = flag->id;
674 if ((tok = get_token(&args, script, lineno)))
675 ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
676 break;
677 }
678 if (x > 5) {
679 ast_log(LOG_WARNING, "Only 6 keys can be defined, ignoring '%s' at line %d of %s\n", tok, lineno, script);
680 break;
681 }
682 if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
683 ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok);
684 continue;
685 }
686
687 if (!(key = getkeybyname(state, newkey, script, lineno)))
688 break;
689 keyid[x] = key->id;
690 }
691 buf[0] = id;
692 buf[1] = (flagid & 0x7) << 3 | (x & 0x7);
693 for (bytes = 0; bytes < x; bytes++)
694 buf[bytes + 2] = keyid[bytes];
695
696 return 2 + x;
697}

References ARG_STRING, args, ast_log, buf, get_token(), getflagbyname(), getkeybyname(), adsi_soft_key::id, id, LOG_WARNING, and process_token().

◆ starttimer()

static int starttimer ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 514 of file app_adsiprog.c.

515{
516 char *tok = get_token(&args, script, lineno);
517 int secs;
518
519 if (!tok) {
520 ast_log(LOG_WARNING, "Missing number of seconds at line %d of %s\n", lineno, script);
521 return 0;
522 }
523
524 if (process_token(&secs, tok, sizeof(secs), ARG_NUMBER)) {
525 ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
526 return 0;
527 }
528
529 buf[0] = id;
530 buf[1] = 0x1;
531 buf[2] = secs;
532
533 return 3;
534}

References ARG_NUMBER, args, ast_log, buf, get_token(), id, LOG_WARNING, and process_token().

◆ subscript()

static int subscript ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 798 of file app_adsiprog.c.

799{
800 char *tok = get_token(&args, script, lineno);
801 char subscr[80];
802 struct adsi_subscript *sub;
803
804 if (!tok) {
805 ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
806 return 0;
807 }
808
809 if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
810 ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
811 return 0;
812 }
813
814 if (!(sub = getsubbyname(state, subscr, script, lineno)))
815 return 0;
816
817 buf[0] = 0x9d;
818 buf[1] = sub->id;
819
820 return 2;
821}

References ARG_STRING, args, ast_log, buf, get_token(), getsubbyname(), LOG_WARNING, process_token(), and sub.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1590 of file app_adsiprog.c.

1591{
1593}
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx_app.c:392

References app, and ast_unregister_application().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Asterisk ADSI Programming Application" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .requires = "res_adsi", }
static

Definition at line 1617 of file app_adsiprog.c.

◆ app

const char app[] = "ADSIProg"
static

Definition at line 56 of file app_adsiprog.c.

Referenced by __stasis_app_register(), action_originate(), add_extension(), add_extensions(), adsi_load_session(), answer_exec_enable(), answer_exec_run(), app_create(), app_deactivate(), app_dtor(), app_event_filter_set(), app_event_sources_to_json(), app_events_allowed_set(), app_events_disallowed_set(), app_handle_subscriptions(), app_hash(), app_is_active(), app_is_finished(), app_is_subscribed_bridge_id(), app_is_subscribed_channel_id(), app_is_subscribed_endpoint_id(), app_name(), app_send(), app_send_end_msg(), app_shutdown(), app_subscribe(), app_subscribe_bridge(), app_subscribe_channel(), app_subscribe_endpoint(), app_to_json(), app_unsubscribe(), app_unsubscribe_bridge(), app_unsubscribe_bridge_id(), app_unsubscribe_channel(), app_unsubscribe_channel_id(), app_unsubscribe_endpoint_id(), app_update(), append_json(), append_name(), applicationmap_handler(), applicationmap_item_alloc(), ari_originate_dial(), ari_set_debug(), ari_show_app(), ari_show_apps(), ast_adsi_load_session(), ast_app_get_topic(), ast_ari_applications_filter(), ast_ari_callback(), ast_attended_transfer_message_add_app(), ast_bridge_transfer_attended(), ast_compile_ael2(), ast_complete_applications(), ast_pbx_exec_application(), ast_pbx_outgoing_app(), ast_pbx_outgoing_app_predial(), ast_register_application2(), AST_TEST_DEFINE(), ast_unregister_application(), attended_transfer_bridge(), bridge_app_subscribed(), bridge_app_subscribed_involved(), bridge_attended_transfer_handler(), bridge_blind_transfer_handler(), bridge_merge_handler(), bridge_subscription_change_handler(), call_forwarded_handler(), cel_track_app(), check_app_args(), check_pval_item(), cleanup_cb(), complete_ari_app(), control_create(), control_set_app(), device_state_subscription_create(), devices_to_json(), endpoint_state_cb(), event_session_alloc(), event_session_shutdown(), exec_exec(), execif_exec(), extension_presence_state_helper(), find_device_state(), find_device_state_subscription(), forwards_create(), forwards_create_bridge(), forwards_create_channel(), forwards_create_endpoint(), handle_cli_dialplan_add_extension(), handle_cli_status(), handle_exec(), handle_show_application(), is_subscribed_device_state(), is_subscribed_device_state_lock(), load_module(), load_moh_classes(), lua_pbx_exec(), message_received_handler(), orig_app(), page_exec(), parse_line(), pbx_exec(), pbx_extension_helper(), pbx_findapp(), pbx_outgoing_attempt(), pbx_outgoing_exec(), realtime_exec(), send_start_msg(), send_start_msg_snapshots(), stasis_app_control_snoop(), stasis_app_event_allowed(), stasis_app_event_filter_set(), stasis_app_event_filter_to_json(), stasis_app_exec(), stasis_app_get_debug(), stasis_app_get_debug_by_name(), stasis_app_name(), stasis_app_object_to_json(), stasis_app_send(), stasis_app_set_debug(), stasis_app_set_debug_by_name(), stasis_app_set_global_debug(), stasis_app_subscribe_channel(), stasis_app_to_cli(), stasis_app_to_json(), stasis_app_unregister(), stasis_app_user_event(), sub_bridge_update_handler(), sub_channel_update_handler(), sub_endpoint_update_handler(), sub_subscription_change_handler(), subscribe_bridge(), subscribe_channel(), subscribe_device_state(), subscribe_endpoint(), tryexec_exec(), unload_module(), unreference_cached_app(), unsubscribe(), and unsubscribe_device_state().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1617 of file app_adsiprog.c.

◆ events

const struct adsi_event events[]
static

◆ justify

const struct adsi_event justify[]
static

Definition at line 112 of file app_adsiprog.c.

Referenced by cpeid_setstatus(), and getjustifybyname().

◆ kcmds

const struct adsi_key_cmd kcmds[]
static

Definition at line 893 of file app_adsiprog.c.

Referenced by process_returncode().

◆ opcmds

const struct adsi_key_cmd opcmds[]
static

Definition at line 935 of file app_adsiprog.c.

Referenced by process_opcode().

◆ validdtmf

char* validdtmf = "123456789*0#ABCD"
static

Definition at line 273 of file app_adsiprog.c.

Referenced by send_dtmf().