Asterisk - The Open Source Telephony Project  GIT-master-1f78ee9
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"

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)

◆ ARG_STRING

#define ARG_STRING   (1 << 0)

◆ MAX_MAIN_LEN

#define MAX_MAIN_LEN   1600

Definition at line 126 of file app_adsiprog.c.

Referenced by process_opcode().

◆ MAX_RET_CODE

#define MAX_RET_CODE   20

Definition at line 124 of file app_adsiprog.c.

Referenced by process_returncode().

◆ MAX_SUB_LEN

#define MAX_SUB_LEN   255

Definition at line 125 of file app_adsiprog.c.

Referenced by process_opcode().

◆ STATE_INIF

#define STATE_INIF   3

Definition at line 122 of file app_adsiprog.c.

Referenced by adsi_process().

◆ STATE_INKEY

#define STATE_INKEY   1

Definition at line 120 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

◆ STATE_INSUB

#define STATE_INSUB   2

Definition at line 121 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

◆ STATE_NORMAL

#define STATE_NORMAL   0

Definition at line 119 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1617 of file app_adsiprog.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1617 of file app_adsiprog.c.

◆ adsi_exec()

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

Definition at line 1573 of file app_adsiprog.c.

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

Referenced by load_module().

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

◆ adsi_process()

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

Definition at line 1021 of file app_adsiprog.c.

References ARG_NUMBER, ARG_STRING, args, ast_copy_string(), ast_log, adsi_subscript::data, adsi_display::data, adsi_subscript::datalen, adsi_display::datalen, adsi_soft_key::defined, adsi_subscript::defined, adsi_script::desc, adsi_script::fdn, get_token(), getdisplaybyname(), geteventbyname(), getflagbyname(), getjustifybyname(), getkeybyname(), getstatebyname(), getsubbyname(), adsi_soft_key::id, adsi_subscript::id, adsi_display::id, adsi_subscript::ifdata, adsi_subscript::ifinscount, adsi_soft_key::initlen, adsi_subscript::inscount, adsi_script::key, LOG_WARNING, NULL, process_opcode(), process_returncode(), process_token(), adsi_soft_key::retstr, adsi_soft_key::retstrlen, adsi_script::sec, adsi_script::state, STATE_INIF, STATE_INKEY, STATE_INSUB, STATE_NORMAL, adsi_script::sub, tmp(), and adsi_script::ver.

Referenced by compile_script().

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

◆ adsi_prog()

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

Definition at line 1462 of file app_adsiprog.c.

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

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

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1617 of file app_adsiprog.c.

◆ clearcbone()

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

Definition at line 774 of file app_adsiprog.c.

References ast_log, get_token(), adsi_event::id, and LOG_WARNING.

775 {
776  char *tok = get_token(&args, script, lineno);
777 
778  if (tok)
779  ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
780 
781  buf[0] = id;
782  buf[1] = 0;
783  return 2;
784 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
enum queue_result id
Definition: app_queue.c:1510

◆ cleardisplay()

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

Definition at line 750 of file app_adsiprog.c.

References ast_log, get_token(), adsi_event::id, and LOG_WARNING.

751 {
752  char *tok = get_token(&args, script, lineno);
753 
754  if (tok)
755  ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
756 
757  buf[0] = id;
758  buf[1] = 0x00;
759  return 2;
760 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
enum queue_result id
Definition: app_queue.c:1510

◆ clearflag()

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

Definition at line 487 of file app_adsiprog.c.

References ARG_STRING, ast_log, get_token(), getflagbyname(), adsi_event::id, adsi_flag::id, LOG_WARNING, and process_token().

488 {
489  char *tok = get_token(&args, script, lineno);
490  struct adsi_flag *flag;
491  char sname[80];
492 
493  if (!tok) {
494  ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script);
495  return 0;
496  }
497 
498  if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
499  ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
500  return 0;
501  }
502 
503  if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
504  ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
505  return 0;
506  }
507 
508  buf[0] = id;
509  buf[1] = ((flag->id & 0x7) << 4);
510 
511  return 2;
512 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
#define ARG_STRING
Definition: app_adsiprog.c:128
long int flag
Definition: f2c.h:83
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
enum queue_result id
Definition: app_queue.c:1510
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:435

◆ cleartimer()

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

Definition at line 417 of file app_adsiprog.c.

References ast_log, get_token(), adsi_event::id, and LOG_WARNING.

418 {
419  char *tok = get_token(&args, script, lineno);
420 
421  if (tok)
422  ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
423 
424  buf[0] = id;
425 
426  /* For some reason the clear code is different slightly */
427  if (id == 7)
428  buf[1] = 0x10;
429  else
430  buf[1] = 0x00;
431 
432  return 2;
433 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
enum queue_result id
Definition: app_queue.c:1510

◆ compile_script()

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

Definition at line 1369 of file app_adsiprog.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, type, adsi_soft_key::vname, and adsi_subscript::vname.

Referenced by adsi_prog().

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

◆ digitcollect()

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

Definition at line 786 of file app_adsiprog.c.

References ast_log, get_token(), adsi_event::id, and LOG_WARNING.

787 {
788  char *tok = get_token(&args, script, lineno);
789 
790  if (tok)
791  ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
792 
793  buf[0] = id;
794  buf[1] = 0xf;
795  return 2;
796 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
enum queue_result id
Definition: app_queue.c:1510

◆ digitdirect()

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

Definition at line 762 of file app_adsiprog.c.

References ast_log, get_token(), adsi_event::id, and LOG_WARNING.

763 {
764  char *tok = get_token(&args, script, lineno);
765 
766  if (tok)
767  ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
768 
769  buf[0] = id;
770  buf[1] = 0x7;
771  return 2;
772 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
enum queue_result id
Definition: app_queue.c:1510

◆ get_token()

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

Definition at line 243 of file app_adsiprog.c.

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

Referenced by adsi_process(), clearcbone(), cleardisplay(), clearflag(), cleartimer(), digitcollect(), digitdirect(), goto_line(), goto_line_rel(), onevent(), process_opcode(), process_returncode(), send_delay(), send_dtmf(), set_state(), setflag(), showdisplay(), showkeys(), starttimer(), and subscript().

244 {
245  char *tmp = *buf, *keyword;
246  int quoted = 0;
247 
248  /* Advance past any white space */
249  while(*tmp && (*tmp < 33))
250  tmp++;
251  if (!*tmp)
252  return NULL;
253  keyword = tmp;
254  while(*tmp && ((*tmp > 32) || quoted)) {
255  if (*tmp == '\"') {
256  quoted = !quoted;
257  }
258  tmp++;
259  }
260  if (quoted) {
261  ast_log(LOG_WARNING, "Mismatched quotes at line %d of %s\n", lineno, script);
262  return NULL;
263  }
264  *tmp = '\0';
265  tmp++;
266  while(*tmp && (*tmp < 33))
267  tmp++;
268  /* Note where we left off */
269  *buf = tmp;
270  return keyword;
271 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42

◆ getdisplaybyname()

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

Definition at line 627 of file app_adsiprog.c.

References ast_copy_string(), ast_log, adsi_script::displays, adsi_display::id, LOG_WARNING, NULL, adsi_script::numdisplays, and adsi_display::vname.

Referenced by adsi_process(), and showdisplay().

628 {
629  int x;
630 
631  for (x = 0; x < state->numdisplays; x++) {
632  if (!strcasecmp(state->displays[x].vname, name))
633  return &state->displays[x];
634  }
635 
636  /* Return now if we're not allowed to create */
637  if (!create)
638  return NULL;
639 
640  if (state->numdisplays > 61) {
641  ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script);
642  return NULL;
643  }
644 
645  ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname));
646  state->displays[state->numdisplays].id = state->numdisplays + 1;
647  state->numdisplays++;
648 
649  return &state->displays[state->numdisplays-1];
650 }
char vname[40]
Definition: app_adsiprog.c:162
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
struct adsi_display displays[63]
Definition: app_adsiprog.c:178
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ geteventbyname()

static int geteventbyname ( char *  name)
static

Definition at line 536 of file app_adsiprog.c.

References ARRAY_LEN.

Referenced by adsi_process(), and onevent().

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

◆ getflagbyname()

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

Definition at line 435 of file app_adsiprog.c.

References ast_copy_string(), ast_log, adsi_script::flags, adsi_flag::id, LOG_WARNING, NULL, adsi_script::numflags, and adsi_flag::vname.

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

436 {
437  int x;
438 
439  for (x = 0; x < state->numflags; x++) {
440  if (!strcasecmp(state->flags[x].vname, name))
441  return &state->flags[x];
442  }
443 
444  /* Return now if we're not allowed to create */
445  if (!create)
446  return NULL;
447 
448  if (state->numflags > 6) {
449  ast_log(LOG_WARNING, "No more flag space at line %d of %s\n", lineno, script);
450  return NULL;
451  }
452 
453  ast_copy_string(state->flags[state->numflags].vname, name, sizeof(state->flags[state->numflags].vname));
454  state->flags[state->numflags].id = state->numflags + 1;
455  state->numflags++;
456 
457  return &state->flags[state->numflags-1];
458 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
char vname[40]
Definition: app_adsiprog.c:157
#define ast_log
Definition: astobj2.c:42
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
struct adsi_flag flags[7]
Definition: app_adsiprog.c:186

◆ getjustifybyname()

static int getjustifybyname ( char *  name)
static

Definition at line 548 of file app_adsiprog.c.

References ARRAY_LEN.

Referenced by adsi_process().

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

◆ getkeybyname()

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

Definition at line 560 of file app_adsiprog.c.

References ast_copy_string(), ast_log, adsi_soft_key::id, adsi_script::keys, LOG_WARNING, NULL, adsi_script::numkeys, and adsi_soft_key::vname.

Referenced by adsi_process(), and showkeys().

561 {
562  int x;
563 
564  for (x = 0; x < state->numkeys; x++) {
565  if (!strcasecmp(state->keys[x].vname, name))
566  return &state->keys[x];
567  }
568 
569  if (state->numkeys > 61) {
570  ast_log(LOG_WARNING, "No more key space at line %d of %s\n", lineno, script);
571  return NULL;
572  }
573 
574  ast_copy_string(state->keys[state->numkeys].vname, name, sizeof(state->keys[state->numkeys].vname));
575  state->keys[state->numkeys].id = state->numkeys + 2;
576  state->numkeys++;
577 
578  return &state->keys[state->numkeys-1];
579 }
#define LOG_WARNING
Definition: logger.h:274
struct adsi_soft_key keys[62]
Definition: app_adsiprog.c:182
#define NULL
Definition: resample.c:96
char vname[40]
Definition: app_adsiprog.c:132
#define ast_log
Definition: astobj2.c:42
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ getstatebyname()

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

Definition at line 602 of file app_adsiprog.c.

References ast_copy_string(), ast_log, adsi_state::id, LOG_WARNING, NULL, adsi_script::numstates, adsi_script::states, and adsi_state::vname.

Referenced by adsi_process(), and onevent().

603 {
604  int x;
605 
606  for (x = 0; x <state->numstates; x++) {
607  if (!strcasecmp(state->states[x].vname, name))
608  return &state->states[x];
609  }
610 
611  /* Return now if we're not allowed to create */
612  if (!create)
613  return NULL;
614 
615  if (state->numstates > 253) {
616  ast_log(LOG_WARNING, "No more state space at line %d of %s\n", lineno, script);
617  return NULL;
618  }
619 
620  ast_copy_string(state->states[state->numstates].vname, name, sizeof(state->states[state->numstates].vname));
621  state->states[state->numstates].id = state->numstates + 1;
622  state->numstates++;
623 
624  return &state->states[state->numstates-1];
625 }
#define LOG_WARNING
Definition: logger.h:274
struct adsi_state states[256]
Definition: app_adsiprog.c:180
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
char vname[40]
Definition: app_adsiprog.c:152
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ getsubbyname()

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

Definition at line 581 of file app_adsiprog.c.

References ast_copy_string(), ast_log, adsi_subscript::id, LOG_WARNING, NULL, adsi_script::numsubs, S_OR, adsi_script::subs, and adsi_subscript::vname.

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

582 {
583  int x;
584 
585  for (x = 0; x < state->numsubs; x++) {
586  if (!strcasecmp(state->subs[x].vname, name))
587  return &state->subs[x];
588  }
589 
590  if (state->numsubs > 127) {
591  ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, S_OR(script, "unknown"));
592  return NULL;
593  }
594 
595  ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname));
596  state->subs[state->numsubs].id = state->numsubs;
597  state->numsubs++;
598 
599  return &state->subs[state->numsubs-1];
600 }
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:184
#define ast_log
Definition: astobj2.c:42
char vname[40]
Definition: app_adsiprog.c:141
static const char name[]
Definition: cdr_mysql.c:74
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79

◆ goto_line()

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

Definition at line 305 of file app_adsiprog.c.

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

306 {
307  char *page = get_token(&args, script, lineno);
308  char *gline = get_token(&args, script, lineno);
309  int line;
310  unsigned char cmd;
311 
312  if (!page || !gline) {
313  ast_log(LOG_WARNING, "Expecting page and line number for GOTOLINE at line %d of %s\n", lineno, script);
314  return 0;
315  }
316 
317  if (!strcasecmp(page, "INFO"))
318  cmd = 0;
319  else if (!strcasecmp(page, "COMM"))
320  cmd = 0x80;
321  else {
322  ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got '%s' at line %d of %s\n", page, lineno, script);
323  return 0;
324  }
325 
326  if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
327  ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
328  return 0;
329  }
330 
331  cmd |= line;
332  buf[0] = 0x8b;
333  buf[1] = cmd;
334 
335  return 2;
336 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196

◆ goto_line_rel()

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

Definition at line 338 of file app_adsiprog.c.

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

339 {
340  char *dir = get_token(&args, script, lineno);
341  char *gline = get_token(&args, script, lineno);
342  int line;
343  unsigned char cmd;
344 
345  if (!dir || !gline) {
346  ast_log(LOG_WARNING, "Expecting direction and number of lines for GOTOLINEREL at line %d of %s\n", lineno, script);
347  return 0;
348  }
349 
350  if (!strcasecmp(dir, "UP"))
351  cmd = 0;
352  else if (!strcasecmp(dir, "DOWN"))
353  cmd = 0x20;
354  else {
355  ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script);
356  return 0;
357  }
358 
359  if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
360  ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
361  return 0;
362  }
363 
364  cmd |= line;
365  buf[0] = 0x8c;
366  buf[1] = cmd;
367 
368  return 2;
369 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196

◆ load_module()

static int load_module ( void  )
static

Load the module.

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

Definition at line 1605 of file app_adsiprog.c.

References adsi_exec(), app, AST_MODFLAG_DEFAULT, AST_MODULE_INFO(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_DEPRECATED, ast_register_application_xml, ASTERISK_GPL_KEY, and unload_module().

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

◆ onevent()

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

Definition at line 823 of file app_adsiprog.c.

References ARG_STRING, ast_log, get_token(), geteventbyname(), getstatebyname(), getsubbyname(), adsi_subscript::id, LOG_WARNING, NULL, process_token(), and sub.

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

◆ process_opcode()

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

Definition at line 984 of file app_adsiprog.c.

References adsi_key_cmd::add_args, ARRAY_LEN, ast_log, adsi_subscript::data, adsi_subscript::datalen, get_token(), adsi_subscript::id, adsi_key_cmd::id, adsi_subscript::inscount, LOG_WARNING, max, MAX_MAIN_LEN, MAX_SUB_LEN, adsi_event::name, and adsi_subscript::vname.

Referenced by adsi_process().

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

◆ process_returncode()

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

Definition at line 955 of file app_adsiprog.c.

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

Referenced by adsi_process().

956 {
957  int x, res;
958  char *unused;
959 
960  for (x = 0; x < ARRAY_LEN(kcmds); x++) {
961  if ((kcmds[x].id > -1) && !strcasecmp(kcmds[x].name, code)) {
962  if (kcmds[x].add_args) {
963  res = kcmds[x].add_args(key->retstr + key->retstrlen,
964  code, kcmds[x].id, args, state, script, lineno);
965  if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
966  key->retstrlen += res;
967  else
968  ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script);
969  } else {
970  if ((unused = get_token(&args, script, lineno)))
971  ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused);
972  if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) {
973  key->retstr[key->retstrlen] = kcmds[x].id;
974  key->retstrlen++;
975  } else
976  ast_log(LOG_WARNING, "No space for '%s' code in key '%s' at line %d of %s\n", kcmds[x].name, key->vname, lineno, script);
977  }
978  return 0;
979  }
980  }
981  return -1;
982 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:274
#define MAX_RET_CODE
Definition: app_adsiprog.c:124
char retstr[80]
Definition: app_adsiprog.c:137
const char * args
char vname[40]
Definition: app_adsiprog.c:132
#define ast_log
Definition: astobj2.c:42
int(* add_args)(char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:890
static const char name[]
Definition: cdr_mysql.c:74
static const struct adsi_key_cmd kcmds[]
Definition: app_adsiprog.c:893

◆ process_token()

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

Definition at line 196 of file app_adsiprog.c.

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

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

◆ send_delay()

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

Definition at line 371 of file app_adsiprog.c.

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

372 {
373  char *gtime = get_token(&args, script, lineno);
374  int ms;
375 
376  if (!gtime) {
377  ast_log(LOG_WARNING, "Expecting number of milliseconds to wait at line %d of %s\n", lineno, script);
378  return 0;
379  }
380 
381  if (process_token(&ms, gtime, sizeof(ms), ARG_NUMBER)) {
382  ast_log(LOG_WARNING, "Invalid delay milliseconds '%s' at line %d of %s\n", gtime, lineno, script);
383  return 0;
384  }
385 
386  buf[0] = 0x90;
387 
388  if (id == 11)
389  buf[1] = ms / 100;
390  else
391  buf[1] = ms / 10;
392 
393  return 2;
394 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196

◆ send_dtmf()

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

Definition at line 275 of file app_adsiprog.c.

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

276 {
277  char dtmfstr[80], *a;
278  int bytes = 0;
279 
280  if (!(a = get_token(&args, script, lineno))) {
281  ast_log(LOG_WARNING, "Expecting something to send for SENDDTMF at line %d of %s\n", lineno, script);
282  return 0;
283  }
284 
285  if (process_token(dtmfstr, a, sizeof(dtmfstr) - 1, ARG_STRING)) {
286  ast_log(LOG_WARNING, "Invalid token for SENDDTMF at line %d of %s\n", lineno, script);
287  return 0;
288  }
289 
290  a = dtmfstr;
291 
292  while (*a) {
293  if (strchr(validdtmf, *a)) {
294  *buf = *a;
295  buf++;
296  bytes++;
297  } else
298  ast_log(LOG_WARNING, "'%c' is not a valid DTMF tone at line %d of %s\n", *a, lineno, script);
299  a++;
300  }
301 
302  return bytes;
303 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
static char * validdtmf
Definition: app_adsiprog.c:273
#define ARG_STRING
Definition: app_adsiprog.c:128
static const struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:20613
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
static struct test_val a

◆ set_state()

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

Definition at line 396 of file app_adsiprog.c.

References ARG_NUMBER, ast_log, get_token(), adsi_event::id, LOG_WARNING, process_token(), and state.

397 {
398  char *gstate = get_token(&args, script, lineno);
399  int state;
400 
401  if (!gstate) {
402  ast_log(LOG_WARNING, "Expecting state number at line %d of %s\n", lineno, script);
403  return 0;
404  }
405 
406  if (process_token(&state, gstate, sizeof(state), ARG_NUMBER)) {
407  ast_log(LOG_WARNING, "Invalid state number '%s' at line %d of %s\n", gstate, lineno, script);
408  return 0;
409  }
410 
411  buf[0] = id;
412  buf[1] = state;
413 
414  return 2;
415 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
enum sip_cc_notify_state state
Definition: chan_sip.c:956
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
enum queue_result id
Definition: app_queue.c:1510

◆ setflag()

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

Definition at line 460 of file app_adsiprog.c.

References ARG_STRING, ast_log, get_token(), getflagbyname(), adsi_event::id, adsi_flag::id, LOG_WARNING, and process_token().

461 {
462  char *tok = get_token(&args, script, lineno);
463  char sname[80];
464  struct adsi_flag *flag;
465 
466  if (!tok) {
467  ast_log(LOG_WARNING, "Setting flag requires a flag number at line %d of %s\n", lineno, script);
468  return 0;
469  }
470 
471  if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
472  ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
473  return 0;
474  }
475 
476  if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
477  ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
478  return 0;
479  }
480 
481  buf[0] = id;
482  buf[1] = ((flag->id & 0x7) << 4) | 1;
483 
484  return 2;
485 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
#define ARG_STRING
Definition: app_adsiprog.c:128
long int flag
Definition: f2c.h:83
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
enum queue_result id
Definition: app_queue.c:1510
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:435

◆ showdisplay()

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

Definition at line 699 of file app_adsiprog.c.

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

700 {
701  char *tok, dispname[80];
702  int line = 0, flag = 0, cmd = 3;
703  struct adsi_display *disp;
704 
705  /* Get display */
706  if (!(tok = get_token(&args, script, lineno)) || process_token(dispname, tok, sizeof(dispname) - 1, ARG_STRING)) {
707  ast_log(LOG_WARNING, "Invalid display name: %s at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
708  return 0;
709  }
710 
711  if (!(disp = getdisplaybyname(state, dispname, script, lineno, 0))) {
712  ast_log(LOG_WARNING, "Display '%s' is undefined at line %d of %s\n", dispname, lineno, script);
713  return 0;
714  }
715 
716  if (!(tok = get_token(&args, script, lineno)) || strcasecmp(tok, "AT")) {
717  ast_log(LOG_WARNING, "Missing token 'AT' at line %d of %s\n", lineno, script);
718  return 0;
719  }
720 
721  /* Get line number */
722  if (!(tok = get_token(&args, script, lineno)) || process_token(&line, tok, sizeof(line), ARG_NUMBER)) {
723  ast_log(LOG_WARNING, "Invalid line: '%s' at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
724  return 0;
725  }
726 
727  if ((tok = get_token(&args, script, lineno)) && !strcasecmp(tok, "NOUPDATE")) {
728  cmd = 1;
729  tok = get_token(&args, script, lineno);
730  }
731 
732  if (tok && !strcasecmp(tok, "UNLESS")) {
733  /* Check for trailing UNLESS flag */
734  if (!(tok = get_token(&args, script, lineno)))
735  ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
736  else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER))
737  ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script);
738 
739  if ((tok = get_token(&args, script, lineno)))
740  ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
741  }
742 
743  buf[0] = id;
744  buf[1] = (cmd << 6) | (disp->id & 0x3f);
745  buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
746 
747  return 3;
748 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
#define ARG_STRING
Definition: app_adsiprog.c:128
static struct adsi_display * getdisplaybyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:627
long int flag
Definition: f2c.h:83
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
enum queue_result id
Definition: app_queue.c:1510

◆ showkeys()

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

Definition at line 652 of file app_adsiprog.c.

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

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

◆ starttimer()

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

Definition at line 514 of file app_adsiprog.c.

References ARG_NUMBER, ast_log, get_token(), adsi_event::id, LOG_WARNING, and process_token().

515 {
516  char *tok = get_token(&args, script, lineno);
517  int secs;
518 
519  if (!tok) {
520  ast_log(LOG_WARNING, "Missing number of seconds at line %d of %s\n", lineno, script);
521  return 0;
522  }
523 
524  if (process_token(&secs, tok, sizeof(secs), ARG_NUMBER)) {
525  ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
526  return 0;
527  }
528 
529  buf[0] = id;
530  buf[1] = 0x1;
531  buf[2] = secs;
532 
533  return 3;
534 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ARG_NUMBER
Definition: app_adsiprog.c:129
const char * args
#define ast_log
Definition: astobj2.c:42
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196
enum queue_result id
Definition: app_queue.c:1510

◆ subscript()

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

Definition at line 798 of file app_adsiprog.c.

References ARG_STRING, ast_log, get_token(), getsubbyname(), adsi_subscript::id, LOG_WARNING, process_token(), and sub.

799 {
800  char *tok = get_token(&args, script, lineno);
801  char subscr[80];
802  struct adsi_subscript *sub;
803 
804  if (!tok) {
805  ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
806  return 0;
807  }
808 
809  if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
810  ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
811  return 0;
812  }
813 
814  if (!(sub = getsubbyname(state, subscr, script, lineno)))
815  return 0;
816 
817  buf[0] = 0x9d;
818  buf[1] = sub->id;
819 
820  return 2;
821 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:243
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
const char * args
#define ast_log
Definition: astobj2.c:42
#define ARG_STRING
Definition: app_adsiprog.c:128
static struct adsi_subscript * getsubbyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:581
struct stasis_forward * sub
Definition: res_corosync.c:240
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:196

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1590 of file app_adsiprog.c.

References app, and ast_unregister_application().

Referenced by load_module().

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

Variable Documentation

◆ __mod_info

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

Definition at line 1617 of file app_adsiprog.c.

◆ app

const char app[] = "ADSIProg"
static

Definition at line 56 of file app_adsiprog.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1617 of file app_adsiprog.c.

◆ events

const struct adsi_event events[]
static

◆ justify

const struct adsi_event justify[]
static

Definition at line 112 of file app_adsiprog.c.

Referenced by cpeid_setstatus().

◆ kcmds

const struct adsi_key_cmd kcmds[]
static

Definition at line 893 of file app_adsiprog.c.

◆ opcmds

const struct adsi_key_cmd opcmds[]
static

Definition at line 935 of file app_adsiprog.c.

◆ validdtmf

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

Definition at line 273 of file app_adsiprog.c.

Referenced by send_dtmf().