Sat Feb 11 06:36:18 2012

Asterisk developer's documentation


res_adsi.c File Reference

ADSI support. More...

#include "asterisk.h"
#include <time.h>
#include <math.h>
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/fskmodem.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/file.h"
#include "asterisk/adsi.h"

Include dependency graph for res_adsi.c:

Go to the source code of this file.

Defines

#define ADSI_FLAG_DATAMODE   (1 << 8)
#define ADSI_MAX_INTRO   20
#define ADSI_MAX_SPEED_DIAL   6
#define ADSI_SPEED_DIAL   10
#define AST_API_MODULE
#define DEFAULT_ADSI_MAX_RETRIES   3
#define SPEEDDIAL_MAX_LEN   20

Functions

static int __adsi_transmit_messages (struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
static void __reg_module (void)
static void __unreg_module (void)
static int adsi_careful_send (struct ast_channel *chan, unsigned char *buf, int len, int *remain)
static int adsi_generate (unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, struct ast_format *codec)
static void adsi_load (int reload)
int AST_OPTIONAL_API_NAME() ast_adsi_available (struct ast_channel *chan)
 Returns non-zero if Channel does or might support ADSI.
int AST_OPTIONAL_API_NAME() ast_adsi_begin_download (struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
int AST_OPTIONAL_API_NAME() ast_adsi_channel_restore (struct ast_channel *chan)
int AST_OPTIONAL_API_NAME() ast_adsi_clear_screen (unsigned char *buf)
int AST_OPTIONAL_API_NAME() ast_adsi_clear_soft_keys (unsigned char *buf)
int AST_OPTIONAL_API_NAME() ast_adsi_connect_session (unsigned char *buf, unsigned char *fdn, int ver)
 Connects an ADSI Display Session.
int AST_OPTIONAL_API_NAME() ast_adsi_data_mode (unsigned char *buf)
 Puts CPE in data mode.
int AST_OPTIONAL_API_NAME() ast_adsi_disconnect_session (unsigned char *buf)
 Disconnects a running session.
int AST_OPTIONAL_API_NAME() 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.
int AST_OPTIONAL_API_NAME() ast_adsi_download_connect (unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
 Begin an ADSI script download.
int AST_OPTIONAL_API_NAME() ast_adsi_download_disconnect (unsigned char *buf)
 Disconnects (and hopefully saves) a downloaded script.
int AST_OPTIONAL_API_NAME() ast_adsi_end_download (struct ast_channel *chan)
int AST_OPTIONAL_API_NAME() ast_adsi_get_cpeid (struct ast_channel *chan, unsigned char *cpeid, int voice)
int AST_OPTIONAL_API_NAME() ast_adsi_get_cpeinfo (struct ast_channel *chan, int *width, int *height, int *buttons, int voice)
int AST_OPTIONAL_API_NAME() ast_adsi_input_control (unsigned char *buf, int page, int line, int display, int format, int just)
 Set input information.
int AST_OPTIONAL_API_NAME() ast_adsi_input_format (unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
 Set input format.
int AST_OPTIONAL_API_NAME() 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, or 0-255 for a specific version.
int AST_OPTIONAL_API_NAME() ast_adsi_load_soft_key (unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data)
 Creates "load soft key" parameters.
int AST_OPTIONAL_API_NAME() ast_adsi_print (struct ast_channel *chan, char **lines, int *alignments, int voice)
 Display some stuff on the screen.
int AST_OPTIONAL_API_NAME() ast_adsi_query_cpeid (unsigned char *buf)
int AST_OPTIONAL_API_NAME() ast_adsi_query_cpeinfo (unsigned char *buf)
int AST_OPTIONAL_API_NAME() ast_adsi_read_encoded_dtmf (struct ast_channel *chan, unsigned char *buf, int maxlen)
int AST_OPTIONAL_API_NAME() ast_adsi_set_keys (unsigned char *buf, unsigned char *keys)
 Set which soft keys should be displayed.
int AST_OPTIONAL_API_NAME() ast_adsi_set_line (unsigned char *buf, int page, int line)
 Sets the current line and page.
int AST_OPTIONAL_API_NAME() ast_adsi_transmit_message (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
int AST_OPTIONAL_API_NAME() ast_adsi_transmit_message_full (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
int AST_OPTIONAL_API_NAME() ast_adsi_unload_session (struct ast_channel *chan)
int AST_OPTIONAL_API_NAME() ast_adsi_voice_mode (unsigned char *buf, int when)
 Puts CPE in voice mode.
static int ccopy (unsigned char *dst, const unsigned char *src, int max)
static void init_state (void)
static int load_module (void)
static int reload (void)
static int str2align (const char *s)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "ADSI Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_APP_DEPEND, }
static int alignment = 0
static int aligns [ADSI_MAX_INTRO]
static struct ast_module_infoast_module_info = &__mod_info
static char intro [ADSI_MAX_INTRO][20]
static int maxretries = DEFAULT_ADSI_MAX_RETRIES
static char speeddial [ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN]
static int speeds = 0
static int total = 0


Detailed Description

ADSI support.

Author:
Mark Spencer <markster@digium.com>
Note:
this module is required by app_voicemail and app_getcpeid
Todo:
Move app_getcpeid into this module
Todo:
Create a core layer so that app_voicemail does not require res_adsi to load

Definition in file res_adsi.c.


Define Documentation

#define ADSI_FLAG_DATAMODE   (1 << 8)

Definition at line 61 of file res_adsi.c.

Referenced by __adsi_transmit_messages(), and ast_adsi_transmit_message_full().

#define ADSI_MAX_INTRO   20

Definition at line 58 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

#define ADSI_MAX_SPEED_DIAL   6

Definition at line 59 of file res_adsi.c.

Referenced by adsi_load().

#define ADSI_SPEED_DIAL   10

Definition at line 66 of file res_adsi.c.

Referenced by ast_adsi_channel_restore().

#define AST_API_MODULE

Definition at line 53 of file res_adsi.c.

#define DEFAULT_ADSI_MAX_RETRIES   3

Definition at line 56 of file res_adsi.c.

#define SPEEDDIAL_MAX_LEN   20

Definition at line 71 of file res_adsi.c.

Referenced by adsi_load().


Function Documentation

static int __adsi_transmit_messages ( struct ast_channel chan,
unsigned char **  msg,
int *  msglen,
int *  msgtype 
) [static]

Definition at line 206 of file res_adsi.c.

References adsi_careful_send(), ADSI_FLAG_DATAMODE, adsi_generate(), ast_channel::adsicpe, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, ast_channel_defer_dtmf(), ast_channel_name(), ast_channel_undefer_dtmf(), ast_debug, ast_format_set(), AST_FORMAT_ULAW, AST_FRAME_DTMF, ast_frfree, ast_gen_cas(), ast_log(), ast_read(), ast_readstring(), ast_waitfor(), errno, f, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, and ast_frame::subclass.

Referenced by ast_adsi_transmit_message_full().

00207 {
00208    /* msglen must be no more than 256 bits, each */
00209    unsigned char buf[24000 * 5];
00210    int pos = 0, res, x, start = 0, retries = 0, waittime, rem = 0, def;
00211    char ack[3];
00212    struct ast_frame *f;
00213 
00214    if (chan->adsicpe == AST_ADSI_UNAVAILABLE) {
00215       /* Don't bother if we know they don't support ADSI */
00216       errno = ENOSYS;
00217       return -1;
00218    }
00219 
00220    while (retries < maxretries) {
00221       struct ast_format tmpfmt;
00222       if (!(chan->adsicpe & ADSI_FLAG_DATAMODE)) {
00223          /* Generate CAS (no SAS) */
00224          ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0);
00225          ast_gen_cas(buf, 0, 680, &tmpfmt);
00226 
00227          /* Send CAS */
00228          if (adsi_careful_send(chan, buf, 680, NULL)) {
00229             ast_log(LOG_WARNING, "Unable to send CAS\n");
00230          }
00231 
00232          /* Wait For DTMF result */
00233          waittime = 500;
00234          for (;;) {
00235             if (((res = ast_waitfor(chan, waittime)) < 1)) {
00236                /* Didn't get back DTMF A in time */
00237                ast_debug(1, "No ADSI CPE detected (%d)\n", res);
00238                if (!chan->adsicpe) {
00239                   chan->adsicpe = AST_ADSI_UNAVAILABLE;
00240                }
00241                errno = ENOSYS;
00242                return -1;
00243             }
00244             waittime = res;
00245             if (!(f = ast_read(chan))) {
00246                ast_debug(1, "Hangup in ADSI\n");
00247                return -1;
00248             }
00249             if (f->frametype == AST_FRAME_DTMF) {
00250                if (f->subclass.integer == 'A') {
00251                   /* Okay, this is an ADSI CPE.  Note this for future reference, too */
00252                   if (!chan->adsicpe) {
00253                      chan->adsicpe = AST_ADSI_AVAILABLE;
00254                   }
00255                   break;
00256                } else {
00257                   if (f->subclass.integer == 'D') {
00258                      ast_debug(1, "Off-hook capable CPE only, not ADSI\n");
00259                   } else {
00260                      ast_log(LOG_WARNING, "Unknown ADSI response '%c'\n", f->subclass.integer);
00261                   }
00262                   if (!chan->adsicpe) {
00263                      chan->adsicpe = AST_ADSI_UNAVAILABLE;
00264                   }
00265                   errno =  ENOSYS;
00266                   ast_frfree(f);
00267                   return -1;
00268                }
00269             }
00270             ast_frfree(f);
00271          }
00272 
00273          ast_debug(1, "ADSI Compatible CPE Detected\n");
00274       } else {
00275          ast_debug(1, "Already in data mode\n");
00276       }
00277 
00278       x = 0;
00279       pos = 0;
00280 #if 1
00281       def= ast_channel_defer_dtmf(chan);
00282 #endif
00283       while ((x < 6) && msg[x]) {
00284          if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], ast_format_set(&tmpfmt, AST_FORMAT_ULAW,0))) < 0) {
00285             ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, ast_channel_name(chan));
00286             return -1;
00287          }
00288          ast_debug(1, "Message %d, of %d input bytes, %d output bytes\n", x + 1, msglen[x], res);
00289          pos += res;
00290          x++;
00291       }
00292 
00293 
00294       rem = 0;
00295       res = adsi_careful_send(chan, buf, pos, &rem);
00296       if (!def) {
00297          ast_channel_undefer_dtmf(chan);
00298       }
00299       if (res) {
00300          return -1;
00301       }
00302 
00303       ast_debug(1, "Sent total spill of %d bytes\n", pos);
00304 
00305       memset(ack, 0, sizeof(ack));
00306       /* Get real result and check for hangup */
00307       if ((res = ast_readstring(chan, ack, 2, 1000, 1000, "")) < 0) {
00308          return -1;
00309       }
00310       if (ack[0] == 'D') {
00311          ast_debug(1, "Acked up to message %d\n", atoi(ack + 1)); start += atoi(ack + 1);
00312          if (start >= x) {
00313             break;
00314          } else {
00315             retries++;
00316             ast_debug(1, "Retransmitting (%d), from %d\n", retries, start + 1);
00317          }
00318       } else {
00319          retries++;
00320          ast_log(LOG_WARNING, "Unexpected response to ack: %s (retry %d)\n", ack, retries);
00321       }
00322    }
00323    if (retries >= maxretries) {
00324       ast_log(LOG_WARNING, "Maximum ADSI Retries (%d) exceeded\n", maxretries);
00325       errno = ETIMEDOUT;
00326       return -1;
00327    }
00328    return 0;
00329 }

static void __reg_module ( void   )  [static]

Definition at line 1160 of file res_adsi.c.

static void __unreg_module ( void   )  [static]

Definition at line 1160 of file res_adsi.c.

static int adsi_careful_send ( struct ast_channel chan,
unsigned char *  buf,
int  len,
int *  remain 
) [static]

Definition at line 126 of file res_adsi.c.

References ast_format_set(), AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_waitfor(), ast_write(), ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_format::id, LOG_WARNING, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by __adsi_transmit_messages().

00127 {
00128    /* Sends carefully on a full duplex channel by using reading for
00129       timing */
00130    struct ast_frame *inf, outf;
00131    int amt;
00132 
00133    /* Zero out our outgoing frame */
00134    memset(&outf, 0, sizeof(outf));
00135 
00136    if (remain && *remain) {
00137       amt = len;
00138 
00139       /* Send remainder if provided */
00140       if (amt > *remain) {
00141          amt = *remain;
00142       } else {
00143          *remain = *remain - amt;
00144       }
00145       outf.frametype = AST_FRAME_VOICE;
00146       ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
00147       outf.data.ptr = buf;
00148       outf.datalen = amt;
00149       outf.samples = amt;
00150       if (ast_write(chan, &outf)) {
00151          ast_log(LOG_WARNING, "Failed to carefully write frame\n");
00152          return -1;
00153       }
00154       /* Update pointers and lengths */
00155       buf += amt;
00156       len -= amt;
00157    }
00158 
00159    while (len) {
00160       amt = len;
00161       /* If we don't get anything at all back in a second, forget
00162          about it */
00163       if (ast_waitfor(chan, 1000) < 1) {
00164          return -1;
00165       }
00166       /* Detect hangup */
00167       if (!(inf = ast_read(chan))) {
00168          return -1;
00169       }
00170 
00171       /* Drop any frames that are not voice */
00172       if (inf->frametype != AST_FRAME_VOICE) {
00173          ast_frfree(inf);
00174          continue;
00175       }
00176 
00177       if (inf->subclass.format.id != AST_FORMAT_ULAW) {
00178          ast_log(LOG_WARNING, "Channel not in ulaw?\n");
00179          ast_frfree(inf);
00180          return -1;
00181       }
00182       /* Send no more than they sent us */
00183       if (amt > inf->datalen) {
00184          amt = inf->datalen;
00185       } else if (remain) {
00186          *remain = inf->datalen - amt;
00187       }
00188       outf.frametype = AST_FRAME_VOICE;
00189       ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
00190       outf.data.ptr = buf;
00191       outf.datalen = amt;
00192       outf.samples = amt;
00193       if (ast_write(chan, &outf)) {
00194          ast_log(LOG_WARNING, "Failed to carefully write frame\n");
00195          ast_frfree(inf);
00196          return -1;
00197       }
00198       /* Update pointers and lengths */
00199       buf += amt;
00200       len -= amt;
00201       ast_frfree(inf);
00202    }
00203    return 0;
00204 }

static int adsi_generate ( unsigned char *  buf,
int  msgtype,
unsigned char *  msg,
int  msglen,
int  msgnum,
int  last,
struct ast_format codec 
) [static]

Definition at line 76 of file res_adsi.c.

References PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __adsi_transmit_messages().

00077 {
00078    int sum, x, bytes = 0;
00079    /* Initial carrier (imaginary) */
00080    float cr = 1.0, ci = 0.0, scont = 0.0;
00081 
00082    if (msglen > 255) {
00083       msglen = 255;
00084    }
00085 
00086    /* If first message, Send 150ms of MARK's */
00087    if (msgnum == 1) {
00088       for (x = 0; x < 150; x++) { /* was 150 */
00089          PUT_CLID_MARKMS;
00090       }
00091    }
00092 
00093    /* Put message type */
00094    PUT_CLID(msgtype);
00095    sum = msgtype;
00096 
00097    /* Put message length (plus one for the message number) */
00098    PUT_CLID(msglen + 1);
00099    sum += msglen + 1;
00100 
00101    /* Put message number */
00102    PUT_CLID(msgnum);
00103    sum += msgnum;
00104 
00105    /* Put actual message */
00106    for (x = 0; x < msglen; x++) {
00107       PUT_CLID(msg[x]);
00108       sum += msg[x];
00109    }
00110 
00111    /* Put 2's compliment of sum */
00112    PUT_CLID(256-(sum & 0xff));
00113 
00114 #if 0
00115    if (last) {
00116       /* Put trailing marks */
00117       for (x = 0; x < 50; x++) {
00118          PUT_CLID_MARKMS;
00119       }
00120    }
00121 #endif
00122    return bytes;
00123 
00124 }

static void adsi_load ( int  reload  )  [static]

Definition at line 1080 of file res_adsi.c.

References ADSI_MAX_INTRO, ADSI_MAX_SPEED_DIAL, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_variable_browse(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, init_state(), ast_variable::name, name, ast_variable::next, SPEEDDIAL_MAX_LEN, str2align(), strsep(), and ast_variable::value.

Referenced by load_module(), and reload().

01081 {
01082    int x = 0;
01083    struct ast_config *conf = NULL;
01084    struct ast_variable *v;
01085    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01086    char *name, *sname;
01087    init_state();
01088 
01089    conf = ast_config_load("adsi.conf", config_flags);
01090    if (conf == CONFIG_STATUS_FILEMISSING || conf == CONFIG_STATUS_FILEUNCHANGED || conf == CONFIG_STATUS_FILEINVALID) {
01091       return;
01092    }
01093    for (v = ast_variable_browse(conf, "intro"); v; v = v->next) {
01094       if (!strcasecmp(v->name, "alignment")) {
01095          alignment = str2align(v->value);
01096       } else if (!strcasecmp(v->name, "greeting")) {
01097          if (x < ADSI_MAX_INTRO) {
01098             aligns[x] = alignment;
01099             ast_copy_string(intro[x], v->value, sizeof(intro[x]));
01100             x++;
01101          }
01102       } else if (!strcasecmp(v->name, "maxretries")) {
01103          if (atoi(v->value) > 0) {
01104             maxretries = atoi(v->value);
01105          }
01106       }
01107    }
01108    if (x) {
01109       total = x;
01110    }
01111 
01112    x = 0;
01113    for (v = ast_variable_browse(conf, "speeddial"); v; v = v->next) {
01114       char buf[3 * SPEEDDIAL_MAX_LEN];
01115       char *stringp = buf;
01116       ast_copy_string(buf, v->value, sizeof(buf));
01117       name = strsep(&stringp, ",");
01118       sname = strsep(&stringp, ",");
01119       if (!sname) {
01120          sname = name;
01121       }
01122       if (x < ADSI_MAX_SPEED_DIAL) {
01123          ast_copy_string(speeddial[x][0], v->name, sizeof(speeddial[x][0]));
01124          ast_copy_string(speeddial[x][1], name, 18);
01125          ast_copy_string(speeddial[x][2], sname, 7);
01126          x++;
01127       }
01128    }
01129    if (x) {
01130       speeds = x;
01131    }
01132    ast_config_destroy(conf);
01133 
01134    return;
01135 }

int AST_OPTIONAL_API_NAME() ast_adsi_available ( struct ast_channel chan  ) 

Returns non-zero if Channel does or might support ADSI.

Parameters:
chan Channel to check

Definition at line 788 of file res_adsi.c.

References ast_channel::adsicpe, AST_ADSI_AVAILABLE, and AST_ADSI_UNKNOWN.

Referenced by adsi_begin(), adsi_delete(), adsi_exec(), adsi_folders(), adsi_goodbye(), adsi_login(), adsi_message(), adsi_password(), adsi_status(), adsi_status2(), park_call_full(), vm_newuser(), vm_options(), and vm_tempgreeting().

00789 {
00790    int cpe = chan->adsicpe & 0xff;
00791    if ((cpe == AST_ADSI_AVAILABLE) ||
00792        (cpe == AST_ADSI_UNKNOWN)) {
00793       return 1;
00794    }
00795    return 0;
00796 }

int AST_OPTIONAL_API_NAME() ast_adsi_begin_download ( struct ast_channel chan,
char *  service,
unsigned char *  fdn,
unsigned char *  sec,
int  version 
)

Definition at line 331 of file res_adsi.c.

References ADSI_MSG_DOWNLOAD, ast_adsi_download_connect(), ast_adsi_transmit_message_full(), ast_debug, ast_readstring(), and version.

Referenced by adsi_load_vmail(), and adsi_prog().

00332 {
00333    int bytes = 0;
00334    unsigned char buf[256];
00335    char ack[2];
00336 
00337    /* Setup the resident soft key stuff, a piece at a time */
00338    /* Upload what scripts we can for voicemail ahead of time */
00339    bytes += ast_adsi_download_connect(buf + bytes, service, fdn, sec, version);
00340    if (ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
00341       return -1;
00342    }
00343    if (ast_readstring(chan, ack, 1, 10000, 10000, "")) {
00344       return -1;
00345    }
00346    if (ack[0] == 'B') {
00347       return 0;
00348    }
00349    ast_debug(1, "Download was denied by CPE\n");
00350    return -1;
00351 }

int AST_OPTIONAL_API_NAME() ast_adsi_channel_restore ( struct ast_channel chan  ) 

Restore ADSI initialization (for applications that play with ADSI and want to restore it to normal. If you touch "INFO" then you have to use the ast_adsi_channel_init again instead.

Parameters:
chan Channel to restore
Return values:
0 on success (or adsi unavailable)
-1 on hangup

Definition at line 950 of file res_adsi.c.

References ADSI_INFO_PAGE, ADSI_MSG_DISPLAY, ADSI_SPEED_DIAL, ast_adsi_set_keys(), ast_adsi_set_line(), and ast_adsi_transmit_message_full().

00951 {
00952    unsigned char dsp[256] = "", keyd[6] = "";
00953    int bytes, x;
00954 
00955    /* Start with initial display setup */
00956    bytes = 0;
00957    bytes += ast_adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
00958 
00959    /* Prepare key setup messages */
00960 
00961    if (speeds) {
00962       for (x = 0; x < speeds; x++) {
00963          keyd[x] = ADSI_SPEED_DIAL + x;
00964       }
00965       bytes += ast_adsi_set_keys(dsp + bytes, keyd);
00966    }
00967    ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0);
00968    return 0;
00969 
00970 }

int AST_OPTIONAL_API_NAME() ast_adsi_clear_screen ( unsigned char *  buf  ) 

Definition at line 756 of file res_adsi.c.

References ADSI_CLEAR_SCREEN.

00757 {
00758    int bytes = 0;
00759 
00760    /* Message type */
00761    buf[bytes++] = ADSI_CLEAR_SCREEN;
00762 
00763    /* Reserve space for length */
00764    bytes++;
00765 
00766    buf[1] = bytes - 2;
00767    return bytes;
00768 
00769 }

int AST_OPTIONAL_API_NAME() ast_adsi_clear_soft_keys ( unsigned char *  buf  ) 

Definition at line 741 of file res_adsi.c.

References ADSI_CLEAR_SOFTKEY.

00742 {
00743    int bytes = 0;
00744 
00745    /* Message type */
00746    buf[bytes++] = ADSI_CLEAR_SOFTKEY;
00747 
00748    /* Reserve space for length */
00749    bytes++;
00750 
00751    buf[1] = bytes - 2;
00752    return bytes;
00753 
00754 }

int AST_OPTIONAL_API_NAME() ast_adsi_connect_session ( unsigned char *  buf,
unsigned char *  fdn,
int  ver 
)

Connects an ADSI Display Session.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
fdn Optional 4 byte Feature Download Number (for loading soft keys)
ver Optional version number (0-255, or -1 to omit)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 500 of file res_adsi.c.

References ADSI_CONNECT_SESSION.

Referenced by ast_adsi_load_session().

00501 {
00502    int bytes = 0, x;
00503 
00504    /* Message type */
00505    buf[bytes++] = ADSI_CONNECT_SESSION;
00506 
00507    /* Reserve space for length */
00508    bytes++;
00509 
00510    if (fdn) {
00511       for (x = 0; x < 4; x++) {
00512          buf[bytes++] = fdn[x];
00513       }
00514       if (ver > -1) {
00515          buf[bytes++] = ver & 0xff;
00516       }
00517    }
00518 
00519    buf[1] = bytes - 2;
00520    return bytes;
00521 
00522 }

int AST_OPTIONAL_API_NAME() ast_adsi_data_mode ( unsigned char *  buf  ) 

Puts CPE in data mode.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 726 of file res_adsi.c.

References ADSI_SWITCH_TO_DATA.

Referenced by adsi_load_vmail(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), and ast_adsi_load_session().

00727 {
00728    int bytes = 0;
00729 
00730    /* Message type */
00731    buf[bytes++] = ADSI_SWITCH_TO_DATA;
00732 
00733    /* Reserve space for length */
00734    bytes++;
00735 
00736    buf[1] = bytes - 2;
00737    return bytes;
00738 
00739 }

int AST_OPTIONAL_API_NAME() ast_adsi_disconnect_session ( unsigned char *  buf  ) 

Disconnects a running session.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 556 of file res_adsi.c.

References ADSI_DISC_SESSION.

Referenced by ast_adsi_unload_session().

00557 {
00558    int bytes = 0;
00559 
00560    /* Message type */
00561    buf[bytes++] = ADSI_DISC_SESSION;
00562 
00563    /* Reserve space for length */
00564    bytes++;
00565 
00566    buf[1] = bytes - 2;
00567    return bytes;
00568 
00569 }

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

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
page Page to load (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
line Line number to load (1-4 for Comm page, 1-33 for info page)
just Line justification (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CENT, ADSI_JUST_IND)
wrap Wrap (1 = yes, 0 = no)
col1 Text to place in first column
col2 Text to place in second column
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 813 of file res_adsi.c.

References ADSI_LOAD_VIRTUAL_DISP, and ccopy().

Referenced by adsi_folders(), adsi_goodbye(), adsi_load_vmail(), adsi_login(), adsi_logo(), adsi_message(), adsi_prog(), adsi_status(), adsi_status2(), ast_adsi_print(), vm_newuser(), vm_options(), and vm_tempgreeting().

00815 {
00816    int bytes = 0;
00817 
00818    /* Sanity check line number */
00819 
00820    if (page) {
00821       if (line > 4) return -1;
00822    } else {
00823       if (line > 33) return -1;
00824    }
00825 
00826    if (line < 1) {
00827       return -1;
00828    }
00829    /* Parameter type */
00830    buf[bytes++] = ADSI_LOAD_VIRTUAL_DISP;
00831 
00832    /* Reserve space for size */
00833    bytes++;
00834 
00835    /* Page and wrap indicator */
00836    buf[bytes++] = ((page & 0x1) << 7) | ((wrap & 0x1) << 6) | (line & 0x3f);
00837 
00838    /* Justification */
00839    buf[bytes++] = (just & 0x3) << 5;
00840 
00841    /* Omit highlight mode definition */
00842    buf[bytes++] = 0xff;
00843 
00844    /* Primary column */
00845    bytes+= ccopy(buf + bytes, (unsigned char *)col1, 20);
00846 
00847    /* Delimiter */
00848    buf[bytes++] = 0xff;
00849 
00850    /* Secondary column */
00851    bytes += ccopy(buf + bytes, (unsigned char *)col2, 20);
00852 
00853    /* Update length */
00854    buf[1] = bytes - 2;
00855 
00856    return bytes;
00857 
00858 }

int AST_OPTIONAL_API_NAME() ast_adsi_download_connect ( unsigned char *  buf,
char *  service,
unsigned char *  fdn,
unsigned char *  sec,
int  ver 
)

Begin an ADSI script download.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
service a 1-18 byte name of the feature
fdn 4 byte Feature Download Number (for loading soft keys)
sec 4 byte vendor security code
ver version number (0-255, or -1 to omit)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 524 of file res_adsi.c.

References ADSI_DOWNLOAD_CONNECT, and ccopy().

Referenced by ast_adsi_begin_download().

00525 {
00526    int bytes = 0, x;
00527 
00528    /* Message type */
00529    buf[bytes++] = ADSI_DOWNLOAD_CONNECT;
00530 
00531    /* Reserve space for length */
00532    bytes++;
00533 
00534    /* Primary column */
00535    bytes+= ccopy(buf + bytes, (unsigned char *)service, 18);
00536 
00537    /* Delimiter */
00538    buf[bytes++] = 0xff;
00539 
00540    for (x = 0; x < 4; x++) {
00541       buf[bytes++] = fdn[x];
00542    }
00543 
00544    for (x = 0; x < 4; x++) {
00545       buf[bytes++] = sec[x];
00546    }
00547 
00548    buf[bytes++] = ver & 0xff;
00549 
00550    buf[1] = bytes - 2;
00551 
00552    return bytes;
00553 
00554 }

int AST_OPTIONAL_API_NAME() ast_adsi_download_disconnect ( unsigned char *  buf  ) 

Disconnects (and hopefully saves) a downloaded script.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 798 of file res_adsi.c.

References ADSI_DOWNLOAD_DISC.

Referenced by adsi_load_vmail(), and ast_adsi_end_download().

00799 {
00800    int bytes = 0;
00801 
00802    /* Message type */
00803    buf[bytes++] = ADSI_DOWNLOAD_DISC;
00804 
00805    /* Reserve space for length */
00806    bytes++;
00807 
00808    buf[1] = bytes - 2;
00809    return bytes;
00810 
00811 }

int AST_OPTIONAL_API_NAME() ast_adsi_end_download ( struct ast_channel chan  ) 

Definition at line 353 of file res_adsi.c.

References ADSI_MSG_DOWNLOAD, ast_adsi_download_disconnect(), and ast_adsi_transmit_message_full().

Referenced by adsi_load_vmail(), and adsi_prog().

00354 {
00355    int bytes = 0;
00356    unsigned char buf[256];
00357 
00358    /* Setup the resident soft key stuff, a piece at a time */
00359    /* Upload what scripts we can for voicemail ahead of time */
00360    bytes += ast_adsi_download_disconnect(buf + bytes);
00361    if (ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
00362       return -1;
00363    }
00364    return 0;
00365 }

int AST_OPTIONAL_API_NAME() ast_adsi_get_cpeid ( struct ast_channel chan,
unsigned char *  cpeid,
int  voice 
)

Get CPE ID from an attached ADSI compatible CPE. Returns 1 on success, storing 4 bytes of CPE ID at buf or -1 on hangup, or 0 if there was no hangup but it failed to find the device ID. Returns to voice mode if "voice" is non-zero.

Definition at line 628 of file res_adsi.c.

References ADSI_MSG_DISPLAY, ast_adsi_data_mode(), ast_adsi_query_cpeid(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_adsi_voice_mode(), ast_log(), ast_waitfordigit(), and LOG_WARNING.

Referenced by cpeid_exec().

00629 {
00630    unsigned char buf[256] = "";
00631    int bytes = 0, res;
00632 
00633    bytes += ast_adsi_data_mode(buf);
00634    ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00635 
00636    bytes = 0;
00637    bytes += ast_adsi_query_cpeid(buf);
00638    ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00639 
00640    /* Get response */
00641    res = ast_adsi_read_encoded_dtmf(chan, cpeid, 4);
00642    if (res != 4) {
00643       ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
00644       res = 0;
00645    } else {
00646       res = 1;
00647    }
00648 
00649    if (voice) {
00650       bytes = 0;
00651       bytes += ast_adsi_voice_mode(buf, 0);
00652       ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00653       /* Ignore the resulting DTMF B announcing it's in voice mode */
00654       ast_waitfordigit(chan, 1000);
00655    }
00656    return res;
00657 }

int AST_OPTIONAL_API_NAME() ast_adsi_get_cpeinfo ( struct ast_channel chan,
int *  width,
int *  height,
int *  buttons,
int  voice 
)

Definition at line 659 of file res_adsi.c.

References ADSI_MSG_DISPLAY, ast_adsi_data_mode(), ast_adsi_query_cpeinfo(), ast_adsi_transmit_message_full(), ast_adsi_voice_mode(), ast_log(), ast_readstring(), ast_waitfordigit(), and LOG_WARNING.

Referenced by cpeid_exec().

00660 {
00661    unsigned char buf[256] = "";
00662    int bytes = 0, res;
00663 
00664    bytes += ast_adsi_data_mode(buf);
00665    ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00666 
00667    bytes = 0;
00668    bytes += ast_adsi_query_cpeinfo(buf);
00669    ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00670 
00671    /* Get width */
00672    if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
00673       return res;
00674    }
00675    if (strlen((char *) buf) != 2) {
00676       ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
00677       res = 0;
00678    } else {
00679       res = 1;
00680    }
00681    if (width) {
00682       *width = atoi((char *) buf);
00683    }
00684    /* Get height */
00685    memset(buf, 0, sizeof(buf));
00686    if (res) {
00687       if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
00688          return res;
00689       }
00690       if (strlen((char *) buf) != 2) {
00691          ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
00692          res = 0;
00693       } else {
00694          res = 1;
00695       }
00696       if (height) {
00697          *height = atoi((char *) buf);
00698       }
00699    }
00700    /* Get buttons */
00701    memset(buf, 0, sizeof(buf));
00702    if (res) {
00703       if ((res = ast_readstring(chan, (char *) buf, 1, 1000, 500, "")) < 0) {
00704          return res;
00705       }
00706       if (strlen((char *) buf) != 1) {
00707          ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
00708          res = 0;
00709       } else {
00710          res = 1;
00711       }
00712       if (buttons) {
00713          *buttons = atoi((char *) buf);
00714       }
00715    }
00716    if (voice) {
00717       bytes = 0;
00718       bytes += ast_adsi_voice_mode(buf, 0);
00719       ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00720       /* Ignore the resulting DTMF B announcing it's in voice mode */
00721       ast_waitfordigit(chan, 1000);
00722    }
00723    return res;
00724 }

int AST_OPTIONAL_API_NAME() ast_adsi_input_control ( unsigned char *  buf,
int  page,
int  line,
int  display,
int  format,
int  just 
)

Set input information.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
page Which page to input on (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
line Line number to input on
display Set to zero to obscure input, or 1 to leave visible
format Format number to use (0-7)
just Justification (left, right center, indent)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 860 of file res_adsi.c.

References ADSI_INPUT_CONTROL.

Referenced by adsi_login(), and adsi_password().

00861 {
00862    int bytes = 0;
00863 
00864    if (page) {
00865       if (line > 4) return -1;
00866    } else {
00867       if (line > 33) return -1;
00868    }
00869 
00870    if (line < 1) {
00871       return -1;
00872    }
00873 
00874    buf[bytes++] = ADSI_INPUT_CONTROL;
00875    bytes++;
00876    buf[bytes++] = ((page & 1) << 7) | (line & 0x3f);
00877    buf[bytes++] = ((display & 1) << 7) | ((just & 0x3) << 4) | (format & 0x7);
00878 
00879    buf[1] = bytes - 2;
00880    return bytes;
00881 }

int AST_OPTIONAL_API_NAME() ast_adsi_input_format ( unsigned char *  buf,
int  num,
int  dir,
int  wrap,
char *  format1,
char *  format2 
)

Set input format.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
num Which format we are setting
dir Which direction (ADSI_DIR_FROM_LEFT or ADSI_DIR_FROM_RIGHT)
wrap Set to 1 to permit line wrap, or 0 if not
format1 Format for column 1
format2 Format for column 2
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 883 of file res_adsi.c.

References ADSI_INPUT_FORMAT, ast_strlen_zero(), and ccopy().

Referenced by adsi_login(), and adsi_password().

00884 {
00885    int bytes = 0;
00886 
00887    if (ast_strlen_zero((char *) format1)) {
00888       return -1;
00889    }
00890 
00891    buf[bytes++] = ADSI_INPUT_FORMAT;
00892    bytes++;
00893    buf[bytes++] = ((dir & 1) << 7) | ((wrap & 1) << 6) | (num & 0x7);
00894    bytes += ccopy(buf + bytes, (unsigned char *) format1, 20);
00895    buf[bytes++] = 0xff;
00896    if (!ast_strlen_zero(format2)) {
00897       bytes += ccopy(buf + bytes, (unsigned char *) format2, 20);
00898    }
00899    buf[1] = bytes - 2;
00900    return bytes;
00901 }

int AST_OPTIONAL_API_NAME() 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, or 0-255 for a specific version.

Parameters:
chan Channel to test for loaded app
app Four character app name (must be unique to your application)
ver optional version number
data Non-zero if you want to be put in data mode
Return values:
0 if scripts is not loaded or not an ADSI CPE
-1 on hangup
1 if script already loaded.

Definition at line 992 of file res_adsi.c.

References ADSI_MSG_DISPLAY, ast_adsi_connect_session(), ast_adsi_data_mode(), ast_adsi_transmit_message_full(), ast_debug, ast_log(), ast_readstring(), ast_channel::data, and LOG_WARNING.

Referenced by adsi_announce_park(), adsi_begin(), adsi_load_vmail(), adsi_prog(), and cpeid_exec().

00993 {
00994    unsigned char dsp[256] = "";
00995    int bytes = 0, res;
00996    char resp[2];
00997 
00998    /* Connect to session */
00999    bytes += ast_adsi_connect_session(dsp + bytes, app, ver);
01000 
01001    if (data) {
01002       bytes += ast_adsi_data_mode(dsp + bytes);
01003    }
01004 
01005    /* Prepare key setup messages */
01006    if (ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
01007       return -1;
01008    }
01009    if (app) {
01010       if ((res = ast_readstring(chan, resp, 1, 1200, 1200, "")) < 0) {
01011          return -1;
01012       }
01013       if (res) {
01014          ast_debug(1, "No response from CPE about version.  Assuming not there.\n");
01015          return 0;
01016       }
01017       if (!strcmp(resp, "B")) {
01018          ast_debug(1, "CPE has script '%s' version %d already loaded\n", app, ver);
01019          return 1;
01020       } else if (!strcmp(resp, "A")) {
01021          ast_debug(1, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
01022       } else {
01023          ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
01024       }
01025    } else
01026       return 1;
01027    return 0;
01028 
01029 }

int AST_OPTIONAL_API_NAME() ast_adsi_load_soft_key ( unsigned char *  buf,
int  key,
const char *  llabel,
const char *  slabel,
char *  ret,
int  data 
)

Creates "load soft key" parameters.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
key Key code from 2 to 33, for which key we are loading
llabel Long label for key (1-18 bytes)
slabel Short label for key (1-7 bytes)
ret Optional return sequence (NULL for none)
data whether to put CPE in data mode before sending digits
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 459 of file res_adsi.c.

References ADSI_LOAD_SOFTKEY, ADSI_SWITCH_TO_DATA2, ccopy(), and ast_channel::data.

Referenced by adsi_load_vmail(), and adsi_login().

00460 {
00461    int bytes = 0;
00462 
00463    /* Abort if invalid key specified */
00464    if ((key < 2) || (key > 33)) {
00465       return -1;
00466    }
00467 
00468    buf[bytes++] = ADSI_LOAD_SOFTKEY;
00469    /* Reserve for length */
00470    bytes++;
00471    /* Which key */
00472    buf[bytes++] = key;
00473 
00474    /* Carefully copy long label */
00475    bytes += ccopy(buf + bytes, (const unsigned char *)llabel, 18);
00476 
00477    /* Place delimiter */
00478    buf[bytes++] = 0xff;
00479 
00480    /* Short label */
00481    bytes += ccopy(buf + bytes, (const unsigned char *)slabel, 7);
00482 
00483 
00484    /* If specified, copy return string */
00485    if (ret) {
00486       /* Place delimiter */
00487       buf[bytes++] = 0xff;
00488       if (data) {
00489          buf[bytes++] = ADSI_SWITCH_TO_DATA2;
00490       }
00491       /* Carefully copy return string */
00492       bytes += ccopy(buf + bytes, (const unsigned char *)ret, 20);
00493 
00494    }
00495    /* Replace parameter length */
00496    buf[1] = bytes - 2;
00497    return bytes;
00498 }

int AST_OPTIONAL_API_NAME() ast_adsi_print ( struct ast_channel chan,
char **  lines,
int *  align,
int  voice 
)

Display some stuff on the screen.

Parameters:
chan Channel to display on
lines NULL-terminated list of things to print (no more than 4 recommended)
align list of alignments to use (ADSI_JUST_LEFT, ADSI_JUST_RIGHT, ADSI_JUST_CEN, etc..)
voice whether to jump into voice mode when finished
Return values:
0 on success (or adsi unavailable)
-1 on hangup

Definition at line 972 of file res_adsi.c.

References ADSI_INFO_PAGE, ADSI_MSG_DISPLAY, ast_adsi_display(), ast_adsi_set_line(), ast_adsi_transmit_message_full(), ast_adsi_voice_mode(), and ast_waitfordigit().

Referenced by adsi_announce_park(), and cpeid_setstatus().

00973 {
00974    unsigned char buf[4096];
00975    int bytes = 0, res, x;
00976 
00977    for (x = 0; lines[x]; x++) {
00978       bytes += ast_adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, alignments[x], 0, lines[x], "");
00979    }
00980    bytes += ast_adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
00981    if (voice) {
00982       bytes += ast_adsi_voice_mode(buf + bytes, 0);
00983    }
00984    res = ast_adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00985    if (voice) {
00986       /* Ignore the resulting DTMF B announcing it's in voice mode */
00987       ast_waitfordigit(chan, 1000);
00988    }
00989    return res;
00990 }

int AST_OPTIONAL_API_NAME() ast_adsi_query_cpeid ( unsigned char *  buf  ) 

Build Query CPE ID of equipment. Returns number of bytes added to message

Definition at line 571 of file res_adsi.c.

References ADSI_QUERY_CPEID.

Referenced by ast_adsi_get_cpeid().

00572 {
00573    int bytes = 0;
00574    buf[bytes++] = ADSI_QUERY_CPEID;
00575    /* Reserve space for length */
00576    bytes++;
00577    buf[1] = bytes - 2;
00578    return bytes;
00579 }

int AST_OPTIONAL_API_NAME() ast_adsi_query_cpeinfo ( unsigned char *  buf  ) 

Definition at line 581 of file res_adsi.c.

References ADSI_QUERY_CONFIG.

Referenced by ast_adsi_get_cpeinfo().

00582 {
00583    int bytes = 0;
00584    buf[bytes++] = ADSI_QUERY_CONFIG;
00585    /* Reserve space for length */
00586    bytes++;
00587    buf[1] = bytes - 2;
00588    return bytes;
00589 }

int AST_OPTIONAL_API_NAME() ast_adsi_read_encoded_dtmf ( struct ast_channel chan,
unsigned char *  buf,
int  maxlen 
)

Read some encoded DTMF data. Returns number of bytes received

Definition at line 591 of file res_adsi.c.

References ast_waitfordigit().

Referenced by ast_adsi_get_cpeid().

00592 {
00593    int bytes = 0, res, gotstar = 0, pos = 0;
00594    unsigned char current = 0;
00595 
00596    memset(buf, 0, sizeof(buf));
00597 
00598    while (bytes <= maxlen) {
00599       /* Wait up to a second for a digit */
00600       if (!(res = ast_waitfordigit(chan, 1000))) {
00601          break;
00602       }
00603       if (res == '*') {
00604          gotstar = 1;
00605          continue;
00606       }
00607       /* Ignore anything other than a digit */
00608       if ((res < '0') || (res > '9')) {
00609          continue;
00610       }
00611       res -= '0';
00612       if (gotstar) {
00613          res += 9;
00614       }
00615       if (pos)  {
00616          pos = 0;
00617          buf[bytes++] = (res << 4) | current;
00618       } else {
00619          pos = 1;
00620          current = res;
00621       }
00622       gotstar = 0;
00623    }
00624 
00625    return bytes;
00626 }

int AST_OPTIONAL_API_NAME() ast_adsi_set_keys ( unsigned char *  buf,
unsigned char *  keys 
)

Set which soft keys should be displayed.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
keys Array of 8 unsigned chars with the key numbers, may be OR'd with ADSI_KEY_HILITE But remember, the last two keys aren't real keys, they're for scrolling
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 903 of file res_adsi.c.

References ADSI_INIT_SOFTKEY_LINE.

Referenced by adsi_delete(), adsi_folders(), adsi_login(), adsi_message(), adsi_password(), adsi_status(), adsi_status2(), and ast_adsi_channel_restore().

00904 {
00905    int bytes = 0, x;
00906 
00907    /* Message type */
00908    buf[bytes++] = ADSI_INIT_SOFTKEY_LINE;
00909    /* Space for size */
00910    bytes++;
00911    /* Key definitions */
00912    for (x = 0; x < 6; x++) {
00913       buf[bytes++] = (keys[x] & 0x3f) ? keys[x] : (keys[x] | 0x1);
00914    }
00915    buf[1] = bytes - 2;
00916    return bytes;
00917 }

int AST_OPTIONAL_API_NAME() ast_adsi_set_line ( unsigned char *  buf,
int  page,
int  line 
)

Sets the current line and page.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
page Which page (ADSI_COMM_PAGE or ADSI_INFO_PAGE)
line Line number (1-33 for info page, 1-4 for comm page)
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 919 of file res_adsi.c.

References ADSI_LINE_CONTROL.

Referenced by adsi_folders(), adsi_goodbye(), adsi_load_vmail(), adsi_login(), adsi_message(), adsi_password(), adsi_prog(), adsi_status(), adsi_status2(), ast_adsi_channel_restore(), ast_adsi_print(), vm_newuser(), vm_options(), and vm_tempgreeting().

00920 {
00921    int bytes = 0;
00922 
00923    /* Sanity check line number */
00924 
00925    if (page) {
00926       if (line > 4) return -1;
00927    } else {
00928       if (line > 33) return -1;
00929    }
00930 
00931    if (line < 1) {
00932       return -1;
00933    }
00934    /* Parameter type */
00935    buf[bytes++] = ADSI_LINE_CONTROL;
00936 
00937    /* Reserve space for size */
00938    bytes++;
00939 
00940    /* Page and line */
00941    buf[bytes++] = ((page & 0x1) << 7) | (line & 0x3f);
00942 
00943    buf[1] = bytes - 2;
00944    return bytes;
00945 }

int AST_OPTIONAL_API_NAME() ast_adsi_transmit_message ( struct ast_channel chan,
unsigned char *  msg,
int  msglen,
int  msgtype 
)

int AST_OPTIONAL_API_NAME() ast_adsi_transmit_message_full ( struct ast_channel chan,
unsigned char *  msg,
int  msglen,
int  msgtype,
int  dowait 
)

Definition at line 367 of file res_adsi.c.

References __adsi_transmit_messages(), ADSI_FLAG_DATAMODE, ADSI_SWITCH_TO_DATA, ADSI_SWITCH_TO_VOICE, ast_channel::adsicpe, ast_debug, ast_format_copy(), AST_FORMAT_ULAW, ast_getformatname(), ast_log(), ast_safe_sleep(), ast_set_read_format(), ast_set_read_format_by_id(), ast_set_write_format(), ast_set_write_format_by_id(), ast_stopstream(), ast_waitfordigit(), ast_format::id, LOG_WARNING, ast_channel::readformat, and ast_channel::writeformat.

Referenced by ast_adsi_begin_download(), ast_adsi_channel_restore(), ast_adsi_end_download(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_adsi_print(), ast_adsi_transmit_message(), and ast_adsi_unload_session().

00368 {
00369    unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
00370    int msglens[5], msgtypes[5], newdatamode = (chan->adsicpe & ADSI_FLAG_DATAMODE), res, x, waitforswitch = 0;
00371    struct ast_format writeformat;
00372    struct ast_format readformat;
00373 
00374    ast_format_copy(&writeformat, &chan->writeformat);
00375    ast_format_copy(&readformat, &chan->readformat);
00376 
00377    for (x = 0; x < msglen; x += (msg[x+1]+2)) {
00378       if (msg[x] == ADSI_SWITCH_TO_DATA) {
00379          ast_debug(1, "Switch to data is sent!\n");
00380          waitforswitch++;
00381          newdatamode = ADSI_FLAG_DATAMODE;
00382       }
00383 
00384       if (msg[x] == ADSI_SWITCH_TO_VOICE) {
00385          ast_debug(1, "Switch to voice is sent!\n");
00386          waitforswitch++;
00387          newdatamode = 0;
00388       }
00389    }
00390    msgs[0] = msg;
00391 
00392    msglens[0] = msglen;
00393    msgtypes[0] = msgtype;
00394 
00395    if (msglen > 253) {
00396       ast_log(LOG_WARNING, "Can't send ADSI message of %d bytes, too large\n", msglen);
00397       return -1;
00398    }
00399 
00400    ast_stopstream(chan);
00401 
00402    if (ast_set_write_format_by_id(chan, AST_FORMAT_ULAW)) {
00403       ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
00404       return -1;
00405    }
00406 
00407    if (ast_set_read_format_by_id(chan, AST_FORMAT_ULAW)) {
00408       ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
00409       if (writeformat.id) {
00410          if (ast_set_write_format(chan, &writeformat)) {
00411             ast_log(LOG_WARNING, "Unable to restore write format to %s\n", ast_getformatname(&writeformat));
00412          }
00413       }
00414       return -1;
00415    }
00416    res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
00417 
00418    if (dowait) {
00419       ast_debug(1, "Wait for switch is '%d'\n", waitforswitch);
00420       while (waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) {
00421          res = 0;
00422          ast_debug(1, "Waiting for 'B'...\n");
00423       }
00424    }
00425 
00426    if (!res) {
00427       chan->adsicpe = (chan->adsicpe & ~ADSI_FLAG_DATAMODE) | newdatamode;
00428    }
00429 
00430    if (writeformat.id) {
00431       ast_set_write_format(chan, &writeformat);
00432    }
00433    if (readformat.id) {
00434       ast_set_read_format(chan, &readformat);
00435    }
00436 
00437    if (!res) {
00438       res = ast_safe_sleep(chan, 100 );
00439    }
00440    return res;
00441 }

int AST_OPTIONAL_API_NAME() ast_adsi_unload_session ( struct ast_channel chan  ) 

Definition at line 1031 of file res_adsi.c.

References ADSI_MSG_DISPLAY, ast_adsi_disconnect_session(), ast_adsi_transmit_message_full(), and ast_adsi_voice_mode().

Referenced by adsi_prog(), cpeid_exec(), park_call_full(), and vm_execmain().

01032 {
01033    unsigned char dsp[256] = "";
01034    int bytes = 0;
01035 
01036    /* Connect to session */
01037    bytes += ast_adsi_disconnect_session(dsp + bytes);
01038    bytes += ast_adsi_voice_mode(dsp + bytes, 0);
01039 
01040    /* Prepare key setup messages */
01041    if (ast_adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
01042       return -1;
01043    }
01044 
01045    return 0;
01046 }

int AST_OPTIONAL_API_NAME() ast_adsi_voice_mode ( unsigned char *  buf,
int  when 
)

Puts CPE in voice mode.

Parameters:
buf Character buffer to create parameter in (must have at least 256 free)
when (a time in seconds) to make the switch
Return values:
number of bytes added to buffer
-1 on error.

Definition at line 771 of file res_adsi.c.

References ADSI_SWITCH_TO_VOICE.

Referenced by adsi_delete(), adsi_folders(), adsi_goodbye(), adsi_load_vmail(), adsi_login(), adsi_message(), adsi_password(), adsi_status(), adsi_status2(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_unload_session(), vm_newuser(), vm_options(), and vm_tempgreeting().

00772 {
00773    int bytes = 0;
00774 
00775    /* Message type */
00776    buf[bytes++] = ADSI_SWITCH_TO_VOICE;
00777 
00778    /* Reserve space for length */
00779    bytes++;
00780 
00781    buf[bytes++] = when & 0x7f;
00782 
00783    buf[1] = bytes - 2;
00784    return bytes;
00785 
00786 }

static int ccopy ( unsigned char *  dst,
const unsigned char *  src,
int  max 
) [inline, static]

Definition at line 448 of file res_adsi.c.

Referenced by ast_adsi_display(), ast_adsi_download_connect(), ast_adsi_input_format(), and ast_adsi_load_soft_key().

00449 {
00450    int x = 0;
00451    /* Carefully copy the requested data */
00452    while ((x < max) && src[x] && (src[x] != 0xff)) {
00453       dst[x] = src[x];
00454       x++;
00455    }
00456    return x;
00457 }

static void init_state ( void   )  [static]

Definition at line 1061 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_MAX_INTRO, and ast_copy_string().

Referenced by adsi_load().

01062 {
01063    int x;
01064 
01065    for (x = 0; x < ADSI_MAX_INTRO; x++) {
01066       aligns[x] = ADSI_JUST_CENT;
01067    }
01068    ast_copy_string(intro[0], "Welcome to the", sizeof(intro[0]));
01069    ast_copy_string(intro[1], "Asterisk", sizeof(intro[1]));
01070    ast_copy_string(intro[2], "Open Source PBX", sizeof(intro[2]));
01071    total = 3;
01072    speeds = 0;
01073    for (x = 3; x < ADSI_MAX_INTRO; x++) {
01074       intro[x][0] = '\0';
01075    }
01076    memset(speeddial, 0, sizeof(speeddial));
01077    alignment = ADSI_JUST_CENT;
01078 }

static int load_module ( void   )  [static]

Definition at line 1143 of file res_adsi.c.

References adsi_load(), and AST_MODULE_LOAD_SUCCESS.

01144 {
01145    adsi_load(0);
01146    return AST_MODULE_LOAD_SUCCESS;
01147 }

static int reload ( void   )  [static]

Definition at line 1137 of file res_adsi.c.

References adsi_load().

01138 {
01139    adsi_load(1);
01140    return 0;
01141 }

static int str2align ( const char *  s  )  [static]

Definition at line 1048 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_JUST_IND, ADSI_JUST_LEFT, and ADSI_JUST_RIGHT.

Referenced by adsi_load().

01049 {
01050    if (!strncasecmp(s, "l", 1)) {
01051       return ADSI_JUST_LEFT;
01052    } else if (!strncasecmp(s, "r", 1)) {
01053       return ADSI_JUST_RIGHT;
01054    } else if (!strncasecmp(s, "i", 1)) {
01055       return ADSI_JUST_IND;
01056    } else {
01057       return ADSI_JUST_CENT;
01058    }
01059 }

static int unload_module ( void   )  [static]

Definition at line 1149 of file res_adsi.c.

01150 {
01151    /* Can't unload this once we're loaded */
01152    return -1;
01153 }


Variable Documentation

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

Definition at line 1160 of file res_adsi.c.

int alignment = 0 [static]

Definition at line 74 of file res_adsi.c.

int aligns[ADSI_MAX_INTRO] [static]

Definition at line 69 of file res_adsi.c.

Definition at line 1160 of file res_adsi.c.

char intro[ADSI_MAX_INTRO][20] [static]

Definition at line 68 of file res_adsi.c.

int maxretries = DEFAULT_ADSI_MAX_RETRIES [static]

Definition at line 63 of file res_adsi.c.

Referenced by ast_ivr_menu_run_internal(), and privacy_exec().

char speeddial[ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN] [static]

Definition at line 72 of file res_adsi.c.

int speeds = 0 [static]

Definition at line 948 of file res_adsi.c.

int total = 0 [static]


Generated on Sat Feb 11 06:36:19 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6