Wed Oct 28 15:49:13 2009

Asterisk developer's documentation


res_adsi.c File Reference

ADSI support. More...

#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <errno.h>
#include "asterisk.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/callerid.h"
#include "asterisk/logger.h"
#include "asterisk/fskmodem.h"
#include "asterisk/channel.h"
#include "asterisk/adsi.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/file.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 DEFAULT_ADSI_MAX_RETRIES   3

Functions

static int __adsi_transmit_messages (struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
int adsi_available (struct ast_channel *chan)
int adsi_begin_download (struct ast_channel *chan, char *service, unsigned char *fdn, unsigned char *sec, int version)
static int adsi_careful_send (struct ast_channel *chan, unsigned char *buf, int len, int *remainder)
int adsi_channel_restore (struct ast_channel *chan)
int adsi_clear_screen (unsigned char *buf)
int adsi_clear_soft_keys (unsigned char *buf)
int adsi_connect_session (unsigned char *buf, unsigned char *fdn, int ver)
int adsi_data_mode (unsigned char *buf)
int adsi_disconnect_session (unsigned char *buf)
int adsi_display (unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
int adsi_download_connect (unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
int adsi_download_disconnect (unsigned char *buf)
int adsi_end_download (struct ast_channel *chan)
static int adsi_generate (unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, int codec)
int adsi_get_cpeid (struct ast_channel *chan, unsigned char *cpeid, int voice)
int adsi_get_cpeinfo (struct ast_channel *chan, int *width, int *height, int *buttons, int voice)
int adsi_input_control (unsigned char *buf, int page, int line, int display, int format, int just)
int adsi_input_format (unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
static void adsi_load (void)
int adsi_load_session (struct ast_channel *chan, unsigned char *app, int ver, int data)
int adsi_load_soft_key (unsigned char *buf, int key, char *llabel, char *slabel, char *ret, int data)
int adsi_print (struct ast_channel *chan, char **lines, int *aligns, int voice)
int adsi_query_cpeid (unsigned char *buf)
int adsi_query_cpeinfo (unsigned char *buf)
int adsi_read_encoded_dtmf (struct ast_channel *chan, unsigned char *buf, int maxlen)
int adsi_set_keys (unsigned char *buf, unsigned char *keys)
int adsi_set_line (unsigned char *buf, int page, int line)
int adsi_transmit_message (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
int adsi_transmit_message_full (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
int adsi_unload_session (struct ast_channel *chan)
int adsi_voice_mode (unsigned char *buf, int when)
static int ccopy (unsigned char *dst, unsigned char *src, int max)
char * description (void)
 Provides a description of the module.
static void init_state (void)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
int reload (void)
 Reload stuff.
static int str2align (char *s)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static int alignment = 0
static int aligns [ADSI_MAX_INTRO]
static char intro [ADSI_MAX_INTRO][20]
static int maxretries = DEFAULT_ADSI_MAX_RETRIES
static char speeddial [ADSI_MAX_SPEED_DIAL][3][20]
static int speeds = 0
static int total = 0


Detailed Description

ADSI support.

Definition in file res_adsi.c.


Define Documentation

#define ADSI_FLAG_DATAMODE   (1 << 8)

Definition at line 55 of file res_adsi.c.

Referenced by __adsi_transmit_messages(), and adsi_transmit_message_full().

#define ADSI_MAX_INTRO   20

Definition at line 52 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

#define ADSI_MAX_SPEED_DIAL   6

Definition at line 53 of file res_adsi.c.

Referenced by adsi_load().

#define ADSI_SPEED_DIAL   10

Definition at line 60 of file res_adsi.c.

Referenced by adsi_channel_restore().

#define DEFAULT_ADSI_MAX_RETRIES   3

Definition at line 50 of file res_adsi.c.


Function Documentation

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

Definition at line 190 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_undefer_dtmf(), AST_FORMAT_ULAW, AST_FRAME_DTMF, ast_frfree(), ast_gen_cas(), ast_log(), ast_read(), ast_readstring(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, and ast_frame::subclass.

Referenced by adsi_transmit_message_full().

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

int adsi_available ( struct ast_channel chan  ) 

Returns non-zero if Channel does or might support ADSI

Parameters:
chan Channel to check

Definition at line 762 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(), ast_park_call(), vm_newuser(), vm_options(), and vm_tempgreeting().

00763 {
00764    int cpe = chan->adsicpe & 0xff;
00765    if ((cpe == AST_ADSI_AVAILABLE) ||
00766        (cpe == AST_ADSI_UNKNOWN))
00767       return 1;
00768    return 0;
00769 }

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

Definition at line 319 of file res_adsi.c.

References adsi_download_connect(), ADSI_MSG_DOWNLOAD, adsi_transmit_message_full(), ast_log(), ast_readstring(), and LOG_DEBUG.

Referenced by adsi_load_vmail(), and adsi_prog().

00320 {
00321    int bytes;
00322    unsigned char buf[256];
00323    char ack[2];
00324    bytes = 0;
00325    /* Setup the resident soft key stuff, a piece at a time */
00326    /* Upload what scripts we can for voicemail ahead of time */
00327    bytes += adsi_download_connect(buf + bytes, service, fdn, sec, version);
00328    if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0))
00329       return -1;
00330    if (ast_readstring(chan, ack, 1, 10000, 10000, ""))
00331       return -1;
00332    if (ack[0] == 'B')
00333       return 0;
00334    ast_log(LOG_DEBUG, "Download was denied by CPE\n");
00335    return -1;
00336 }

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

Definition at line 119 of file res_adsi.c.

References AST_FORMAT_ULAW, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_waitfor(), ast_write(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::samples, and ast_frame::subclass.

Referenced by __adsi_transmit_messages().

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

int adsi_channel_restore ( struct ast_channel chan  ) 

Restore ADSI initialization (for applications that play with ADSI

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

Definition at line 920 of file res_adsi.c.

References ADSI_INFO_PAGE, ADSI_MSG_DISPLAY, adsi_set_keys(), adsi_set_line(), ADSI_SPEED_DIAL, adsi_transmit_message_full(), and dsp.

00921 {
00922    unsigned char dsp[256];
00923    int bytes;
00924    int x;
00925    unsigned char keyd[6];
00926 
00927    memset(dsp, 0, sizeof(dsp));
00928 
00929    /* Start with initial display setup */
00930    bytes = 0;
00931    bytes += adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
00932 
00933    /* Prepare key setup messages */
00934 
00935    if (speeds) {
00936       memset(keyd, 0, sizeof(keyd));
00937       for (x=0;x<speeds;x++) {
00938          keyd[x] = ADSI_SPEED_DIAL + x;
00939       }
00940       bytes += adsi_set_keys(dsp + bytes, keyd);
00941    }
00942    adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0);
00943    return 0;
00944 
00945 }

int adsi_clear_screen ( unsigned char *  buf  ) 

Definition at line 730 of file res_adsi.c.

References ADSI_CLEAR_SCREEN.

00731 {
00732    int bytes=0;
00733 
00734    /* Message type */
00735    buf[bytes++] = ADSI_CLEAR_SCREEN;
00736 
00737    /* Reserve space for length */
00738    bytes++;
00739 
00740    buf[1] = bytes - 2;
00741    return bytes;
00742 
00743 }

int adsi_clear_soft_keys ( unsigned char *  buf  ) 

Definition at line 715 of file res_adsi.c.

References ADSI_CLEAR_SOFTKEY.

00716 {
00717    int bytes=0;
00718 
00719    /* Message type */
00720    buf[bytes++] = ADSI_CLEAR_SOFTKEY;
00721 
00722    /* Reserve space for length */
00723    bytes++;
00724 
00725    buf[1] = bytes - 2;
00726    return bytes;
00727 
00728 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 480 of file res_adsi.c.

References ADSI_CONNECT_SESSION.

Referenced by adsi_load_session().

00481 {
00482    int bytes=0;
00483    int x;
00484 
00485    /* Message type */
00486    buf[bytes++] = ADSI_CONNECT_SESSION;
00487 
00488    /* Reserve space for length */
00489    bytes++;
00490 
00491    if (fdn) {
00492       for (x=0;x<4;x++)
00493          buf[bytes++] = fdn[x];
00494       if (ver > -1)
00495          buf[bytes++] = ver & 0xff;
00496    }
00497 
00498    buf[1] = bytes - 2;
00499    return bytes;
00500 
00501 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 700 of file res_adsi.c.

References ADSI_SWITCH_TO_DATA.

Referenced by adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_load_session(), and adsi_load_vmail().

00701 {
00702    int bytes=0;
00703 
00704    /* Message type */
00705    buf[bytes++] = ADSI_SWITCH_TO_DATA;
00706 
00707    /* Reserve space for length */
00708    bytes++;
00709 
00710    buf[1] = bytes - 2;
00711    return bytes;
00712 
00713 }

int adsi_disconnect_session ( unsigned char *  buf  ) 

Disconnects a running session

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

Definition at line 533 of file res_adsi.c.

References ADSI_DISC_SESSION.

Referenced by adsi_unload_session().

00534 {
00535    int bytes=0;
00536 
00537    /* Message type */
00538    buf[bytes++] = ADSI_DISC_SESSION;
00539 
00540    /* Reserve space for length */
00541    bytes++;
00542 
00543    buf[1] = bytes - 2;
00544    return bytes;
00545 
00546 }

int 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
Returns number of bytes added to buffer or -1 on error.

Definition at line 786 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_print(), adsi_prog(), adsi_status(), adsi_status2(), vm_newuser(), vm_options(), and vm_tempgreeting().

00788 {
00789    int bytes=0;
00790 
00791    /* Sanity check line number */
00792 
00793    if (page) {
00794       if (line > 4) return -1;
00795    } else {
00796       if (line > 33) return -1;
00797    }
00798 
00799    if (line < 1)
00800       return -1;
00801    /* Parameter type */
00802    buf[bytes++] = ADSI_LOAD_VIRTUAL_DISP;
00803    
00804    /* Reserve space for size */
00805    bytes++;
00806 
00807    /* Page and wrap indicator */
00808    buf[bytes++] = ((page & 0x1) << 7) | ((wrap & 0x1) << 6) | (line & 0x3f);
00809 
00810    /* Justification */
00811    buf[bytes++] = (just & 0x3) << 5;
00812 
00813    /* Omit highlight mode definition */
00814    buf[bytes++] = 0xff;
00815 
00816    /* Primary column */
00817    bytes+= ccopy(buf + bytes, (unsigned char *)col1, 20);
00818 
00819    /* Delimiter */
00820    buf[bytes++] = 0xff;
00821    
00822    /* Secondary column */
00823    bytes += ccopy(buf + bytes, (unsigned char *)col2, 20);
00824 
00825    /* Update length */
00826    buf[1] = bytes - 2;
00827    
00828    return bytes;
00829 
00830 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 503 of file res_adsi.c.

References ADSI_DOWNLOAD_CONNECT, and ccopy().

Referenced by adsi_begin_download().

00504 {
00505    int bytes=0;
00506    int x;
00507 
00508    /* Message type */
00509    buf[bytes++] = ADSI_DOWNLOAD_CONNECT;
00510 
00511    /* Reserve space for length */
00512    bytes++;
00513 
00514    /* Primary column */
00515    bytes+= ccopy(buf + bytes, (unsigned char *)service, 18);
00516 
00517    /* Delimiter */
00518    buf[bytes++] = 0xff;
00519    
00520    for (x=0;x<4;x++) {
00521       buf[bytes++] = fdn[x];
00522    }
00523    for (x=0;x<4;x++)
00524       buf[bytes++] = sec[x];
00525    buf[bytes++] = ver & 0xff;
00526 
00527    buf[1] = bytes - 2;
00528 
00529    return bytes;
00530 
00531 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 771 of file res_adsi.c.

References ADSI_DOWNLOAD_DISC.

Referenced by adsi_end_download(), and adsi_load_vmail().

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

int adsi_end_download ( struct ast_channel chan  ) 

Definition at line 338 of file res_adsi.c.

References adsi_download_disconnect(), ADSI_MSG_DOWNLOAD, and adsi_transmit_message_full().

Referenced by adsi_load_vmail(), and adsi_prog().

00339 {
00340    int bytes;
00341    unsigned char buf[256];
00342         bytes = 0;
00343         /* Setup the resident soft key stuff, a piece at a time */
00344         /* Upload what scripts we can for voicemail ahead of time */
00345         bytes += adsi_download_disconnect(buf + bytes);
00346    if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0))
00347       return -1;
00348    return 0;
00349 }

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

Definition at line 69 of file res_adsi.c.

References PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __adsi_transmit_messages().

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

int 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 603 of file res_adsi.c.

References adsi_data_mode(), ADSI_MSG_DISPLAY, adsi_query_cpeid(), adsi_read_encoded_dtmf(), adsi_transmit_message_full(), adsi_voice_mode(), ast_log(), ast_waitfordigit(), and LOG_WARNING.

Referenced by cpeid_exec().

00604 {
00605    unsigned char buf[256];
00606    int bytes = 0;
00607    int res;
00608    bytes += adsi_data_mode(buf);
00609    adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00610 
00611    bytes = 0;
00612    bytes += adsi_query_cpeid(buf);
00613    adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00614 
00615    /* Get response */
00616    memset(buf, 0, sizeof(buf));
00617    res = adsi_read_encoded_dtmf(chan, cpeid, 4);
00618    if (res != 4) {
00619       ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
00620       res = 0;
00621    } else {
00622       res = 1;
00623    }
00624 
00625    if (voice) {
00626       bytes = 0;
00627       bytes += adsi_voice_mode(buf, 0);
00628       adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00629       /* Ignore the resulting DTMF B announcing it's in voice mode */
00630       ast_waitfordigit(chan, 1000);
00631    }
00632    return res;
00633 }

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

Definition at line 635 of file res_adsi.c.

References adsi_data_mode(), ADSI_MSG_DISPLAY, adsi_query_cpeinfo(), adsi_transmit_message_full(), adsi_voice_mode(), ast_log(), ast_readstring(), ast_waitfordigit(), and LOG_WARNING.

Referenced by cpeid_exec().

00636 {
00637    unsigned char buf[256];
00638    int bytes = 0;
00639    int res;
00640    bytes += adsi_data_mode(buf);
00641    adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00642 
00643    bytes = 0;
00644    bytes += adsi_query_cpeinfo(buf);
00645    adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00646 
00647    /* Get width */
00648    memset(buf, 0, sizeof(buf));
00649    res = ast_readstring(chan, (char *)buf, 2, 1000, 500, "");
00650    if (res < 0)
00651       return res;
00652    if (strlen((char *)buf) != 2) {
00653       ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
00654       res = 0;
00655    } else {
00656       res = 1;
00657    }
00658    if (width)
00659       *width = atoi((char *)buf);
00660    /* Get height */
00661    memset(buf, 0, sizeof(buf));
00662    if (res) {
00663       res = ast_readstring(chan, (char *)buf, 2, 1000, 500, "");
00664       if (res < 0)
00665          return res;
00666       if (strlen((char *)buf) != 2) {
00667          ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
00668          res = 0;
00669       } else {
00670          res = 1;
00671       }  
00672       if (height)
00673          *height= atoi((char *)buf);
00674    }
00675    /* Get buttons */
00676    memset(buf, 0, sizeof(buf));
00677    if (res) {
00678       res = ast_readstring(chan, (char *)buf, 1, 1000, 500, "");
00679       if (res < 0)
00680          return res;
00681       if (strlen((char *)buf) != 1) {
00682          ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
00683          res = 0;
00684       } else {
00685          res = 1;
00686       }  
00687       if (buttons)
00688          *buttons = atoi((char *)buf);
00689    }
00690    if (voice) {
00691       bytes = 0;
00692       bytes += adsi_voice_mode(buf, 0);
00693       adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00694       /* Ignore the resulting DTMF B announcing it's in voice mode */
00695       ast_waitfordigit(chan, 1000);
00696    }
00697    return res;
00698 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 832 of file res_adsi.c.

References ADSI_INPUT_CONTROL.

Referenced by adsi_login(), and adsi_password().

00833 {
00834    int bytes=0;
00835 
00836    if (page) {
00837       if (line > 4) return -1;
00838    } else {
00839       if (line > 33) return -1;
00840    }
00841 
00842    if (line < 1)
00843       return -1;
00844 
00845    buf[bytes++] = ADSI_INPUT_CONTROL;
00846    bytes++;
00847    buf[bytes++] = ((page & 1) << 7) | (line & 0x3f);
00848    buf[bytes++] = ((display & 1) << 7) | ((just & 0x3) << 4) | (format & 0x7);
00849    
00850    buf[1] = bytes - 2;
00851    return bytes;
00852 
00853 }

int 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
Returns number of bytes added to buffer or -1 on error.

Definition at line 855 of file res_adsi.c.

References ADSI_INPUT_FORMAT, and ccopy().

Referenced by adsi_login(), and adsi_password().

00856 {
00857    int bytes = 0;
00858 
00859    if (!strlen((char *)format1))
00860       return -1;
00861 
00862    buf[bytes++] = ADSI_INPUT_FORMAT;
00863    bytes++;
00864    buf[bytes++] = ((dir & 1) << 7) | ((wrap & 1) << 6) | (num & 0x7);
00865    bytes += ccopy(buf + bytes, (unsigned char *)format1, 20);
00866    buf[bytes++] = 0xff;
00867    if (format2 && strlen((char *)format2)) {
00868       bytes += ccopy(buf + bytes, (unsigned char *)format2, 20);
00869    }
00870    buf[1] = bytes - 2;
00871    return bytes;
00872 }

static void adsi_load ( void   )  [static]

Definition at line 1055 of file res_adsi.c.

References ADSI_MAX_INTRO, ADSI_MAX_SPEED_DIAL, ast_config_destroy(), ast_config_load(), ast_variable_browse(), init_state(), ast_variable::name, name, ast_variable::next, str2align(), strsep(), and ast_variable::value.

Referenced by load_module(), and reload().

01056 {
01057    int x;
01058    struct ast_config *conf;
01059    struct ast_variable *v;
01060    char *name, *sname;
01061    init_state();
01062    conf = ast_config_load("adsi.conf");
01063    if (conf) {
01064       x=0;
01065       v = ast_variable_browse(conf, "intro");
01066       while(v) {
01067          if (!strcasecmp(v->name, "alignment"))
01068             alignment = str2align(v->value);
01069          else if (!strcasecmp(v->name, "greeting")) {
01070             if (x < ADSI_MAX_INTRO) {
01071                aligns[x] = alignment;
01072                strncpy(intro[x], v->value, sizeof(intro[x]) - 1);
01073                intro[x][sizeof(intro[x]) - 1] = '\0';
01074                x++;
01075             }
01076          } else if (!strcasecmp(v->name, "maxretries")) {
01077             if (atoi(v->value) > 0)
01078                maxretries = atoi(v->value);
01079          }
01080          v = v->next;
01081       }
01082       v = ast_variable_browse(conf, "speeddial");
01083       if (x)
01084          total = x;
01085       x = 0;
01086       while(v) {
01087          char *stringp=NULL;
01088          stringp=v->value;
01089          name = strsep(&stringp, ",");
01090          sname = strsep(&stringp, ",");
01091          if (!sname) 
01092             sname = name;
01093          if (x < ADSI_MAX_SPEED_DIAL) {
01094             /* Up to 20 digits */
01095             strncpy(speeddial[x][0], v->name, sizeof(speeddial[x][0]) - 1);
01096             strncpy(speeddial[x][1], name, 18);
01097             strncpy(speeddial[x][2], sname, 7);
01098             x++;
01099          }
01100          v = v->next;
01101             
01102       }
01103       if (x)
01104          speeds = x;
01105       ast_config_destroy(conf);
01106    }
01107 }

int 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

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
Returns 0 if scripts is not loaded or not an ADSI CPE. Returns -1 on hangup. Returns 1 if script already loaded.

Definition at line 967 of file res_adsi.c.

References adsi_connect_session(), adsi_data_mode(), ADSI_MSG_DISPLAY, adsi_transmit_message_full(), ast_log(), ast_readstring(), dsp, LOG_DEBUG, and LOG_WARNING.

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

00968 {
00969    unsigned char dsp[256];
00970    int bytes;
00971    int res;
00972    char resp[2];
00973 
00974    memset(dsp, 0, sizeof(dsp));
00975 
00976    /* Connect to session */
00977    bytes = 0;
00978    bytes += adsi_connect_session(dsp + bytes, app, ver);
00979 
00980    if (data)
00981       bytes += adsi_data_mode(dsp + bytes);
00982 
00983    /* Prepare key setup messages */
00984    if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0))
00985       return -1;
00986    if (app) {
00987       res = ast_readstring(chan, resp, 1, 1200, 1200, "");
00988       if (res < 0)
00989          return -1;
00990       if (res) {
00991          ast_log(LOG_DEBUG, "No response from CPE about version.  Assuming not there.\n");
00992          return 0;
00993       }
00994       if (!strcmp(resp, "B")) {
00995          ast_log(LOG_DEBUG, "CPE has script '%s' version %d already loaded\n", app, ver);
00996          return 1;
00997       } else if (!strcmp(resp, "A")) {
00998          ast_log(LOG_DEBUG, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
00999       } else {
01000          ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
01001       }
01002    } else
01003       return 1;
01004    return 0;
01005 
01006 }

int adsi_load_soft_key ( unsigned char *  buf,
int  key,
char *  llabel,
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
Returns number of bytes added to buffer or -1 on error.

Definition at line 441 of file res_adsi.c.

References ADSI_LOAD_SOFTKEY, ADSI_SWITCH_TO_DATA2, and ccopy().

Referenced by adsi_load_vmail(), and adsi_login().

00442 {
00443    int bytes=0;
00444 
00445    /* Abort if invalid key specified */
00446    if ((key < 2) || (key > 33))
00447       return -1;
00448    buf[bytes++] = ADSI_LOAD_SOFTKEY;
00449    /* Reserve for length */
00450    bytes++;
00451    /* Which key */
00452    buf[bytes++] = key;
00453 
00454    /* Carefully copy long label */
00455    bytes += ccopy(buf + bytes, (unsigned char *)llabel, 18);
00456 
00457    /* Place delimiter */
00458    buf[bytes++] = 0xff;
00459 
00460    /* Short label */
00461    bytes += ccopy(buf + bytes, (unsigned char *)slabel, 7);
00462 
00463 
00464    /* If specified, copy return string */
00465    if (ret) {
00466       /* Place delimiter */
00467       buf[bytes++] = 0xff;
00468       if (data)
00469          buf[bytes++] = ADSI_SWITCH_TO_DATA2;
00470       /* Carefully copy return string */
00471       bytes += ccopy(buf + bytes, (unsigned char *)ret, 20);
00472 
00473    }
00474    /* Replace parameter length */
00475    buf[1] = bytes - 2;
00476    return bytes;
00477    
00478 }

int 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 0 on success (or adsi unavailable) and -1 on hangup

Definition at line 947 of file res_adsi.c.

References adsi_display(), ADSI_INFO_PAGE, ADSI_MSG_DISPLAY, adsi_set_line(), adsi_transmit_message_full(), adsi_voice_mode(), and ast_waitfordigit().

Referenced by adsi_announce_park(), and cpeid_setstatus().

00948 {
00949    unsigned char buf[4096];
00950    int bytes=0;
00951    int res;
00952    int x;
00953    for(x=0;lines[x];x++) 
00954       bytes += adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, aligns[x], 0, lines[x], "");
00955    bytes += adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
00956    if (voice) {
00957       bytes += adsi_voice_mode(buf + bytes, 0);
00958    }
00959    res = adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
00960    if (voice) {
00961       /* Ignore the resulting DTMF B announcing it's in voice mode */
00962       ast_waitfordigit(chan, 1000);
00963    }
00964    return res;
00965 }

int adsi_query_cpeid ( unsigned char *  buf  ) 

Build Query CPE ID of equipment

Returns number of bytes added to message

Definition at line 548 of file res_adsi.c.

References ADSI_QUERY_CPEID.

Referenced by adsi_get_cpeid().

00549 {
00550    int bytes = 0;
00551    buf[bytes++] = ADSI_QUERY_CPEID;
00552    /* Reserve space for length */
00553    bytes++;
00554    buf[1] = bytes - 2;
00555    return bytes;
00556 }

int adsi_query_cpeinfo ( unsigned char *  buf  ) 

Definition at line 558 of file res_adsi.c.

References ADSI_QUERY_CONFIG.

Referenced by adsi_get_cpeinfo().

00559 {
00560    int bytes = 0;
00561    buf[bytes++] = ADSI_QUERY_CONFIG;
00562    /* Reserve space for length */
00563    bytes++;
00564    buf[1] = bytes - 2;
00565    return bytes;
00566 }

int 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 568 of file res_adsi.c.

References ast_waitfordigit().

Referenced by adsi_get_cpeid().

00569 {
00570    int bytes = 0;
00571    int res;
00572    unsigned char current = 0;
00573    int gotstar = 0;
00574    int pos = 0;
00575    memset(buf, 0, sizeof(buf));
00576    while(bytes <= maxlen) {
00577       /* Wait up to a second for a digit */
00578       res = ast_waitfordigit(chan, 1000);
00579       if (!res)
00580          break;
00581       if (res == '*') {
00582          gotstar = 1;   
00583          continue;
00584       }
00585       /* Ignore anything other than a digit */
00586       if ((res < '0') || (res > '9'))
00587          continue;
00588       res -= '0';
00589       if (gotstar)
00590          res += 9;
00591       if (pos)  {
00592          pos = 0;
00593          buf[bytes++] = (res << 4) | current;
00594       } else {
00595          pos = 1;
00596          current = res;
00597       }
00598       gotstar = 0;
00599    }
00600    return bytes;
00601 }

int 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
Returns number of bytes added to buffer or -1 on error.

Definition at line 874 of file res_adsi.c.

References ADSI_INIT_SOFTKEY_LINE.

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

00875 {
00876    int bytes=0;
00877    int x;
00878    /* Message type */
00879    buf[bytes++] = ADSI_INIT_SOFTKEY_LINE;
00880    /* Space for size */
00881    bytes++;
00882    /* Key definitions */
00883    for (x=0;x<6;x++)
00884       buf[bytes++] = (keys[x] & 0x3f) ? keys[x] : (keys[x] | 0x1);
00885    buf[1] = bytes - 2;
00886    return bytes;
00887 }

int 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)
Returns number of bytes added to buffer or -1 on error.

Definition at line 889 of file res_adsi.c.

References ADSI_LINE_CONTROL.

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

00890 {
00891    int bytes=0;
00892 
00893    /* Sanity check line number */
00894 
00895    if (page) {
00896       if (line > 4) return -1;
00897    } else {
00898       if (line > 33) return -1;
00899    }
00900 
00901    if (line < 1)
00902       return -1;
00903    /* Parameter type */
00904    buf[bytes++] = ADSI_LINE_CONTROL;
00905    
00906    /* Reserve space for size */
00907    bytes++;
00908 
00909    /* Page and line */
00910    buf[bytes++] = ((page & 0x1) << 7) | (line & 0x3f);
00911 
00912    buf[1] = bytes - 2;
00913    return bytes;
00914 
00915 };

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

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

Definition at line 351 of file res_adsi.c.

References __adsi_transmit_messages(), ADSI_FLAG_DATAMODE, ADSI_SWITCH_TO_DATA, ADSI_SWITCH_TO_VOICE, ast_channel::adsicpe, AST_FORMAT_ULAW, ast_log(), ast_safe_sleep(), ast_set_read_format(), ast_set_write_format(), ast_stopstream(), ast_waitfordigit(), LOG_DEBUG, LOG_WARNING, ast_channel::readformat, and ast_channel::writeformat.

Referenced by adsi_begin_download(), adsi_channel_restore(), adsi_end_download(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_load_session(), adsi_print(), adsi_transmit_message(), and adsi_unload_session().

00352 {
00353    unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
00354    int msglens[5];
00355    int msgtypes[5];
00356    int newdatamode;
00357    int res;
00358    int x;
00359    int writeformat, readformat;
00360    int waitforswitch = 0;
00361 
00362    writeformat = chan->writeformat;
00363    readformat = chan->readformat;
00364 
00365    newdatamode = chan->adsicpe & ADSI_FLAG_DATAMODE;
00366 
00367    for (x=0;x<msglen;x+=(msg[x+1]+2)) {
00368       if (msg[x] == ADSI_SWITCH_TO_DATA) {
00369          ast_log(LOG_DEBUG, "Switch to data is sent!\n");
00370          waitforswitch++;
00371          newdatamode = ADSI_FLAG_DATAMODE;
00372       }
00373       
00374       if (msg[x] == ADSI_SWITCH_TO_VOICE) {
00375          ast_log(LOG_DEBUG, "Switch to voice is sent!\n");
00376          waitforswitch++;
00377          newdatamode = 0;
00378       }
00379    }
00380    msgs[0] = msg;
00381 
00382    msglens[0] = msglen;
00383    msgtypes[0] = msgtype;
00384 
00385    if (msglen > 253) {
00386       ast_log(LOG_WARNING, "Can't send ADSI message of %d bytes, too large\n", msglen);
00387       return -1;
00388    }
00389 
00390    ast_stopstream(chan);
00391 
00392    if (ast_set_write_format(chan, AST_FORMAT_ULAW)) {
00393       ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
00394       return -1;
00395    }
00396 
00397    if (ast_set_read_format(chan, AST_FORMAT_ULAW)) {
00398       ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
00399       if (writeformat) {
00400          if (ast_set_write_format(chan, writeformat)) 
00401             ast_log(LOG_WARNING, "Unable to restore write format to %d\n", writeformat);
00402       }
00403       return -1;
00404    }
00405    res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
00406 
00407    if (dowait) {
00408       ast_log(LOG_DEBUG, "Wait for switch is '%d'\n", waitforswitch);
00409       while(waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) { res = 0; ast_log(LOG_DEBUG, "Waiting for 'B'...\n"); }
00410    }
00411    
00412    if (!res)
00413       chan->adsicpe = (chan->adsicpe & ~ADSI_FLAG_DATAMODE) | newdatamode;
00414 
00415    if (writeformat)
00416       ast_set_write_format(chan, writeformat);
00417    if (readformat)
00418       ast_set_read_format(chan, readformat);
00419 
00420    if (!res)
00421       res = ast_safe_sleep(chan, 100 );
00422    return res;
00423 }

int adsi_unload_session ( struct ast_channel chan  ) 

Definition at line 1008 of file res_adsi.c.

References adsi_disconnect_session(), ADSI_MSG_DISPLAY, adsi_transmit_message_full(), adsi_voice_mode(), and dsp.

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

01009 {
01010    unsigned char dsp[256];
01011    int bytes;
01012 
01013    memset(dsp, 0, sizeof(dsp));
01014 
01015    /* Connect to session */
01016    bytes = 0;
01017    bytes += adsi_disconnect_session(dsp + bytes);
01018    bytes += adsi_voice_mode(dsp + bytes, 0);
01019 
01020    /* Prepare key setup messages */
01021    if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0))
01022       return -1;
01023    return 0;
01024 }

int 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
Returns number of bytes added to buffer or -1 on error.

Definition at line 745 of file res_adsi.c.

References ADSI_SWITCH_TO_VOICE.

Referenced by adsi_delete(), adsi_folders(), adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_goodbye(), adsi_load_vmail(), adsi_login(), adsi_message(), adsi_password(), adsi_print(), adsi_status(), adsi_status2(), adsi_unload_session(), vm_newuser(), vm_options(), and vm_tempgreeting().

00746 {
00747    int bytes=0;
00748 
00749    /* Message type */
00750    buf[bytes++] = ADSI_SWITCH_TO_VOICE;
00751 
00752    /* Reserve space for length */
00753    bytes++;
00754 
00755    buf[bytes++] = when & 0x7f;
00756 
00757    buf[1] = bytes - 2;
00758    return bytes;
00759 
00760 }

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

Definition at line 430 of file res_adsi.c.

Referenced by adsi_display(), adsi_download_connect(), adsi_input_format(), and adsi_load_soft_key().

00431 {
00432    int x=0;
00433    /* Carefully copy the requested data */
00434    while ((x < max) && src[x] && (src[x] != 0xff)) {
00435       dst[x] = src[x];
00436       x++;
00437    }
00438    return x;
00439 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 1127 of file res_adsi.c.

01128 {
01129    return "ADSI Resource";
01130 }

static void init_state ( void   )  [static]

Definition at line 1038 of file res_adsi.c.

References ADSI_JUST_CENT, and ADSI_MAX_INTRO.

Referenced by adsi_load().

01039 {
01040    int x;
01041 
01042    for (x=0;x<ADSI_MAX_INTRO;x++)
01043       aligns[x] = ADSI_JUST_CENT;
01044    strncpy(intro[0], "Welcome to the", sizeof(intro[0]) - 1);
01045    strncpy(intro[1], "Asterisk", sizeof(intro[1]) - 1);
01046    strncpy(intro[2], "Open Source PBX", sizeof(intro[2]) - 1);
01047    total = 3;
01048    speeds = 0;
01049    for (x=3;x<ADSI_MAX_INTRO;x++)
01050       intro[x][0] = '\0';
01051    memset(speeddial, 0, sizeof(speeddial));
01052    alignment = ADSI_JUST_CENT;
01053 }

char* key ( void   ) 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 1138 of file res_adsi.c.

References ASTERISK_GPL_KEY.

01139 {
01140    return ASTERISK_GPL_KEY;
01141 }

int load_module ( void   ) 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.
TE STUFF END

Definition at line 1115 of file res_adsi.c.

References adsi_load().

01116 {
01117    adsi_load();
01118    return 0;
01119 }

int reload ( void   ) 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 1109 of file res_adsi.c.

References adsi_load().

01110 {
01111    adsi_load();
01112    return 0;
01113 }

static int str2align ( char *  s  )  [static]

Definition at line 1026 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_JUST_IND, ADSI_JUST_LEFT, and ADSI_JUST_RIGHT.

Referenced by adsi_load().

01027 {
01028    if (!strncasecmp(s, "l", 1))
01029       return ADSI_JUST_LEFT;
01030    else if (!strncasecmp(s, "r", 1))
01031       return ADSI_JUST_RIGHT;
01032    else if (!strncasecmp(s, "i", 1))
01033       return ADSI_JUST_IND;
01034    else
01035       return ADSI_JUST_CENT;
01036 }

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.
Standard module functions ...

Definition at line 1121 of file res_adsi.c.

01122 {
01123    /* Can't unload this once we're loaded */
01124    return -1;
01125 }

int usecount ( void   ) 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 1132 of file res_adsi.c.

01133 {
01134    /* We should never be unloaded */
01135    return 1;
01136 }


Variable Documentation

int alignment = 0 [static]

Definition at line 67 of file res_adsi.c.

int aligns[ADSI_MAX_INTRO] [static]

Definition at line 63 of file res_adsi.c.

char intro[ADSI_MAX_INTRO][20] [static]

Definition at line 62 of file res_adsi.c.

int maxretries = DEFAULT_ADSI_MAX_RETRIES [static]

Definition at line 57 of file res_adsi.c.

Referenced by ast_ivr_menu_run_internal(), and privacy_exec().

char speeddial[ADSI_MAX_SPEED_DIAL][3][20] [static]

Definition at line 65 of file res_adsi.c.

int speeds = 0 [static]

Definition at line 918 of file res_adsi.c.

int total = 0 [static]


Generated on Wed Oct 28 15:49:13 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6