|
|
|
@ -21,7 +21,7 @@
|
|
|
|
|
* \brief Program Asterisk ADSI Scripts into phone
|
|
|
|
|
*
|
|
|
|
|
* \author Mark Spencer <markster@digium.com>
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* \ingroup applications
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
@ -36,7 +36,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
#include "asterisk/paths.h" /* use ast_config_AST_CONFIG_DIR */
|
|
|
|
|
#include "asterisk/paths.h" /* use ast_config_AST_CONFIG_DIR */
|
|
|
|
|
#include "asterisk/file.h"
|
|
|
|
|
#include "asterisk/channel.h"
|
|
|
|
|
#include "asterisk/pbx.h"
|
|
|
|
@ -94,25 +94,25 @@ static struct adsi_event justify[] = {
|
|
|
|
|
{ 3, "INDENT" },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define STATE_NORMAL 0
|
|
|
|
|
#define STATE_INKEY 1
|
|
|
|
|
#define STATE_INSUB 2
|
|
|
|
|
#define STATE_INIF 3
|
|
|
|
|
#define STATE_NORMAL 0
|
|
|
|
|
#define STATE_INKEY 1
|
|
|
|
|
#define STATE_INSUB 2
|
|
|
|
|
#define STATE_INIF 3
|
|
|
|
|
|
|
|
|
|
#define MAX_RET_CODE 20
|
|
|
|
|
#define MAX_SUB_LEN 255
|
|
|
|
|
#define MAX_MAIN_LEN 1600
|
|
|
|
|
#define MAX_RET_CODE 20
|
|
|
|
|
#define MAX_SUB_LEN 255
|
|
|
|
|
#define MAX_MAIN_LEN 1600
|
|
|
|
|
|
|
|
|
|
#define ARG_STRING (1 << 0)
|
|
|
|
|
#define ARG_NUMBER (1 << 1)
|
|
|
|
|
#define ARG_STRING (1 << 0)
|
|
|
|
|
#define ARG_NUMBER (1 << 1)
|
|
|
|
|
|
|
|
|
|
struct adsi_soft_key {
|
|
|
|
|
char vname[40]; /* Which "variable" is associated with it */
|
|
|
|
|
int retstrlen; /* Length of return string */
|
|
|
|
|
int initlen; /* initial length */
|
|
|
|
|
char vname[40]; /* Which "variable" is associated with it */
|
|
|
|
|
int retstrlen; /* Length of return string */
|
|
|
|
|
int initlen; /* initial length */
|
|
|
|
|
int id;
|
|
|
|
|
int defined;
|
|
|
|
|
char retstr[80]; /* Return string data */
|
|
|
|
|
char retstr[80]; /* Return string data */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct adsi_subscript {
|
|
|
|
@ -267,7 +267,7 @@ static int send_dtmf(char *buf, char *name, int id, char *args, struct adsi_scri
|
|
|
|
|
|
|
|
|
|
a = dtmfstr;
|
|
|
|
|
|
|
|
|
|
while(*a) {
|
|
|
|
|
while (*a) {
|
|
|
|
|
if (strchr(validdtmf, *a)) {
|
|
|
|
|
*buf = *a;
|
|
|
|
|
buf++;
|
|
|
|
@ -292,11 +292,11 @@ static int goto_line(char *buf, char *name, int id, char *args, struct adsi_scri
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(page, "INFO")) {
|
|
|
|
|
if (!strcasecmp(page, "INFO"))
|
|
|
|
|
cmd = 0;
|
|
|
|
|
} else if (!strcasecmp(page, "COMM")) {
|
|
|
|
|
else if (!strcasecmp(page, "COMM"))
|
|
|
|
|
cmd = 0x80;
|
|
|
|
|
} else {
|
|
|
|
|
else {
|
|
|
|
|
ast_log(LOG_WARNING, "Expecting either 'INFO' or 'COMM' page, got got '%s' at line %d of %s\n", page, lineno, script);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -325,11 +325,11 @@ static int goto_line_rel(char *buf, char *name, int id, char *args, struct adsi_
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!strcasecmp(dir, "UP")) {
|
|
|
|
|
if (!strcasecmp(dir, "UP"))
|
|
|
|
|
cmd = 0;
|
|
|
|
|
} else if (!strcasecmp(dir, "DOWN")) {
|
|
|
|
|
else if (!strcasecmp(dir, "DOWN"))
|
|
|
|
|
cmd = 0x20;
|
|
|
|
|
} else {
|
|
|
|
|
else {
|
|
|
|
|
ast_log(LOG_WARNING, "Expecting either 'UP' or 'DOWN' direction, got '%s' at line %d of %s\n", dir, lineno, script);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -396,7 +396,7 @@ static int cleartimer(char *buf, char *name, int id, char *args, struct adsi_scr
|
|
|
|
|
{
|
|
|
|
|
char *tok = get_token(&args, script, lineno);
|
|
|
|
|
|
|
|
|
|
if (tok)
|
|
|
|
|
if (tok)
|
|
|
|
|
ast_log(LOG_WARNING, "Clearing timer requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
|
|
|
|
|
buf[0] = id;
|
|
|
|
@ -415,7 +415,7 @@ static struct adsi_flag *getflagbyname(struct adsi_script *state, char *name, ch
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < state->numflags; x++) {
|
|
|
|
|
if (!strcasecmp(state->flags[x].vname, name))
|
|
|
|
|
if (!strcasecmp(state->flags[x].vname, name))
|
|
|
|
|
return &state->flags[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -540,7 +540,7 @@ static struct adsi_soft_key *getkeybyname(struct adsi_script *state, char *name,
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < state->numkeys; x++) {
|
|
|
|
|
if (!strcasecmp(state->keys[x].vname, name))
|
|
|
|
|
if (!strcasecmp(state->keys[x].vname, name))
|
|
|
|
|
return &state->keys[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -561,7 +561,7 @@ static struct adsi_subscript *getsubbyname(struct adsi_script *state, char *name
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < state->numsubs; x++) {
|
|
|
|
|
if (!strcasecmp(state->subs[x].vname, name))
|
|
|
|
|
if (!strcasecmp(state->subs[x].vname, name))
|
|
|
|
|
return &state->subs[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -582,7 +582,7 @@ static struct adsi_state *getstatebyname(struct adsi_script *state, char *name,
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x <state->numstates; x++) {
|
|
|
|
|
if (!strcasecmp(state->states[x].vname, name))
|
|
|
|
|
if (!strcasecmp(state->states[x].vname, name))
|
|
|
|
|
return &state->states[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -607,7 +607,7 @@ static struct adsi_display *getdisplaybyname(struct adsi_script *state, char *na
|
|
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < state->numdisplays; x++) {
|
|
|
|
|
if (!strcasecmp(state->displays[x].vname, name))
|
|
|
|
|
if (!strcasecmp(state->displays[x].vname, name))
|
|
|
|
|
return &state->displays[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -641,13 +641,13 @@ static int showkeys(char *buf, char *name, int id, char *args, struct adsi_scrip
|
|
|
|
|
break;
|
|
|
|
|
if (!strcasecmp(tok, "UNLESS")) {
|
|
|
|
|
/* Check for trailing UNLESS flag */
|
|
|
|
|
if (!(tok = get_token(&args, script, lineno))) {
|
|
|
|
|
if (!(tok = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
|
|
|
|
|
} else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
|
|
|
|
|
else if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING))
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid flag name '%s' at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
} else if (!(flag = getflagbyname(state, newkey, script, lineno, 0))) {
|
|
|
|
|
else if (!(flag = getflagbyname(state, newkey, script, lineno, 0)))
|
|
|
|
|
ast_log(LOG_WARNING, "Flag '%s' is undeclared at line %d of %s\n", newkey, lineno, script);
|
|
|
|
|
} else
|
|
|
|
|
else
|
|
|
|
|
flagid = flag->id;
|
|
|
|
|
if ((tok = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
|
|
|
|
@ -658,19 +658,19 @@ static int showkeys(char *buf, char *name, int id, char *args, struct adsi_scrip
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (process_token(newkey, tok, sizeof(newkey) - 1, ARG_STRING)) {
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok);
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid token for key name: %s\n", tok);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(key = getkeybyname(state, newkey, script, lineno)))
|
|
|
|
|
break;
|
|
|
|
|
keyid[x] = key->id;
|
|
|
|
|
}
|
|
|
|
|
buf[0] = id;
|
|
|
|
|
buf[1] = (flagid & 0x7) << 3 | (x & 0x7);
|
|
|
|
|
for (bytes = 0; bytes < x; bytes++) {
|
|
|
|
|
for (bytes = 0; bytes < x; bytes++)
|
|
|
|
|
buf[bytes + 2] = keyid[bytes];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 2 + x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -709,17 +709,17 @@ static int showdisplay(char *buf, char *name, int id, char *args, struct adsi_sc
|
|
|
|
|
|
|
|
|
|
if (tok && !strcasecmp(tok, "UNLESS")) {
|
|
|
|
|
/* Check for trailing UNLESS flag */
|
|
|
|
|
if (!(tok = get_token(&args, script, lineno))) {
|
|
|
|
|
if (!(tok = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "Missing argument for UNLESS clause at line %d of %s\n", lineno, script);
|
|
|
|
|
} else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER)) {
|
|
|
|
|
else if (process_token(&flag, tok, sizeof(flag), ARG_NUMBER))
|
|
|
|
|
ast_log(LOG_WARNING, "Invalid flag number '%s' at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((tok = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "Extra arguments after UNLESS clause: '%s' at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf[0] = id;
|
|
|
|
|
buf[1] = (cmd << 6) | (disp->id & 0x3f);
|
|
|
|
|
buf[1] = (cmd << 6) | (disp->id & 0x3f);
|
|
|
|
|
buf[2] = ((line & 0x1f) << 3) | (flag & 0x7);
|
|
|
|
|
|
|
|
|
|
return 3;
|
|
|
|
@ -729,7 +729,7 @@ static int cleardisplay(char *buf, char *name, int id, char *args, struct adsi_s
|
|
|
|
|
{
|
|
|
|
|
char *tok = get_token(&args, script, lineno);
|
|
|
|
|
|
|
|
|
|
if (tok)
|
|
|
|
|
if (tok)
|
|
|
|
|
ast_log(LOG_WARNING, "Clearing display requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
|
|
|
|
|
buf[0] = id;
|
|
|
|
@ -741,7 +741,7 @@ static int digitdirect(char *buf, char *name, int id, char *args, struct adsi_sc
|
|
|
|
|
{
|
|
|
|
|
char *tok = get_token(&args, script, lineno);
|
|
|
|
|
|
|
|
|
|
if (tok)
|
|
|
|
|
if (tok)
|
|
|
|
|
ast_log(LOG_WARNING, "Digitdirect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
|
|
|
|
|
buf[0] = id;
|
|
|
|
@ -765,7 +765,7 @@ static int digitcollect(char *buf, char *name, int id, char *args, struct adsi_s
|
|
|
|
|
{
|
|
|
|
|
char *tok = get_token(&args, script, lineno);
|
|
|
|
|
|
|
|
|
|
if (tok)
|
|
|
|
|
if (tok)
|
|
|
|
|
ast_log(LOG_WARNING, "Digitcollect requires no arguments ('%s') at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
|
|
|
|
|
buf[0] = id;
|
|
|
|
@ -816,8 +816,7 @@ static int onevent(char *buf, char *name, int id, char *args, struct adsi_script
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tok = get_token(&args, script, lineno);
|
|
|
|
|
while ((!sawin && !strcasecmp(tok, "IN")) ||
|
|
|
|
|
(sawin && !strcasecmp(tok, "OR"))) {
|
|
|
|
|
while ((!sawin && !strcasecmp(tok, "IN")) || (sawin && !strcasecmp(tok, "OR"))) {
|
|
|
|
|
sawin = 1;
|
|
|
|
|
if (scnt > 7) {
|
|
|
|
|
ast_log(LOG_WARNING, "No more than 8 states may be specified for inclusion at line %d of %s\n", lineno, script);
|
|
|
|
@ -840,7 +839,7 @@ static int onevent(char *buf, char *name, int id, char *args, struct adsi_script
|
|
|
|
|
if (!tok || strcasecmp(tok, "GOTO")) {
|
|
|
|
|
if (!tok)
|
|
|
|
|
tok = "<nothing>";
|
|
|
|
|
if (sawin)
|
|
|
|
|
if (sawin)
|
|
|
|
|
ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'OR' at line %d of %s\n", tok, lineno, script);
|
|
|
|
|
else
|
|
|
|
|
ast_log(LOG_WARNING, "Got '%s' while looking for 'GOTO' or 'IN' at line %d of %s\n", tok, lineno, script);
|
|
|
|
@ -941,17 +940,17 @@ static int process_returncode(struct adsi_soft_key *key, char *code, char *args,
|
|
|
|
|
if (kcmds[x].add_args) {
|
|
|
|
|
res = kcmds[x].add_args(key->retstr + key->retstrlen,
|
|
|
|
|
code, kcmds[x].id, args, state, script, lineno);
|
|
|
|
|
if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
|
|
|
|
|
if ((key->retstrlen + res - key->initlen) <= MAX_RET_CODE)
|
|
|
|
|
key->retstrlen += res;
|
|
|
|
|
else
|
|
|
|
|
else
|
|
|
|
|
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);
|
|
|
|
|
} else {
|
|
|
|
|
if ((unused = get_token(&args, script, lineno)))
|
|
|
|
|
if ((unused = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", kcmds[x].name, lineno, script, unused);
|
|
|
|
|
if ((key->retstrlen + 1 - key->initlen) <= MAX_RET_CODE) {
|
|
|
|
|
key->retstr[key->retstrlen] = kcmds[x].id;
|
|
|
|
|
key->retstrlen++;
|
|
|
|
|
} else
|
|
|
|
|
} else
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
@ -970,14 +969,14 @@ static int process_opcode(struct adsi_subscript *sub, char *code, char *args, st
|
|
|
|
|
if (opcmds[x].add_args) {
|
|
|
|
|
res = opcmds[x].add_args(sub->data + sub->datalen,
|
|
|
|
|
code, opcmds[x].id, args, state, script, lineno);
|
|
|
|
|
if ((sub->datalen + res + 1) <= max)
|
|
|
|
|
if ((sub->datalen + res + 1) <= max)
|
|
|
|
|
sub->datalen += res;
|
|
|
|
|
else {
|
|
|
|
|
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);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ((unused = get_token(&args, script, lineno)))
|
|
|
|
|
if ((unused = get_token(&args, script, lineno)))
|
|
|
|
|
ast_log(LOG_WARNING, "'%s' takes no arguments at line %d of %s (token is '%s')\n", opcmds[x].name, lineno, script, unused);
|
|
|
|
|
if ((sub->datalen + 2) <= max) {
|
|
|
|
|
sub->data[sub->datalen] = opcmds[x].id;
|
|
|
|
@ -1005,7 +1004,7 @@ static int adsi_process(struct adsi_script *state, char *buf, char *script, int
|
|
|
|
|
struct adsi_display *disp;
|
|
|
|
|
struct adsi_subscript *newsub;
|
|
|
|
|
|
|
|
|
|
if (!keyword)
|
|
|
|
|
if (!keyword)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
switch(state->state) {
|
|
|
|
@ -1141,7 +1140,7 @@ static int adsi_process(struct adsi_script *state, char *buf, char *script, int
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
state->state = STATE_INSUB;
|
|
|
|
|
} else if (!strcasecmp(keyword, "STATE")) {
|
|
|
|
|
} else if (!strcasecmp(keyword, "STATE")) {
|
|
|
|
|
if (!(args = get_token(&buf, script, lineno))) {
|
|
|
|
|
ast_log(LOG_WARNING, "STATE definition missing name at line %d of %s\n", lineno, script);
|
|
|
|
|
break;
|
|
|
|
@ -1155,7 +1154,7 @@ static int adsi_process(struct adsi_script *state, char *buf, char *script, int
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
getstatebyname(state, vname, script, lineno, 1);
|
|
|
|
|
} else if (!strcasecmp(keyword, "FLAG")) {
|
|
|
|
|
} else if (!strcasecmp(keyword, "FLAG")) {
|
|
|
|
|
if (!(args = get_token(&buf, script, lineno))) {
|
|
|
|
|
ast_log(LOG_WARNING, "FLAG definition missing name at line %d of %s\n", lineno, script);
|
|
|
|
|
break;
|
|
|
|
@ -1217,7 +1216,7 @@ static int adsi_process(struct adsi_script *state, char *buf, char *script, int
|
|
|
|
|
disp->datalen += strlen(tmp);
|
|
|
|
|
args = get_token(&buf, script, lineno);
|
|
|
|
|
}
|
|
|
|
|
while(args) {
|
|
|
|
|
while (args) {
|
|
|
|
|
if (!strcasecmp(args, "JUSTIFY")) {
|
|
|
|
|
args = get_token(&buf, script, lineno);
|
|
|
|
|
if (!args) {
|
|
|
|
@ -1324,8 +1323,7 @@ static int adsi_process(struct adsi_script *state, char *buf, char *script, int
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
state->sub->ifinscount = 0;
|
|
|
|
|
state->sub->ifdata = state->sub->data +
|
|
|
|
|
state->sub->datalen;
|
|
|
|
|
state->sub->ifdata = state->sub->data + state->sub->datalen;
|
|
|
|
|
/* Reserve header and insert op codes */
|
|
|
|
|
state->sub->ifdata[0] = 0x1;
|
|
|
|
|
state->sub->ifdata[1] = event;
|
|
|
|
@ -1370,7 +1368,7 @@ static struct adsi_script *compile_script(char *script)
|
|
|
|
|
|
|
|
|
|
/* Create "main" as first subroutine */
|
|
|
|
|
getsubbyname(scr, "main", NULL, 0);
|
|
|
|
|
while(!feof(f)) {
|
|
|
|
|
while (!feof(f)) {
|
|
|
|
|
fgets(buf, sizeof(buf), f);
|
|
|
|
|
if (!feof(f)) {
|
|
|
|
|
lineno++;
|
|
|
|
@ -1447,7 +1445,7 @@ static int adsi_prog(struct ast_channel *chan, char *script)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* Start an empty ADSI Session */
|
|
|
|
|
if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
|
|
|
|
|
if (ast_adsi_load_session(chan, NULL, 0, 1) < 1)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* Now begin the download attempt */
|
|
|
|
@ -1531,7 +1529,6 @@ static int adsi_prog(struct ast_channel *chan, char *script)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bytes = 0;
|
|
|
|
|
bytes += ast_adsi_display(buf, ADSI_INFO_PAGE, 1, ADSI_JUST_LEFT, 0, "Download complete.", "");
|
|
|
|
|
bytes += ast_adsi_set_line(buf, ADSI_INFO_PAGE, 1);
|
|
|
|
@ -1555,14 +1552,14 @@ static int adsi_exec(struct ast_channel *chan, void *data)
|
|
|
|
|
|
|
|
|
|
if (ast_strlen_zero(data))
|
|
|
|
|
data = "asterisk.adsi";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ast_adsi_available(chan)) {
|
|
|
|
|
ast_verb(3, "ADSI Unavailable on CPE. Not bothering to try.\n");
|
|
|
|
|
} else {
|
|
|
|
|
ast_verb(3, "ADSI Available on CPE. Attempting Upload.\n");
|
|
|
|
|
res = adsi_prog(chan, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|