Wed Jan 8 2020 09:49:52

Asterisk developer's documentation


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)
 
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)
 
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .nonoptreq = "res_adsi", }
 
static const char app [] = "ADSIProg"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct adsi_event events []
 
static struct adsi_event justify []
 
static struct adsi_key_cmd kcmds []
 
static 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

#define ARG_NUMBER   (1 << 1)
#define ARG_STRING   (1 << 0)
#define MAX_MAIN_LEN   1600

Definition at line 119 of file app_adsiprog.c.

Referenced by process_opcode().

#define MAX_RET_CODE   20

Definition at line 117 of file app_adsiprog.c.

Referenced by process_returncode().

#define MAX_SUB_LEN   255

Definition at line 118 of file app_adsiprog.c.

Referenced by process_opcode().

#define STATE_INIF   3

Definition at line 115 of file app_adsiprog.c.

Referenced by adsi_process().

#define STATE_INKEY   1

Definition at line 113 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_INSUB   2

Definition at line 114 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

#define STATE_NORMAL   0

Definition at line 112 of file app_adsiprog.c.

Referenced by adsi_process(), and compile_script().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 1599 of file app_adsiprog.c.

static void __unreg_module ( void  )
static

Definition at line 1599 of file app_adsiprog.c.

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

Definition at line 1566 of file app_adsiprog.c.

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

Referenced by load_module().

1567 {
1568  int res = 0;
1569 
1570  if (ast_strlen_zero(data))
1571  data = "asterisk.adsi";
1572 
1573  if (!ast_adsi_available(chan)) {
1574  ast_verb(3, "ADSI Unavailable on CPE. Not bothering to try.\n");
1575  } else {
1576  ast_verb(3, "ADSI Available on CPE. Attempting Upload.\n");
1577  res = adsi_prog(chan, data);
1578  }
1579 
1580  return res;
1581 }
static int adsi_prog(struct ast_channel *chan, const char *script)
#define ast_verb(level,...)
Definition: logger.h:243
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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_process ( struct adsi_script state,
char *  buf,
const char *  script,
int  lineno 
)
static

Definition at line 1014 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, process_opcode(), process_returncode(), process_token(), adsi_soft_key::retstr, adsi_soft_key::retstrlen, adsi_script::sec, adsi_script::state, STATE_INIF, STATE_INKEY, STATE_INSUB, STATE_NORMAL, adsi_script::sub, and adsi_script::ver.

Referenced by compile_script().

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

Definition at line 1455 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_free, ast_log(), ast_verb, 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, ast_channel::name, 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().

1456 {
1457  struct adsi_script *scr;
1458  int x, bytes;
1459  unsigned char buf[1024];
1460 
1461  if (!(scr = compile_script(script)))
1462  return -1;
1463 
1464  /* Start an empty ADSI Session */
1465  if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
1466  return -1;
1467 
1468  /* Now begin the download attempt */
1469  if (ast_adsi_begin_download(chan, scr->desc, scr->fdn, scr->sec, scr->ver)) {
1470  /* User rejected us for some reason */
1471  ast_verb(3, "User rejected download attempt\n");
1472  ast_log(LOG_NOTICE, "User rejected download on channel %s\n", chan->name);
1473  ast_free(scr);
1474  return -1;
1475  }
1476 
1477  bytes = 0;
1478  /* Start with key definitions */
1479  for (x = 0; x < scr->numkeys; x++) {
1480  if (bytes + scr->keys[x].retstrlen > 253) {
1481  /* Send what we've collected so far */
1482  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1483  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1484  return -1;
1485  }
1486  bytes =0;
1487  }
1488  memcpy(buf + bytes, scr->keys[x].retstr, scr->keys[x].retstrlen);
1489  bytes += scr->keys[x].retstrlen;
1490 #ifdef DUMP_MESSAGES
1491  dump_message("Key", scr->keys[x].vname, scr->keys[x].retstr, scr->keys[x].retstrlen);
1492 #endif
1493  }
1494  if (bytes) {
1495  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1496  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1497  return -1;
1498  }
1499  }
1500 
1501  bytes = 0;
1502  /* Continue with the display messages */
1503  for (x = 0; x < scr->numdisplays; x++) {
1504  if (bytes + scr->displays[x].datalen > 253) {
1505  /* Send what we've collected so far */
1506  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1507  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1508  return -1;
1509  }
1510  bytes =0;
1511  }
1512  memcpy(buf + bytes, scr->displays[x].data, scr->displays[x].datalen);
1513  bytes += scr->displays[x].datalen;
1514 #ifdef DUMP_MESSAGES
1515  dump_message("Display", scr->displays[x].vname, scr->displays[x].data, scr->displays[x].datalen);
1516 #endif
1517  }
1518  if (bytes) {
1519  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1520  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1521  return -1;
1522  }
1523  }
1524 
1525  bytes = 0;
1526  /* Send subroutines */
1527  for (x = 0; x < scr->numsubs; x++) {
1528  if (bytes + scr->subs[x].datalen > 253) {
1529  /* Send what we've collected so far */
1530  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1531  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1532  return -1;
1533  }
1534  bytes =0;
1535  }
1536  memcpy(buf + bytes, scr->subs[x].data, scr->subs[x].datalen);
1537  bytes += scr->subs[x].datalen;
1538 #ifdef DUMP_MESSAGES
1539  dump_message("Sub", scr->subs[x].vname, scr->subs[x].data, scr->subs[x].datalen);
1540 #endif
1541  }
1542  if (bytes) {
1543  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DOWNLOAD)) {
1544  ast_log(LOG_WARNING, "Unable to send chunk ending at %d\n", x);
1545  return -1;
1546  }
1547  }
1548 
1549  bytes = 0;
1550  bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
1551  bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
1552  if (ast_adsi_transmit_message(chan, buf, bytes, ADSI_MSG_DISPLAY) < 0)
1553  return -1;
1554  if (ast_adsi_end_download(chan)) {
1555  /* Download failed for some reason */
1556  ast_verb(3, "Download attempt failed\n");
1557  ast_log(LOG_NOTICE, "Download failed on %s\n", chan->name);
1558  ast_free(scr);
1559  return -1;
1560  }
1561  ast_free(scr);
1563  return 0;
1564 }
#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:157
char vname[40]
Definition: app_adsiprog.c:155
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define LOG_WARNING
Definition: logger.h:144
unsigned char sec[5]
Definition: app_adsiprog.c:182
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:175
#define ADSI_JUST_LEFT
Definition: adsi.h:112
char retstr[80]
Definition: app_adsiprog.c:130
char desc[19]
Definition: app_adsiprog.c:183
#define ast_verb(level,...)
Definition: logger.h:243
char vname[40]
Definition: app_adsiprog.c:125
unsigned char fdn[5]
Definition: app_adsiprog.c:184
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:177
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:171
char vname[40]
Definition: app_adsiprog.c:134
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:141
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_free(a)
Definition: astmm.h:97
int ast_adsi_end_download(struct ast_channel *chan)
Definition: adsi.c:43
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
int ast_adsi_unload_session(struct ast_channel *chan)
Definition: adsi.c:87
static int clearcbone ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 767 of file app_adsiprog.c.

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

768 {
769  char *tok = get_token(&args, script, lineno);
770 
771  if (tok)
772  ast_log(LOG_WARNING, "CLEARCB1 requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
773 
774  buf[0] = id;
775  buf[1] = 0;
776  return 2;
777 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum queue_result id
Definition: app_queue.c:1090
static int cleardisplay ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 743 of file app_adsiprog.c.

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

744 {
745  char *tok = get_token(&args, script, lineno);
746 
747  if (tok)
748  ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
749 
750  buf[0] = id;
751  buf[1] = 0x00;
752  return 2;
753 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum queue_result id
Definition: app_queue.c:1090
static int clearflag ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 480 of file app_adsiprog.c.

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

481 {
482  char *tok = get_token(&args, script, lineno);
483  struct adsi_flag *flag;
484  char sname[80];
485 
486  if (!tok) {
487  ast_log(LOG_WARNING, "Clearing flag requires a flag number at line %d of %s\n", lineno, script);
488  return 0;
489  }
490 
491  if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
492  ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
493  return 0;
494  }
495 
496  if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
497  ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
498  return 0;
499  }
500 
501  buf[0] = id;
502  buf[1] = ((flag->id & 0x7) << 4);
503 
504  return 2;
505 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:428
static int cleartimer ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 410 of file app_adsiprog.c.

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

411 {
412  char *tok = get_token(&args, script, lineno);
413 
414  if (tok)
415  ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
416 
417  buf[0] = id;
418 
419  /* For some reason the clear code is different slightly */
420  if (id == 7)
421  buf[1] = 0x10;
422  else
423  buf[1] = 0x00;
424 
425  return 2;
426 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum queue_result id
Definition: app_queue.c:1090
static struct adsi_script* compile_script ( const char *  script)
static

Definition at line 1362 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(), adsi_subscript::data, adsi_soft_key::defined, adsi_subscript::defined, f, getsubbyname(), adsi_script::keys, LOG_WARNING, 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().

1363 {
1364  FILE *f;
1365  char fn[256], buf[256], *c;
1366  int lineno = 0, x, err;
1367  struct adsi_script *scr;
1368 
1369  if (script[0] == '/')
1370  ast_copy_string(fn, script, sizeof(fn));
1371  else
1372  snprintf(fn, sizeof(fn), "%s/%s", ast_config_AST_CONFIG_DIR, script);
1373 
1374  if (!(f = fopen(fn, "r"))) {
1375  ast_log(LOG_WARNING, "Can't open file '%s'\n", fn);
1376  return NULL;
1377  }
1378 
1379  if (!(scr = ast_calloc(1, sizeof(*scr)))) {
1380  fclose(f);
1381  return NULL;
1382  }
1383 
1384  /* Create "main" as first subroutine */
1385  getsubbyname(scr, "main", NULL, 0);
1386  while (!feof(f)) {
1387  if (!fgets(buf, sizeof(buf), f)) {
1388  continue;
1389  }
1390  if (!feof(f)) {
1391  lineno++;
1392  /* Trim off trailing return */
1393  buf[strlen(buf) - 1] = '\0';
1394  /* Strip comments */
1395  if ((c = strchr(buf, ';')))
1396  *c = '\0';
1397  if (!ast_strlen_zero(buf))
1398  adsi_process(scr, buf, script, lineno);
1399  }
1400  }
1401  fclose(f);
1402  /* Make sure we're in the main routine again */
1403  switch(scr->state) {
1404  case STATE_NORMAL:
1405  break;
1406  case STATE_INSUB:
1407  ast_log(LOG_WARNING, "Missing ENDSUB at end of file %s\n", script);
1408  ast_free(scr);
1409  return NULL;
1410  case STATE_INKEY:
1411  ast_log(LOG_WARNING, "Missing ENDKEY at end of file %s\n", script);
1412  ast_free(scr);
1413  return NULL;
1414  }
1415  err = 0;
1416 
1417  /* Resolve all keys and record their lengths */
1418  for (x = 0; x < scr->numkeys; x++) {
1419  if (!scr->keys[x].defined) {
1420  ast_log(LOG_WARNING, "Key '%s' referenced but never defined in file %s\n", scr->keys[x].vname, fn);
1421  err++;
1422  }
1423  }
1424 
1425  /* Resolve all subs */
1426  for (x = 0; x < scr->numsubs; x++) {
1427  if (!scr->subs[x].defined) {
1428  ast_log(LOG_WARNING, "Subscript '%s' referenced but never defined in file %s\n", scr->subs[x].vname, fn);
1429  err++;
1430  }
1431  if (x == (scr->numsubs - 1)) {
1432  /* Clear out extension bit on last message */
1433  scr->subs[x].data[2] = 0x80;
1434  }
1435  }
1436 
1437  if (err) {
1438  ast_free(scr);
1439  return NULL;
1440  }
1441  return scr;
1442 }
#define LOG_WARNING
Definition: logger.h:144
struct adsi_soft_key keys[62]
Definition: app_adsiprog.c:175
char vname[40]
Definition: app_adsiprog.c:125
#define STATE_INSUB
Definition: app_adsiprog.c:114
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:177
#define STATE_INKEY
Definition: app_adsiprog.c:113
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char vname[40]
Definition: app_adsiprog.c:134
static struct adsi_subscript * getsubbyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:574
char data[2048]
Definition: app_adsiprog.c:141
const char * ast_config_AST_CONFIG_DIR
Definition: asterisk.c:256
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static struct ast_format f[]
Definition: format_g726.c:181
#define STATE_NORMAL
Definition: app_adsiprog.c:112
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int adsi_process(struct adsi_script *state, char *buf, const char *script, int lineno)
static int digitcollect ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 779 of file app_adsiprog.c.

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

780 {
781  char *tok = get_token(&args, script, lineno);
782 
783  if (tok)
784  ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
785 
786  buf[0] = id;
787  buf[1] = 0xf;
788  return 2;
789 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum queue_result id
Definition: app_queue.c:1090
static int digitdirect ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 755 of file app_adsiprog.c.

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

756 {
757  char *tok = get_token(&args, script, lineno);
758 
759  if (tok)
760  ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
761 
762  buf[0] = id;
763  buf[1] = 0x7;
764  return 2;
765 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
enum queue_result id
Definition: app_queue.c:1090
static char* get_token ( char **  buf,
const char *  script,
int  lineno 
)
static

Definition at line 236 of file app_adsiprog.c.

References ast_log(), and LOG_WARNING.

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

237 {
238  char *tmp = *buf, *keyword;
239  int quoted = 0;
240 
241  /* Advance past any white space */
242  while(*tmp && (*tmp < 33))
243  tmp++;
244  if (!*tmp)
245  return NULL;
246  keyword = tmp;
247  while(*tmp && ((*tmp > 32) || quoted)) {
248  if (*tmp == '\"') {
249  quoted = !quoted;
250  }
251  tmp++;
252  }
253  if (quoted) {
254  ast_log(LOG_WARNING, "Mismatched quotes at line %d of %s\n", lineno, script);
255  return NULL;
256  }
257  *tmp = '\0';
258  tmp++;
259  while(*tmp && (*tmp < 33))
260  tmp++;
261  /* Note where we left off */
262  *buf = tmp;
263  return keyword;
264 }
#define LOG_WARNING
Definition: logger.h:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct adsi_display* getdisplaybyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 620 of file app_adsiprog.c.

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

Referenced by adsi_process(), and showdisplay().

621 {
622  int x;
623 
624  for (x = 0; x < state->numdisplays; x++) {
625  if (!strcasecmp(state->displays[x].vname, name))
626  return &state->displays[x];
627  }
628 
629  /* Return now if we're not allowed to create */
630  if (!create)
631  return NULL;
632 
633  if (state->numdisplays > 61) {
634  ast_log(LOG_WARNING, "No more display space at line %d of %s\n", lineno, script);
635  return NULL;
636  }
637 
638  ast_copy_string(state->displays[state->numdisplays].vname, name, sizeof(state->displays[state->numdisplays].vname));
639  state->displays[state->numdisplays].id = state->numdisplays + 1;
640  state->numdisplays++;
641 
642  return &state->displays[state->numdisplays-1];
643 }
char vname[40]
Definition: app_adsiprog.c:155
#define LOG_WARNING
Definition: logger.h:144
struct adsi_display displays[63]
Definition: app_adsiprog.c:171
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int geteventbyname ( char *  name)
static

Definition at line 529 of file app_adsiprog.c.

References ARRAY_LEN.

Referenced by adsi_process(), and onevent().

530 {
531  int x;
532 
533  for (x = 0; x < ARRAY_LEN(events); x++) {
534  if (!strcasecmp(events[x].name, name))
535  return events[x].id;
536  }
537 
538  return 0;
539 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const char name[]
static struct adsi_event events[]
Definition: app_adsiprog.c:78
static struct adsi_flag* getflagbyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 428 of file app_adsiprog.c.

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

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

429 {
430  int x;
431 
432  for (x = 0; x < state->numflags; x++) {
433  if (!strcasecmp(state->flags[x].vname, name))
434  return &state->flags[x];
435  }
436 
437  /* Return now if we're not allowed to create */
438  if (!create)
439  return NULL;
440 
441  if (state->numflags > 6) {
442  ast_log(LOG_WARNING, "No more flag space at line %d of %s\n", lineno, script);
443  return NULL;
444  }
445 
446  ast_copy_string(state->flags[state->numflags].vname, name, sizeof(state->flags[state->numflags].vname));
447  state->flags[state->numflags].id = state->numflags + 1;
448  state->numflags++;
449 
450  return &state->flags[state->numflags-1];
451 }
#define LOG_WARNING
Definition: logger.h:144
char vname[40]
Definition: app_adsiprog.c:150
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct adsi_flag flags[7]
Definition: app_adsiprog.c:179
static int getjustifybyname ( char *  name)
static

Definition at line 541 of file app_adsiprog.c.

References ARRAY_LEN.

Referenced by adsi_process().

542 {
543  int x;
544 
545  for (x = 0; x < ARRAY_LEN(justify); x++) {
546  if (!strcasecmp(justify[x].name, name))
547  return justify[x].id;
548  }
549 
550  return -1;
551 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static struct adsi_event justify[]
Definition: app_adsiprog.c:105
static const char name[]
static struct adsi_soft_key* getkeybyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno 
)
static

Definition at line 553 of file app_adsiprog.c.

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

Referenced by adsi_process(), and showkeys().

554 {
555  int x;
556 
557  for (x = 0; x < state->numkeys; x++) {
558  if (!strcasecmp(state->keys[x].vname, name))
559  return &state->keys[x];
560  }
561 
562  if (state->numkeys > 61) {
563  ast_log(LOG_WARNING, "No more key space at line %d of %s\n", lineno, script);
564  return NULL;
565  }
566 
567  ast_copy_string(state->keys[state->numkeys].vname, name, sizeof(state->keys[state->numkeys].vname));
568  state->keys[state->numkeys].id = state->numkeys + 2;
569  state->numkeys++;
570 
571  return &state->keys[state->numkeys-1];
572 }
#define LOG_WARNING
Definition: logger.h:144
struct adsi_soft_key keys[62]
Definition: app_adsiprog.c:175
char vname[40]
Definition: app_adsiprog.c:125
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct adsi_state* getstatebyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno,
int  create 
)
static

Definition at line 595 of file app_adsiprog.c.

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

Referenced by adsi_process(), and onevent().

596 {
597  int x;
598 
599  for (x = 0; x <state->numstates; x++) {
600  if (!strcasecmp(state->states[x].vname, name))
601  return &state->states[x];
602  }
603 
604  /* Return now if we're not allowed to create */
605  if (!create)
606  return NULL;
607 
608  if (state->numstates > 253) {
609  ast_log(LOG_WARNING, "No more state space at line %d of %s\n", lineno, script);
610  return NULL;
611  }
612 
613  ast_copy_string(state->states[state->numstates].vname, name, sizeof(state->states[state->numstates].vname));
614  state->states[state->numstates].id = state->numstates + 1;
615  state->numstates++;
616 
617  return &state->states[state->numstates-1];
618 }
#define LOG_WARNING
Definition: logger.h:144
struct adsi_state states[256]
Definition: app_adsiprog.c:173
char vname[40]
Definition: app_adsiprog.c:145
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static struct adsi_subscript* getsubbyname ( struct adsi_script state,
char *  name,
const char *  script,
int  lineno 
)
static

Definition at line 574 of file app_adsiprog.c.

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

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

575 {
576  int x;
577 
578  for (x = 0; x < state->numsubs; x++) {
579  if (!strcasecmp(state->subs[x].vname, name))
580  return &state->subs[x];
581  }
582 
583  if (state->numsubs > 127) {
584  ast_log(LOG_WARNING, "No more subscript space at line %d of %s\n", lineno, script);
585  return NULL;
586  }
587 
588  ast_copy_string(state->subs[state->numsubs].vname, name, sizeof(state->subs[state->numsubs].vname));
589  state->subs[state->numsubs].id = state->numsubs;
590  state->numsubs++;
591 
592  return &state->subs[state->numsubs-1];
593 }
#define LOG_WARNING
Definition: logger.h:144
struct adsi_subscript subs[128]
Definition: app_adsiprog.c:177
char vname[40]
Definition: app_adsiprog.c:134
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
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 298 of file app_adsiprog.c.

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

299 {
300  char *page = get_token(&args, script, lineno);
301  char *gline = get_token(&args, script, lineno);
302  int line;
303  unsigned char cmd;
304 
305  if (!page || !gline) {
306  ast_log(LOG_WARNING, "Expecting page and line number for GOTOLINE at line %d of %s\n", lineno, script);
307  return 0;
308  }
309 
310  if (!strcasecmp(page, "INFO"))
311  cmd = 0;
312  else if (!strcasecmp(page, "COMM"))
313  cmd = 0x80;
314  else {
315  ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got got '%s' at line %d of %s\n", page, lineno, script);
316  return 0;
317  }
318 
319  if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
320  ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
321  return 0;
322  }
323 
324  cmd |= line;
325  buf[0] = 0x8b;
326  buf[1] = cmd;
327 
328  return 2;
329 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
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 331 of file app_adsiprog.c.

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

332 {
333  char *dir = get_token(&args, script, lineno);
334  char *gline = get_token(&args, script, lineno);
335  int line;
336  unsigned char cmd;
337 
338  if (!dir || !gline) {
339  ast_log(LOG_WARNING, "Expecting direction and number of lines for GOTOLINEREL at line %d of %s\n", lineno, script);
340  return 0;
341  }
342 
343  if (!strcasecmp(dir, "UP"))
344  cmd = 0;
345  else if (!strcasecmp(dir, "DOWN"))
346  cmd = 0x20;
347  else {
348  ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script);
349  return 0;
350  }
351 
352  if (process_token(&line, gline, sizeof(line), ARG_NUMBER)) {
353  ast_log(LOG_WARNING, "Invalid line number '%s' at line %d of %s\n", gline, lineno, script);
354  return 0;
355  }
356 
357  cmd |= line;
358  buf[0] = 0x8c;
359  buf[1] = cmd;
360 
361  return 2;
362 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
static int load_module ( void  )
static

Definition at line 1588 of file app_adsiprog.c.

References adsi_exec(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, and ast_register_application_xml.

1589 {
1591  return AST_MODULE_LOAD_FAILURE;
1592  return AST_MODULE_LOAD_SUCCESS;
1593 }
static const char app[]
Definition: app_adsiprog.c:49
static int adsi_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int onevent ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 816 of file app_adsiprog.c.

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

817 {
818  char *tok = get_token(&args, script, lineno);
819  char subscr[80], sname[80];
820  int sawin = 0, event, snums[8], scnt = 0, x;
821  struct adsi_subscript *sub;
822 
823  if (!tok) {
824  ast_log(LOG_WARNING, "Missing event for 'ONEVENT' at line %d of %s\n", lineno, script);
825  return 0;
826  }
827 
828  if ((event = geteventbyname(tok)) < 1) {
829  ast_log(LOG_WARNING, "'%s' is not a valid event name, at line %d of %s\n", args, lineno, script);
830  return 0;
831  }
832 
833  tok = get_token(&args, script, lineno);
834  while ((!sawin && !strcasecmp(tok, "IN")) || (sawin && !strcasecmp(tok, "OR"))) {
835  sawin = 1;
836  if (scnt > 7) {
837  ast_log(LOG_WARNING, "No more than 8 states may be specified for inclusion at line %d of %s\n", lineno, script);
838  return 0;
839  }
840  /* Process 'in' things */
841  tok = get_token(&args, script, lineno);
842  if (process_token(sname, tok, sizeof(sname), ARG_STRING)) {
843  ast_log(LOG_WARNING, "'%s' is not a valid state name at line %d of %s\n", tok, lineno, script);
844  return 0;
845  }
846  if ((snums[scnt] = getstatebyname(state, sname, script, lineno, 0) == NULL)) {
847  ast_log(LOG_WARNING, "State '%s' not declared at line %d of %s\n", sname, lineno, script);
848  return 0;
849  }
850  scnt++;
851  if (!(tok = get_token(&args, script, lineno)))
852  break;
853  }
854  if (!tok || strcasecmp(tok, "GOTO")) {
855  if (!tok)
856  tok = "<nothing>";
857  if (sawin)
858  ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script);
859  else
860  ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script);
861  }
862  if (!(tok = get_token(&args, script, lineno))) {
863  ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
864  return 0;
865  }
866  if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
867  ast_log(LOG_WARNING, "Invalid subscript '%s' at line %d of %s\n", tok, lineno, script);
868  return 0;
869  }
870  if (!(sub = getsubbyname(state, subscr, script, lineno)))
871  return 0;
872  buf[0] = 8;
873  buf[1] = event;
874  buf[2] = sub->id | 0x80;
875  for (x = 0; x < scnt; x++)
876  buf[3 + x] = snums[x];
877  return 3 + scnt;
878 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
static struct adsi_state * getstatebyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:595
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct adsi_subscript * getsubbyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:574
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
static int geteventbyname(char *name)
Definition: app_adsiprog.c:529
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 977 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_MAIN_LEN, MAX_SUB_LEN, name, and adsi_subscript::vname.

Referenced by adsi_process().

978 {
979  int x, res, max = sub->id ? MAX_SUB_LEN : MAX_MAIN_LEN;
980  char *unused;
981 
982  for (x = 0; x < ARRAY_LEN(opcmds); x++) {
983  if ((opcmds[x].id > -1) && !strcasecmp(opcmds[x].name, code)) {
984  if (opcmds[x].add_args) {
985  res = opcmds[x].add_args(sub->data + sub->datalen,
986  code, opcmds[x].id, args, state, script, lineno);
987  if ((sub->datalen + res + 1) <= max)
988  sub->datalen += res;
989  else {
990  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);
991  return -1;
992  }
993  } else {
994  if ((unused = get_token(&args, script, lineno)))
995  ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", opcmds[x].name, lineno, script, unused);
996  if ((sub->datalen + 2) <= max) {
997  sub->data[sub->datalen] = opcmds[x].id;
998  sub->datalen++;
999  } else {
1000  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);
1001  return -1;
1002  }
1003  }
1004  /* Separate commands with 0xff */
1005  sub->data[sub->datalen] = 0xff;
1006  sub->datalen++;
1007  sub->inscount++;
1008  return 0;
1009  }
1010  }
1011  return -1;
1012 }
#define MAX_SUB_LEN
Definition: app_adsiprog.c:118
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
#define MAX_MAIN_LEN
Definition: app_adsiprog.c:119
char vname[40]
Definition: app_adsiprog.c:134
static struct @350 args
char data[2048]
Definition: app_adsiprog.c:141
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
int(* add_args)(char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:883
static struct adsi_key_cmd opcmds[]
Definition: app_adsiprog.c:928
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 948 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, name, adsi_soft_key::retstr, adsi_soft_key::retstrlen, and adsi_soft_key::vname.

Referenced by adsi_process().

949 {
950  int x, res;
951  char *unused;
952 
953  for (x = 0; x < ARRAY_LEN(kcmds); x++) {
954  if ((kcmds[x].id > -1) && !strcasecmp(kcmds[x].name, code)) {
955  if (kcmds[x].add_args) {
956  res = kcmds[x].add_args(key->retstr + key->retstrlen,
957  code, kcmds[x].id, args, state, script, lineno);
958  if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
959  key->retstrlen += res;
960  else
961  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);
962  } else {
963  if ((unused = get_token(&args, script, lineno)))
964  ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused);
965  if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) {
966  key->retstr[key->retstrlen] = kcmds[x].id;
967  key->retstrlen++;
968  } else
969  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);
970  }
971  return 0;
972  }
973  }
974  return -1;
975 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
#define MAX_RET_CODE
Definition: app_adsiprog.c:117
char retstr[80]
Definition: app_adsiprog.c:130
char vname[40]
Definition: app_adsiprog.c:125
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
int(* add_args)(char *buf, char *name, int id, char *args, struct adsi_script *state, const char *script, int lineno)
Definition: app_adsiprog.c:883
static struct adsi_key_cmd kcmds[]
Definition: app_adsiprog.c:886
static int process_token ( void *  out,
char *  src,
int  maxlen,
int  argtype 
)
static

Definition at line 189 of file app_adsiprog.c.

References ARG_NUMBER, ARG_STRING, and ast_strlen_zero().

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

190 {
191  if ((strlen(src) > 1) && src[0] == '\"') {
192  /* This is a quoted string */
193  if (!(argtype & ARG_STRING))
194  return -1;
195  src++;
196  /* Don't take more than what's there */
197  if (maxlen > strlen(src) - 1)
198  maxlen = strlen(src) - 1;
199  memcpy(out, src, maxlen);
200  ((char *)out)[maxlen] = '\0';
201  } else if (!ast_strlen_zero(src) && (src[0] == '\\')) {
202  if (!(argtype & ARG_NUMBER))
203  return -1;
204  /* Octal value */
205  if (sscanf(src, "%30o", (unsigned *)out) != 1)
206  return -1;
207  if (argtype & ARG_STRING) {
208  /* Convert */
209  *((unsigned int *)out) = htonl(*((unsigned int *)out));
210  }
211  } else if ((strlen(src) > 2) && (src[0] == '0') && (tolower(src[1]) == 'x')) {
212  if (!(argtype & ARG_NUMBER))
213  return -1;
214  /* Hex value */
215  if (sscanf(src + 2, "%30x", (unsigned int *)out) != 1)
216  return -1;
217  if (argtype & ARG_STRING) {
218  /* Convert */
219  *((unsigned int *)out) = htonl(*((unsigned int *)out));
220  }
221  } else if ((!ast_strlen_zero(src) && isdigit(src[0]))) {
222  if (!(argtype & ARG_NUMBER))
223  return -1;
224  /* Hex value */
225  if (sscanf(src, "%30d", (int *)out) != 1)
226  return -1;
227  if (argtype & ARG_STRING) {
228  /* Convert */
229  *((unsigned int *)out) = htonl(*((unsigned int *)out));
230  }
231  } else
232  return -1;
233  return 0;
234 }
#define ARG_NUMBER
Definition: app_adsiprog.c:122
#define ARG_STRING
Definition: app_adsiprog.c:121
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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 364 of file app_adsiprog.c.

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

365 {
366  char *gtime = get_token(&args, script, lineno);
367  int ms;
368 
369  if (!gtime) {
370  ast_log(LOG_WARNING, "Expecting number of milliseconds to wait at line %d of %s\n", lineno, script);
371  return 0;
372  }
373 
374  if (process_token(&ms, gtime, sizeof(ms), ARG_NUMBER)) {
375  ast_log(LOG_WARNING, "Invalid delay milliseconds '%s' at line %d of %s\n", gtime, lineno, script);
376  return 0;
377  }
378 
379  buf[0] = 0x90;
380 
381  if (id == 11)
382  buf[1] = ms / 100;
383  else
384  buf[1] = ms / 10;
385 
386  return 2;
387 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
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 268 of file app_adsiprog.c.

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

269 {
270  char dtmfstr[80], *a;
271  int bytes = 0;
272 
273  if (!(a = get_token(&args, script, lineno))) {
274  ast_log(LOG_WARNING, "Expecting something to send for SENDDTMF at line %d of %s\n", lineno, script);
275  return 0;
276  }
277 
278  if (process_token(dtmfstr, a, sizeof(dtmfstr) - 1, ARG_STRING)) {
279  ast_log(LOG_WARNING, "Invalid token for SENDDTMF at line %d of %s\n", lineno, script);
280  return 0;
281  }
282 
283  a = dtmfstr;
284 
285  while (*a) {
286  if (strchr(validdtmf, *a)) {
287  *buf = *a;
288  buf++;
289  bytes++;
290  } else
291  ast_log(LOG_WARNING, "'%c' is not a valid DTMF tone at line %d of %s\n", *a, lineno, script);
292  a++;
293  }
294 
295  return bytes;
296 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
static struct _map_x_s dtmfstr[]
mapping between dtmf flags and strings
Definition: chan_sip.c:17581
#define LOG_WARNING
Definition: logger.h:144
static char * validdtmf
Definition: app_adsiprog.c:266
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
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 389 of file app_adsiprog.c.

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

390 {
391  char *gstate = get_token(&args, script, lineno);
392  int state;
393 
394  if (!gstate) {
395  ast_log(LOG_WARNING, "Expecting state number at line %d of %s\n", lineno, script);
396  return 0;
397  }
398 
399  if (process_token(&state, gstate, sizeof(state), ARG_NUMBER)) {
400  ast_log(LOG_WARNING, "Invalid state number '%s' at line %d of %s\n", gstate, lineno, script);
401  return 0;
402  }
403 
404  buf[0] = id;
405  buf[1] = state;
406 
407  return 2;
408 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static int setflag ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 453 of file app_adsiprog.c.

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

454 {
455  char *tok = get_token(&args, script, lineno);
456  char sname[80];
457  struct adsi_flag *flag;
458 
459  if (!tok) {
460  ast_log(LOG_WARNING, "Setting flag requires a flag number at line %d of %s\n", lineno, script);
461  return 0;
462  }
463 
464  if (process_token(sname, tok, sizeof(sname) - 1, ARG_STRING)) {
465  ast_log(LOG_WARNING, "Invalid flag '%s' at line %d of %s\n", tok, lineno, script);
466  return 0;
467  }
468 
469  if (!(flag = getflagbyname(state, sname, script, lineno, 0))) {
470  ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", sname, lineno, script);
471  return 0;
472  }
473 
474  buf[0] = id;
475  buf[1] = ((flag->id & 0x7) << 4) | 1;
476 
477  return 2;
478 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:428
static int showdisplay ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 692 of file app_adsiprog.c.

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

693 {
694  char *tok, dispname[80];
695  int line = 0, flag = 0, cmd = 3;
696  struct adsi_display *disp;
697 
698  /* Get display */
699  if (!(tok = get_token(&args, script, lineno)) || process_token(dispname, tok, sizeof(dispname) - 1, ARG_STRING)) {
700  ast_log(LOG_WARNING, "Invalid display name: %s at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
701  return 0;
702  }
703 
704  if (!(disp = getdisplaybyname(state, dispname, script, lineno, 0))) {
705  ast_log(LOG_WARNING, "Display '%s' is undefined at line %d of %s\n", dispname, lineno, script);
706  return 0;
707  }
708 
709  if (!(tok = get_token(&args, script, lineno)) || strcasecmp(tok, "AT")) {
710  ast_log(LOG_WARNING, "Missing token 'AT' at line %d of %s\n", lineno, script);
711  return 0;
712  }
713 
714  /* Get line number */
715  if (!(tok = get_token(&args, script, lineno)) || process_token(&line, tok, sizeof(line), ARG_NUMBER)) {
716  ast_log(LOG_WARNING, "Invalid line: '%s' at line %d of %s\n", tok ? tok : "<nothing>", lineno, script);
717  return 0;
718  }
719 
720  if ((tok = get_token(&args, script, lineno)) && !strcasecmp(tok, "NOUPDATE")) {
721  cmd = 1;
722  tok = get_token(&args, script, lineno);
723  }
724 
725  if (tok && !strcasecmp(tok, "UNLESS")) {
726  /* Check for trailing UNLESS flag */
727  if (!(tok = get_token(&args, script, lineno)))
728  ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
729  else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER))
730  ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script);
731 
732  if ((tok = get_token(&args, script, lineno)))
733  ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
734  }
735 
736  buf[0] = id;
737  buf[1] = (cmd << 6) | (disp->id & 0x3f);
738  buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
739 
740  return 3;
741 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct adsi_display * getdisplaybyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:620
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static int showkeys ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 645 of file app_adsiprog.c.

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

646 {
647  char *tok, newkey[80];
648  int bytes, x, flagid = 0;
649  unsigned char keyid[6];
650  struct adsi_soft_key *key;
651  struct adsi_flag *flag;
652 
653  for (x = 0; x < 7; x++) {
654  /* Up to 6 key arguments */
655  if (!(tok = get_token(&args, script, lineno)))
656  break;
657  if (!strcasecmp(tok, "UNLESS")) {
658  /* Check for trailing UNLESS flag */
659  if (!(tok = get_token(&args, script, lineno)))
660  ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
661  else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING))
662  ast_log(LOG_WARNING, "Invalid flag name '%s' at line %d of %s\n", tok, lineno, script);
663  else if (!(flag = getflagbyname(state, newkey, script, lineno, 0)))
664  ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", newkey, lineno, script);
665  else
666  flagid = flag->id;
667  if ((tok = get_token(&args, script, lineno)))
668  ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
669  break;
670  }
671  if (x > 5) {
672  ast_log(LOG_WARNING, "Only 6 keys can be defined, ignoring '%s' at line %d of %s\n", tok, lineno, script);
673  break;
674  }
675  if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
676  ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok);
677  continue;
678  }
679 
680  if (!(key = getkeybyname(state, newkey, script, lineno)))
681  break;
682  keyid[x] = key->id;
683  }
684  buf[0] = id;
685  buf[1] = (flagid & 0x7) << 3 | (x & 0x7);
686  for (bytes = 0; bytes < x; bytes++)
687  buf[bytes + 2] = keyid[bytes];
688 
689  return 2 + x;
690 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static struct adsi_soft_key * getkeybyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:553
static struct adsi_flag * getflagbyname(struct adsi_script *state, char *name, const char *script, int lineno, int create)
Definition: app_adsiprog.c:428
static int starttimer ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script istate,
const char *  script,
int  lineno 
)
static

Definition at line 507 of file app_adsiprog.c.

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

508 {
509  char *tok = get_token(&args, script, lineno);
510  int secs;
511 
512  if (!tok) {
513  ast_log(LOG_WARNING, "Missing number of seconds at line %d of %s\n", lineno, script);
514  return 0;
515  }
516 
517  if (process_token(&secs, tok, sizeof(secs), ARG_NUMBER)) {
518  ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
519  return 0;
520  }
521 
522  buf[0] = id;
523  buf[1] = 0x1;
524  buf[2] = secs;
525 
526  return 3;
527 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_NUMBER
Definition: app_adsiprog.c:122
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
enum queue_result id
Definition: app_queue.c:1090
static int subscript ( char *  buf,
char *  name,
int  id,
char *  args,
struct adsi_script state,
const char *  script,
int  lineno 
)
static

Definition at line 791 of file app_adsiprog.c.

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

792 {
793  char *tok = get_token(&args, script, lineno);
794  char subscr[80];
795  struct adsi_subscript *sub;
796 
797  if (!tok) {
798  ast_log(LOG_WARNING, "Missing subscript to call at line %d of %s\n", lineno, script);
799  return 0;
800  }
801 
802  if (process_token(subscr, tok, sizeof(subscr) - 1, ARG_STRING)) {
803  ast_log(LOG_WARNING, "Invalid number of seconds '%s' at line %d of %s\n", tok, lineno, script);
804  return 0;
805  }
806 
807  if (!(sub = getsubbyname(state, subscr, script, lineno)))
808  return 0;
809 
810  buf[0] = 0x9d;
811  buf[1] = sub->id;
812 
813  return 2;
814 }
static char * get_token(char **buf, const char *script, int lineno)
Definition: app_adsiprog.c:236
#define LOG_WARNING
Definition: logger.h:144
#define ARG_STRING
Definition: app_adsiprog.c:121
static struct adsi_subscript * getsubbyname(struct adsi_script *state, char *name, const char *script, int lineno)
Definition: app_adsiprog.c:574
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int process_token(void *out, char *src, int maxlen, int argtype)
Definition: app_adsiprog.c:189
static int unload_module ( void  )
static

Definition at line 1583 of file app_adsiprog.c.

References ast_unregister_application().

1584 {
1586 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app[]
Definition: app_adsiprog.c:49

Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .nonoptreq = "res_adsi", }
static

Definition at line 1599 of file app_adsiprog.c.

Definition at line 1599 of file app_adsiprog.c.

struct adsi_event justify[]
static

Definition at line 105 of file app_adsiprog.c.

Referenced by adsi_announce_park(), and cpeid_setstatus().

struct adsi_key_cmd kcmds[]
static

Definition at line 886 of file app_adsiprog.c.

struct adsi_key_cmd opcmds[]
static

Definition at line 928 of file app_adsiprog.c.

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

Definition at line 266 of file app_adsiprog.c.