Asterisk - The Open Source Telephony Project GIT-master-8f1982c
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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 1620 of file app_adsiprog.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1620 of file app_adsiprog.c.

◆ adsi_exec()

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

Definition at line 1576 of file app_adsiprog.c.

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

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

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

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

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

1609{
1613}
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 tok = get_token(&args, script, lineno);
852 if (process_token(sname, tok, sizeof(sname), ARG_STRING)) {
853 ast_log(LOG_WARNING, "'%s' is not a valid state name at line %d of %s\n", tok, lineno, script);
854 return 0;
855 }
856 if ((snums[scnt] = getstatebyname(state, sname, script, lineno, 0) == NULL)) {
857 ast_log(LOG_WARNING, "State '%s' not declared at line %d of %s\n", sname, lineno, script);
858 return 0;
859 }
860 scnt++;
861 if (!(tok = get_token(&args, script, lineno)))
862 break;
863 }
864 if (!tok || strcasecmp(tok, "GOTO")) {
865 if (!tok)
866 tok = "<nothing>";
867 if (sawin)
868 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script);
869 else
870 ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script);
871 }
872 if (!(tok = get_token(&args, script, lineno))) {
873 ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
874 return 0;
875 }
876 if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
877 ast_log(LOG_WARNING, "Invalid subscript '%s' at line %d of %s\n", tok, lineno, script);
878 return 0;
879 }
880 if (!(sub = getsubbyname(state, subscr, script, lineno)))
881 return 0;
882 buf[0] = 8;
883 buf[1] = event;
884 buf[2] = sub->id | 0x80;
885 for (x = 0; x < scnt; x++)
886 buf[3 + x] = snums[x];
887 return 3 + scnt;
888}
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 987 of file app_adsiprog.c.

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

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

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

1594{
1596}
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 1620 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(), ari_ws_session_create(), ari_ws_session_reset(), 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(), 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(), 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(), 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 1620 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 896 of file app_adsiprog.c.

Referenced by process_returncode().

◆ opcmds

const struct adsi_key_cmd opcmds[]
static

Definition at line 938 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().