Asterisk - The Open Source Telephony Project GIT-master-77d630f
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 132 of file app_adsiprog.c.

◆ ARG_STRING

#define ARG_STRING   (1 << 0)

Definition at line 131 of file app_adsiprog.c.

◆ MAX_MAIN_LEN

#define MAX_MAIN_LEN   1600

Definition at line 129 of file app_adsiprog.c.

◆ MAX_RET_CODE

#define MAX_RET_CODE   20

Definition at line 127 of file app_adsiprog.c.

◆ MAX_SUB_LEN

#define MAX_SUB_LEN   255

Definition at line 128 of file app_adsiprog.c.

◆ STATE_INIF

#define STATE_INIF   3

Definition at line 125 of file app_adsiprog.c.

◆ STATE_INKEY

#define STATE_INKEY   1

Definition at line 123 of file app_adsiprog.c.

◆ STATE_INSUB

#define STATE_INSUB   2

Definition at line 124 of file app_adsiprog.c.

◆ STATE_NORMAL

#define STATE_NORMAL   0

Definition at line 122 of file app_adsiprog.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1623 of file app_adsiprog.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1623 of file app_adsiprog.c.

◆ adsi_exec()

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

Definition at line 1579 of file app_adsiprog.c.

1580{
1581 int res = 0;
1582
1583 if (ast_strlen_zero(data))
1584 data = "asterisk.adsi";
1585
1586 if (!ast_adsi_available(chan)) {
1587 ast_verb(3, "ADSI Unavailable on CPE. Not bothering to try.\n");
1588 } else {
1589 ast_verb(3, "ADSI Available on CPE. Attempting Upload.\n");
1590 res = adsi_prog(chan, data);
1591 }
1592
1593 return res;
1594}
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 1027 of file app_adsiprog.c.

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

1469{
1470 struct adsi_script *scr;
1471 int x, bytes;
1472 unsigned char buf[1024];
1473
1474 if (!(scr = compile_script(script)))
1475 return -1;
1476
1477 /* Start an empty ADSI Session */
1478 if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
1479 return -1;
1480
1481 /* Now begin the download attempt */
1482 if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
1483 /* User rejected us for some reason */
1484 ast_verb(3, "User rejected download attempt\n");
1485 ast_log(LOG_NOTICE, "User rejected download on channel %s\n", ast_channel_name(chan));
1486 ast_free(scr);
1487 return -1;
1488 }
1489
1490 bytes = 0;
1491 /* Start with key definitions */
1492 for (x = 0; x < scr->numkeys; x++) {
1493 if (bytes + scr->keys[x].retstrlen > 253) {
1494 /* Send what we've collected so far */
1495 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1496 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1497 return -1;
1498 }
1499 bytes =0;
1500 }
1501 memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
1502 bytes += scr->keys[x].retstrlen;
1503#ifdef DUMP_MESSAGES
1504 dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
1505#endif
1506 }
1507 if (bytes) {
1508 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1509 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1510 return -1;
1511 }
1512 }
1513
1514 bytes = 0;
1515 /* Continue with the display messages */
1516 for (x = 0; x < scr->numdisplays; x++) {
1517 if (bytes + scr->displays[x].datalen > 253) {
1518 /* Send what we've collected so far */
1519 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1520 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1521 return -1;
1522 }
1523 bytes =0;
1524 }
1525 memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
1526 bytes += scr->displays[x].datalen;
1527#ifdef DUMP_MESSAGES
1528 dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
1529#endif
1530 }
1531 if (bytes) {
1532 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1533 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1534 return -1;
1535 }
1536 }
1537
1538 bytes = 0;
1539 /* Send subroutines */
1540 for (x = 0; x < scr->numsubs; x++) {
1541 if (bytes + scr->subs[x].datalen > 253) {
1542 /* Send what we've collected so far */
1543 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1544 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1545 return -1;
1546 }
1547 bytes =0;
1548 }
1549 memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
1550 bytes += scr->subs[x].datalen;
1551#ifdef DUMP_MESSAGES
1552 dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
1553#endif
1554 }
1555 if (bytes) {
1556 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1557 ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1558 return -1;
1559 }
1560 }
1561
1562 bytes = 0;
1563 bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
1564 bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
1565 if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
1566 return -1;
1567 if (ast_adsi_end_download(chan)) {
1568 /* Download failed for some reason */
1569 ast_verb(3, "Download attempt failed\n");
1570 ast_log(LOG_NOTICE, "Download failed on %s\n", ast_channel_name(chan));
1571 ast_free(scr);
1572 return -1;
1573 }
1574 ast_free(scr);
1576 return 0;
1577}
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:165
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:187
unsigned char fdn[5]
Definition: app_adsiprog.c:194
char desc[19]
Definition: app_adsiprog.c:193
unsigned char sec[5]
Definition: app_adsiprog.c:192
struct adsi_display displays[63]
Definition: app_adsiprog.c:181
struct adsi_soft_key keys[62]
Definition: app_adsiprog.c:185
char retstr[80]
Definition: app_adsiprog.c:140
char vname[40]
Definition: app_adsiprog.c:135
char data[2048]
Definition: app_adsiprog.c:151

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 1623 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 777 of file app_adsiprog.c.

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

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 753 of file app_adsiprog.c.

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

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 490 of file app_adsiprog.c.

491{
492 char *tok = get_token(&args, script, lineno);
493 struct adsi_flag *flag;
494 char sname[80];
495
496 if (!tok) {
497 ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script);
498 return 0;
499 }
500
501 if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
502 ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
503 return 0;
504 }
505
506 if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
507 ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
508 return 0;
509 }
510
511 buf[0] = id;
512 buf[1] = ((flag->id & 0x7) << 4);
513
514 return 2;
515}
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 420 of file app_adsiprog.c.

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

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 1375 of file app_adsiprog.c.

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

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

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 765 of file app_adsiprog.c.

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

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 246 of file app_adsiprog.c.

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

References ast_log, buf, LOG_WARNING, and NULL.

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 630 of file app_adsiprog.c.

631{
632 int x;
633
634 for (x = 0; x < state->numdisplays; x++) {
635 if (!strcasecmp(state->displays[x].vname, name))
636 return &state->displays[x];
637 }
638
639 /* Return now if we're not allowed to create */
640 if (!create)
641 return NULL;
642
643 if (state->numdisplays > 61) {
644 ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script);
645 return NULL;
646 }
647
648 ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname));
649 state->displays[state->numdisplays].id = state->numdisplays + 1;
650 state->numdisplays++;
651
652 return &state->displays[state->numdisplays-1];
653}
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 539 of file app_adsiprog.c.

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

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 438 of file app_adsiprog.c.

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

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 551 of file app_adsiprog.c.

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

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 563 of file app_adsiprog.c.

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

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 605 of file app_adsiprog.c.

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

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 584 of file app_adsiprog.c.

585{
586 int x;
587
588 for (x = 0; x < state->numsubs; x++) {
589 if (!strcasecmp(state->subs[x].vname, name))
590 return &state->subs[x];
591 }
592
593 if (state->numsubs > 127) {
594 ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, S_OR(script, "unknown"));
595 return NULL;
596 }
597
598 ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname));
599 state->subs[state->numsubs].id = state->numsubs;
600 state->numsubs++;
601
602 return &state->subs[state->numsubs-1];
603}
#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 308 of file app_adsiprog.c.

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

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 341 of file app_adsiprog.c.

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

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 1611 of file app_adsiprog.c.

1612{
1616}
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:640

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 826 of file app_adsiprog.c.

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

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

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 961 of file app_adsiprog.c.

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

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 199 of file app_adsiprog.c.

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

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

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 278 of file app_adsiprog.c.

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

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

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 463 of file app_adsiprog.c.

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

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 702 of file app_adsiprog.c.

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

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 655 of file app_adsiprog.c.

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

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 517 of file app_adsiprog.c.

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

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 801 of file app_adsiprog.c.

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

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 1596 of file app_adsiprog.c.

1597{
1599}
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 1623 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_match(), 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(), control_create(), control_set_app(), device_state_subscription_create(), devices_to_json(), endpoint_state_cb(), 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_originate_app_permitted(), is_subscribed_device_state(), is_subscribed_device_state_lock(), load_module(), load_moh_classes(), lua_pbx_exec(), message_received_handler(), orig_app(), outbound_session_apply_config(), outbound_websocket_apply(), outbound_websocket_validate_cb(), page_exec(), parse_line(), pbx_exec(), pbx_extension_helper(), pbx_findapp(), pbx_outgoing_attempt(), pbx_outgoing_exec(), queue_match(), realtime_exec(), send_start_msg(), send_start_msg_snapshots(), session_find_by_app(), session_update(), 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_is_registered(), 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 1623 of file app_adsiprog.c.

◆ events

const struct adsi_event events[]
static

◆ justify

const struct adsi_event justify[]
static

Definition at line 115 of file app_adsiprog.c.

Referenced by cpeid_setstatus(), and getjustifybyname().

◆ kcmds

const struct adsi_key_cmd kcmds[]
static

Definition at line 899 of file app_adsiprog.c.

Referenced by process_returncode().

◆ opcmds

const struct adsi_key_cmd opcmds[]
static

Definition at line 941 of file app_adsiprog.c.

Referenced by process_opcode().

◆ validdtmf

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

Definition at line 276 of file app_adsiprog.c.

Referenced by send_dtmf().