#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 |
Definition in file res_adsi.c.
| #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 |
| #define ADSI_MAX_SPEED_DIAL 6 |
| #define ADSI_SPEED_DIAL 10 |
| #define DEFAULT_ADSI_MAX_RETRIES 3 |
Definition at line 50 of file res_adsi.c.
| 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 | ) |
| 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::datalen, ast_frame::frametype, LOG_WARNING, 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 | ) |
| chan | Channel to restore |
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 | |||
| ) |
| 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) |
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 | ) |
| buf | Character buffer to create parameter in (must have at least 256 free) |
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 | ) |
| buf | Character buffer to create parameter in (must have at least 256 free) |
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 | |||
| ) |
| 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 |
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_print(), 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 | |||
| ) |
| 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) |
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 | ) |
| buf | Character buffer to create parameter in (must have at least 256 free) |
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().
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 | |||
| ) |
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 | |||
| ) |
| 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) |
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 | |||
| ) |
| 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 |
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 | |||
| ) |
| 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 |