Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Macros | Functions | Variables
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 "asterisk/format_cache.h"
Include dependency graph for res_adsi.c:

Go to the source code of this file.

Macros

#define ADSI_FLAG_DATAMODE   (1 << 8)
 
#define ADSI_MAX_INTRO   20
 
#define ADSI_MAX_SPEED_DIAL   6
 
#define ADSI_SPEED_DIAL   10 /* 10-15 are reserved for speed dial */
 
#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_available (struct ast_channel *chan)
 
static 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 *remain)
 
static int adsi_channel_restore (struct ast_channel *chan)
 
static int adsi_clear_screen (unsigned char *buf)
 
static int adsi_clear_soft_keys (unsigned char *buf)
 
static int adsi_connect_session (unsigned char *buf, unsigned char *fdn, int ver)
 
static int adsi_data_mode (unsigned char *buf)
 
static int adsi_disconnect_session (unsigned char *buf)
 
static int adsi_display (unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
 
static int adsi_download_connect (unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
 
static int adsi_download_disconnect (unsigned char *buf)
 
static 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, struct ast_format *codec)
 
static int adsi_get_cpeid (struct ast_channel *chan, unsigned char *cpeid, int voice)
 
static int adsi_get_cpeinfo (struct ast_channel *chan, int *width, int *height, int *buttons, int voice)
 
static int adsi_input_control (unsigned char *buf, int page, int line, int display, int format, int just)
 
static int adsi_input_format (unsigned char *buf, int num, int dir, int wrap, char *format1, char *format2)
 
static void adsi_load (int reload)
 
static int adsi_load_session (struct ast_channel *chan, unsigned char *app, int ver, int data)
 
static int adsi_load_soft_key (unsigned char *buf, int key, const char *llabel, const char *slabel, char *ret, int data)
 
static int adsi_print (struct ast_channel *chan, char **lines, int *align, int voice)
 
static int adsi_query_cpeid (unsigned char *buf)
 
static int adsi_query_cpeinfo (unsigned char *buf)
 
static int adsi_read_encoded_dtmf (struct ast_channel *chan, unsigned char *buf, int maxlen)
 
static int adsi_set_keys (unsigned char *buf, unsigned char *keys)
 
static int adsi_set_line (unsigned char *buf, int page, int line)
 
static int adsi_transmit_message (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype)
 
static int adsi_transmit_message_full (struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
 
static int adsi_unload_session (struct ast_channel *chan)
 
static int adsi_voice_mode (unsigned char *buf, int when)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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_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, .support_level = AST_MODULE_SUPPORT_DEPRECATED, .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 const struct ast_module_infoast_module_info = &__mod_info
 
static char intro [ADSI_MAX_INTRO][20]
 
static int maxretries = DEFAULT_ADSI_MAX_RETRIES
 
static struct adsi_funcs res_adsi_funcs
 
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 marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
this module is required by app_voicemail and app_getcpeid
Todo:

Move app_getcpeid into this module

Create a core layer so that app_voicemail does not require res_adsi to load

Definition in file res_adsi.c.

Macro Definition Documentation

◆ ADSI_FLAG_DATAMODE

#define ADSI_FLAG_DATAMODE   (1 << 8)

Definition at line 58 of file res_adsi.c.

◆ ADSI_MAX_INTRO

#define ADSI_MAX_INTRO   20

Definition at line 55 of file res_adsi.c.

◆ ADSI_MAX_SPEED_DIAL

#define ADSI_MAX_SPEED_DIAL   6

Definition at line 56 of file res_adsi.c.

◆ ADSI_SPEED_DIAL

#define ADSI_SPEED_DIAL   10 /* 10-15 are reserved for speed dial */

Definition at line 63 of file res_adsi.c.

◆ DEFAULT_ADSI_MAX_RETRIES

#define DEFAULT_ADSI_MAX_RETRIES   3

Definition at line 53 of file res_adsi.c.

◆ SPEEDDIAL_MAX_LEN

#define SPEEDDIAL_MAX_LEN   20

Definition at line 68 of file res_adsi.c.

Function Documentation

◆ __adsi_transmit_messages()

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

Definition at line 230 of file res_adsi.c.

231{
232 /* msglen must be no more than 256 bits, each */
233 unsigned char buf[24000 * 5];
234 int pos = 0, res, x, start = 0, retries = 0, waittime, rem = 0, def;
235 char ack[3];
236 struct ast_frame *f;
237
239 /* Don't bother if we know they don't support ADSI */
240 ast_log(LOG_WARNING, "ADSI is not supported for %s\n", ast_channel_name(chan));
241 errno = ENOSYS;
242 return -1;
243 }
244
245 while (retries < maxretries) {
247 /* Generate CAS (no SAS) */
249
250 /* Send CAS */
251 if (adsi_careful_send(chan, buf, 680, NULL)) {
252 ast_log(LOG_WARNING, "Unable to send CAS\n");
253 }
254
255 /* Wait For DTMF result */
256 waittime = 500;
257 for (;;) {
258 if (((res = ast_waitfor(chan, waittime)) < 1)) {
259 /* Didn't get back DTMF A in time */
260 ast_verb(4, "No ADSI CPE detected (%d)\n", res);
261 if (!ast_channel_adsicpe(chan)) {
263 }
264 errno = ENOSYS;
265 return -1;
266 }
267 waittime = res;
268 if (!(f = ast_read(chan))) {
269 ast_debug(1, "Hangup in ADSI\n");
270 return -1;
271 }
272 if (f->frametype == AST_FRAME_DTMF) {
273 if (f->subclass.integer == 'A') {
274 /* Okay, this is an ADSI CPE. Note this for future reference, too */
275 if (!ast_channel_adsicpe(chan)) {
277 }
278 break;
279 } else {
280 if (f->subclass.integer == 'D') {
281 ast_debug(1, "Off-hook capable CPE only, not ADSI\n");
282 } else {
283 ast_log(LOG_WARNING, "Unknown ADSI response '%c'\n", f->subclass.integer);
284 }
285 if (!ast_channel_adsicpe(chan)) {
287 }
288 errno = ENOSYS;
289 ast_frfree(f);
290 return -1;
291 }
292 }
293 ast_frfree(f);
294 }
295
296 ast_verb(4, "ADSI Compatible CPE Detected\n");
297 } else {
298 ast_debug(1, "Already in data mode\n");
299 }
300
301 x = 0;
302 pos = 0;
303#if 1
304 def= ast_channel_defer_dtmf(chan);
305#endif
306 while ((x < 6) && msg[x]) {
307 if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], ast_format_ulaw)) < 0) {
308 ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, ast_channel_name(chan));
309 return -1;
310 }
311 ast_debug(1, "Message %d, of %d input bytes, %d output bytes\n", x + 1, msglen[x], res);
312 pos += res;
313 x++;
314 }
315
316
317 rem = 0;
318 res = adsi_careful_send(chan, buf, pos, &rem);
319 if (!def) {
321 }
322 if (res) {
323 return -1;
324 }
325
326 ast_debug(1, "Sent total spill of %d bytes\n", pos);
327
328 memset(ack, 0, sizeof(ack));
329 /* Get real result and check for hangup */
330 if ((res = ast_readstring(chan, ack, 2, 1000, 1000, "")) < 0) {
331 return -1;
332 }
333 if (ack[0] == 'D') {
334 ast_debug(1, "Acked up to message %d\n", atoi(ack + 1)); start += atoi(ack + 1);
335 if (start >= x) {
336 break;
337 } else {
338 retries++;
339 ast_debug(1, "Retransmitting (%d), from %d\n", retries, start + 1);
340 }
341 } else {
342 retries++;
343 ast_log(LOG_WARNING, "Unexpected response to ack: %s (retry %d)\n", ack, retries);
344 }
345 }
346 if (retries >= maxretries) {
347 ast_log(LOG_WARNING, "Maximum ADSI Retries (%d) exceeded\n", maxretries);
348 errno = ETIMEDOUT;
349 return -1;
350 }
351 return 0;
352}
#define ast_log
Definition: astobj2.c:42
int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec)
Generate a CAS (CPE Alert Signal) tone for 'n' samples.
Definition: callerid.c:271
const char * ast_channel_name(const struct ast_channel *chan)
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3162
void ast_channel_undefer_dtmf(struct ast_channel *chan)
Unset defer DTMF flag on channel.
Definition: channel.c:1271
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4257
ast_channel_adsicpe
Definition: channel.h:868
@ AST_ADSI_UNAVAILABLE
Definition: channel.h:871
@ AST_ADSI_AVAILABLE
Definition: channel.h:870
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6558
int ast_channel_defer_dtmf(struct ast_channel *chan)
Defers DTMF so that you only read things like hangups and audio.
Definition: channel.c:1257
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define AST_FRAME_DTMF
#define ast_frfree(fr)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define LOG_WARNING
int errno
#define ADSI_FLAG_DATAMODE
Definition: res_adsi.c:58
static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remain)
Definition: res_adsi.c:152
static int maxretries
Definition: res_adsi.c:60
static int adsi_generate(unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, struct ast_format *codec)
Definition: res_adsi.c:102
#define NULL
Definition: resample.c:96
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype

References adsi_careful_send(), ADSI_FLAG_DATAMODE, adsi_generate(), AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, ast_channel_adsicpe_set(), ast_channel_defer_dtmf(), ast_channel_name(), ast_channel_undefer_dtmf(), ast_debug, ast_format_ulaw, AST_FRAME_DTMF, ast_frfree, ast_gen_cas(), ast_log, ast_read(), ast_readstring(), ast_verb, ast_waitfor(), buf, errno, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, maxretries, NULL, and ast_frame::subclass.

Referenced by adsi_transmit_message_full().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1218 of file res_adsi.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1218 of file res_adsi.c.

◆ adsi_available()

static int adsi_available ( struct ast_channel chan)
static

Definition at line 811 of file res_adsi.c.

812{
813 int cpe = ast_channel_adsicpe(chan) & 0xff;
814 if ((cpe == AST_ADSI_AVAILABLE) ||
815 (cpe == AST_ADSI_UNKNOWN)) {
816 return 1;
817 }
818 return 0;
819}
@ AST_ADSI_UNKNOWN
Definition: channel.h:869

References AST_ADSI_AVAILABLE, and AST_ADSI_UNKNOWN.

◆ adsi_begin_download()

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

Definition at line 354 of file res_adsi.c.

355{
356 int bytes = 0;
357 unsigned char buf[256];
358 char ack[2];
359
360 /* Setup the resident soft key stuff, a piece at a time */
361 /* Upload what scripts we can for voicemail ahead of time */
362 bytes += adsi_download_connect(buf + bytes, service, fdn, sec, version);
363 if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
364 return -1;
365 }
366 if (ast_readstring(chan, ack, 1, 10000, 10000, "")) {
367 return -1;
368 }
369 if (ack[0] == 'B') {
370 return 0;
371 }
372 ast_debug(1, "Download was denied by CPE\n");
373 return -1;
374}
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
enum ast_cc_service_type service
Definition: ccss.c:383
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
static int adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
Definition: res_adsi.c:547
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:390

References adsi_download_connect(), ADSI_MSG_DOWNLOAD, adsi_transmit_message_full(), ast_debug, ast_readstring(), buf, service, and version.

◆ adsi_careful_send()

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

Definition at line 152 of file res_adsi.c.

153{
154 /* Sends carefully on a full duplex channel by using reading for
155 timing */
156 struct ast_frame *inf;
157 struct ast_frame outf = {
159 .subclass.format = ast_format_ulaw,
160 };
161 int amt;
162
163 if (remain && *remain) {
164 amt = len;
165
166 /* Send remainder if provided */
167 if (amt > *remain) {
168 amt = *remain;
169 } else {
170 *remain = *remain - amt;
171 }
172
173 outf.data.ptr = buf;
174 outf.datalen = amt;
175 outf.samples = amt;
176 if (ast_write(chan, &outf)) {
177 ast_log(LOG_WARNING, "Failed to carefully write frame\n");
178 return -1;
179 }
180 /* Update pointers and lengths */
181 buf += amt;
182 len -= amt;
183 }
184
185 while (len) {
186 amt = len;
187 /* If we don't get anything at all back in a second, forget
188 about it */
189 if (ast_waitfor(chan, 1000) < 1) {
190 return -1;
191 }
192 /* Detect hangup */
193 if (!(inf = ast_read(chan))) {
194 return -1;
195 }
196
197 /* Drop any frames that are not voice */
198 if (inf->frametype != AST_FRAME_VOICE) {
199 ast_frfree(inf);
200 continue;
201 }
202
204 ast_log(LOG_WARNING, "Channel not in ulaw?\n");
205 ast_frfree(inf);
206 return -1;
207 }
208 /* Send no more than they sent us */
209 if (amt > inf->datalen) {
210 amt = inf->datalen;
211 } else if (remain) {
212 *remain = inf->datalen - amt;
213 }
214 outf.data.ptr = buf;
215 outf.datalen = amt;
216 outf.samples = amt;
217 if (ast_write(chan, &outf)) {
218 ast_log(LOG_WARNING, "Failed to carefully write frame\n");
219 ast_frfree(inf);
220 return -1;
221 }
222 /* Update pointers and lengths */
223 buf += amt;
224 len -= amt;
225 ast_frfree(inf);
226 }
227 return 0;
228}
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:5144
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
@ AST_FRAME_VOICE
struct ast_format * format
union ast_frame::@226 data

References ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_ulaw, AST_FRAME_VOICE, ast_frfree, ast_log, ast_read(), ast_waitfor(), ast_write(), buf, ast_frame::data, ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, ast_frame::samples, and ast_frame::subclass.

Referenced by __adsi_transmit_messages().

◆ adsi_channel_restore()

static int adsi_channel_restore ( struct ast_channel chan)
static

Definition at line 973 of file res_adsi.c.

974{
975 unsigned char dsp[256] = "", keyd[6] = "";
976 int bytes, x;
977
978 /* Start with initial display setup */
979 bytes = 0;
980 bytes += adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
981
982 /* Prepare key setup messages */
983
984 if (speeds) {
985 for (x = 0; x < speeds; x++) {
986 keyd[x] = ADSI_SPEED_DIAL + x;
987 }
988 bytes += adsi_set_keys(dsp + bytes, keyd);
989 }
990 adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0);
991 return 0;
992
993}
#define ADSI_INFO_PAGE
Definition: adsi.h:106
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
static int adsi_set_keys(unsigned char *buf, unsigned char *keys)
Definition: res_adsi.c:926
static int speeds
Definition: res_adsi.c:971
static int adsi_set_line(unsigned char *buf, int page, int line)
Definition: res_adsi.c:942
#define ADSI_SPEED_DIAL
Definition: res_adsi.c:63

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

◆ adsi_clear_screen()

static int adsi_clear_screen ( unsigned char *  buf)
static

Definition at line 779 of file res_adsi.c.

780{
781 int bytes = 0;
782
783 /* Message type */
784 buf[bytes++] = ADSI_CLEAR_SCREEN;
785
786 /* Reserve space for length */
787 bytes++;
788
789 buf[1] = bytes - 2;
790 return bytes;
791
792}
#define ADSI_CLEAR_SCREEN
Definition: adsi.h:56

References ADSI_CLEAR_SCREEN, and buf.

◆ adsi_clear_soft_keys()

static int adsi_clear_soft_keys ( unsigned char *  buf)
static

Definition at line 764 of file res_adsi.c.

765{
766 int bytes = 0;
767
768 /* Message type */
769 buf[bytes++] = ADSI_CLEAR_SOFTKEY;
770
771 /* Reserve space for length */
772 bytes++;
773
774 buf[1] = bytes - 2;
775 return bytes;
776
777}
#define ADSI_CLEAR_SOFTKEY
Definition: adsi.h:44

References ADSI_CLEAR_SOFTKEY, and buf.

◆ adsi_connect_session()

static int adsi_connect_session ( unsigned char *  buf,
unsigned char *  fdn,
int  ver 
)
static

Definition at line 523 of file res_adsi.c.

524{
525 int bytes = 0, x;
526
527 /* Message type */
528 buf[bytes++] = ADSI_CONNECT_SESSION;
529
530 /* Reserve space for length */
531 bytes++;
532
533 if (fdn) {
534 for (x = 0; x < 4; x++) {
535 buf[bytes++] = fdn[x];
536 }
537 if (ver > -1) {
538 buf[bytes++] = ver & 0xff;
539 }
540 }
541
542 buf[1] = bytes - 2;
543 return bytes;
544
545}
#define ADSI_CONNECT_SESSION
Definition: adsi.h:50

References ADSI_CONNECT_SESSION, and buf.

Referenced by adsi_load_session().

◆ adsi_data_mode()

static int adsi_data_mode ( unsigned char *  buf)
static

Definition at line 749 of file res_adsi.c.

750{
751 int bytes = 0;
752
753 /* Message type */
754 buf[bytes++] = ADSI_SWITCH_TO_DATA;
755
756 /* Reserve space for length */
757 bytes++;
758
759 buf[1] = bytes - 2;
760 return bytes;
761
762}
#define ADSI_SWITCH_TO_DATA
Definition: adsi.h:42

References ADSI_SWITCH_TO_DATA, and buf.

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

◆ adsi_disconnect_session()

static int adsi_disconnect_session ( unsigned char *  buf)
static

Definition at line 579 of file res_adsi.c.

580{
581 int bytes = 0;
582
583 /* Message type */
584 buf[bytes++] = ADSI_DISC_SESSION;
585
586 /* Reserve space for length */
587 bytes++;
588
589 buf[1] = bytes - 2;
590 return bytes;
591
592}
#define ADSI_DISC_SESSION
Definition: adsi.h:41

References ADSI_DISC_SESSION, and buf.

Referenced by adsi_unload_session().

◆ adsi_display()

static int adsi_display ( unsigned char *  buf,
int  page,
int  line,
int  just,
int  wrap,
char *  col1,
char *  col2 
)
static

Definition at line 836 of file res_adsi.c.

838{
839 int bytes = 0;
840
841 /* Sanity check line number */
842
843 if (page) {
844 if (line > 4) return -1;
845 } else {
846 if (line > 33) return -1;
847 }
848
849 if (line < 1) {
850 return -1;
851 }
852 /* Parameter type */
853 buf[bytes++] = ADSI_LOAD_VIRTUAL_DISP;
854
855 /* Reserve space for size */
856 bytes++;
857
858 /* Page and wrap indicator */
859 buf[bytes++] = ((page & 0x1) << 7) | ((wrap & 0x1) << 6) | (line & 0x3f);
860
861 /* Justification */
862 buf[bytes++] = (just & 0x3) << 5;
863
864 /* Omit highlight mode definition */
865 buf[bytes++] = 0xff;
866
867 /* Primary column */
868 bytes+= ccopy(buf + bytes, (unsigned char *)col1, 20);
869
870 /* Delimiter */
871 buf[bytes++] = 0xff;
872
873 /* Secondary column */
874 bytes += ccopy(buf + bytes, (unsigned char *)col2, 20);
875
876 /* Update length */
877 buf[1] = bytes - 2;
878
879 return bytes;
880
881}
#define ADSI_LOAD_VIRTUAL_DISP
Definition: adsi.h:38
static int ccopy(unsigned char *dst, const unsigned char *src, int max)
Definition: res_adsi.c:471

References ADSI_LOAD_VIRTUAL_DISP, buf, and ccopy().

Referenced by adsi_print().

◆ adsi_download_connect()

static int adsi_download_connect ( unsigned char *  buf,
char *  service,
unsigned char *  fdn,
unsigned char *  sec,
int  ver 
)
static

Definition at line 547 of file res_adsi.c.

548{
549 int bytes = 0, x;
550
551 /* Message type */
552 buf[bytes++] = ADSI_DOWNLOAD_CONNECT;
553
554 /* Reserve space for length */
555 bytes++;
556
557 /* Primary column */
558 bytes+= ccopy(buf + bytes, (unsigned char *)service, 18);
559
560 /* Delimiter */
561 buf[bytes++] = 0xff;
562
563 for (x = 0; x < 4; x++) {
564 buf[bytes++] = fdn[x];
565 }
566
567 for (x = 0; x < 4; x++) {
568 buf[bytes++] = sec[x];
569 }
570
571 buf[bytes++] = ver & 0xff;
572
573 buf[1] = bytes - 2;
574
575 return bytes;
576
577}
#define ADSI_DOWNLOAD_CONNECT
Definition: adsi.h:65

References ADSI_DOWNLOAD_CONNECT, buf, ccopy(), and service.

Referenced by adsi_begin_download().

◆ adsi_download_disconnect()

static int adsi_download_disconnect ( unsigned char *  buf)
static

Definition at line 821 of file res_adsi.c.

822{
823 int bytes = 0;
824
825 /* Message type */
826 buf[bytes++] = ADSI_DOWNLOAD_DISC;
827
828 /* Reserve space for length */
829 bytes++;
830
831 buf[1] = bytes - 2;
832 return bytes;
833
834}
#define ADSI_DOWNLOAD_DISC
Definition: adsi.h:66

References ADSI_DOWNLOAD_DISC, and buf.

Referenced by adsi_end_download().

◆ adsi_end_download()

static int adsi_end_download ( struct ast_channel chan)
static

Definition at line 376 of file res_adsi.c.

377{
378 int bytes = 0;
379 unsigned char buf[256];
380
381 /* Setup the resident soft key stuff, a piece at a time */
382 /* Upload what scripts we can for voicemail ahead of time */
383 bytes += adsi_download_disconnect(buf + bytes);
384 if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
385 return -1;
386 }
387 return 0;
388}
static int adsi_download_disconnect(unsigned char *buf)
Definition: res_adsi.c:821

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

◆ adsi_generate()

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

103{
104 int sum, x, bytes = 0;
105 /* Initial carrier (imaginary) */
106 float cr = 1.0, ci = 0.0, scont = 0.0;
107
108 if (msglen > 255) {
109 msglen = 255;
110 }
111
112 /* If first message, Send 150ms of MARK's */
113 if (msgnum == 1) {
114 for (x = 0; x < 150; x++) { /* was 150 */
116 }
117 }
118
119 /* Put message type */
120 PUT_CLID(msgtype);
121 sum = msgtype;
122
123 /* Put message length (plus one for the message number) */
124 PUT_CLID(msglen + 1);
125 sum += msglen + 1;
126
127 /* Put message number */
128 PUT_CLID(msgnum);
129 sum += msgnum;
130
131 /* Put actual message */
132 for (x = 0; x < msglen; x++) {
133 PUT_CLID(msg[x]);
134 sum += msg[x];
135 }
136
137 /* Put 2's compliment of sum */
138 PUT_CLID(256-(sum & 0xff));
139
140#if 0
141 if (last) {
142 /* Put trailing marks */
143 for (x = 0; x < 50; x++) {
145 }
146 }
147#endif
148 return bytes;
149
150}
struct sla_ringing_trunk * last
Definition: app_sla.c:332
#define PUT_CLID(byte)
Definition: callerid.h:412
#define PUT_CLID_MARKMS
Definition: callerid.h:397

References last, PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __adsi_transmit_messages().

◆ adsi_get_cpeid()

static int adsi_get_cpeid ( struct ast_channel chan,
unsigned char *  cpeid,
int  voice 
)
static

Definition at line 651 of file res_adsi.c.

652{
653 unsigned char buf[256] = "";
654 int bytes = 0, res;
655
656 bytes += adsi_data_mode(buf);
658
659 bytes = 0;
660 bytes += adsi_query_cpeid(buf);
662
663 /* Get response */
664 res = adsi_read_encoded_dtmf(chan, cpeid, 4);
665 if (res != 4) {
666 ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
667 res = 0;
668 } else {
669 res = 1;
670 }
671
672 if (voice) {
673 bytes = 0;
674 bytes += adsi_voice_mode(buf, 0);
676 /* Ignore the resulting DTMF B announcing it's in voice mode */
677 ast_waitfordigit(chan, 1000);
678 }
679 return res;
680}
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3175
static int adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen)
Definition: res_adsi.c:614
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:794
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:749
static int adsi_query_cpeid(unsigned char *buf)
Definition: res_adsi.c:594

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(), buf, and LOG_WARNING.

◆ adsi_get_cpeinfo()

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

Definition at line 682 of file res_adsi.c.

683{
684 unsigned char buf[256] = "";
685 int bytes = 0, res;
686
687 bytes += adsi_data_mode(buf);
689
690 bytes = 0;
691 bytes += adsi_query_cpeinfo(buf);
693
694 /* Get width */
695 if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
696 return res;
697 }
698 if (strlen((char *) buf) != 2) {
699 ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
700 res = 0;
701 } else {
702 res = 1;
703 }
704 if (width) {
705 *width = atoi((char *) buf);
706 }
707 /* Get height */
708 memset(buf, 0, sizeof(buf));
709 if (res) {
710 if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
711 return res;
712 }
713 if (strlen((char *) buf) != 2) {
714 ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
715 res = 0;
716 } else {
717 res = 1;
718 }
719 if (height) {
720 *height = atoi((char *) buf);
721 }
722 }
723 /* Get buttons */
724 memset(buf, 0, sizeof(buf));
725 if (res) {
726 if ((res = ast_readstring(chan, (char *) buf, 1, 1000, 500, "")) < 0) {
727 return res;
728 }
729 if (strlen((char *) buf) != 1) {
730 ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
731 res = 0;
732 } else {
733 res = 1;
734 }
735 if (buttons) {
736 *buttons = atoi((char *) buf);
737 }
738 }
739 if (voice) {
740 bytes = 0;
741 bytes += adsi_voice_mode(buf, 0);
743 /* Ignore the resulting DTMF B announcing it's in voice mode */
744 ast_waitfordigit(chan, 1000);
745 }
746 return res;
747}
static int adsi_query_cpeinfo(unsigned char *buf)
Definition: res_adsi.c:604

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

◆ adsi_input_control()

static int adsi_input_control ( unsigned char *  buf,
int  page,
int  line,
int  display,
int  format,
int  just 
)
static

Definition at line 883 of file res_adsi.c.

884{
885 int bytes = 0;
886
887 if (page) {
888 if (line > 4) return -1;
889 } else {
890 if (line > 33) return -1;
891 }
892
893 if (line < 1) {
894 return -1;
895 }
896
897 buf[bytes++] = ADSI_INPUT_CONTROL;
898 bytes++;
899 buf[bytes++] = ((page & 1) << 7) | (line & 0x3f);
900 buf[bytes++] = ((display & 1) << 7) | ((just & 0x3) << 4) | (format & 0x7);
901
902 buf[1] = bytes - 2;
903 return bytes;
904}
#define ADSI_INPUT_CONTROL
Definition: adsi.h:45

References ADSI_INPUT_CONTROL, and buf.

◆ adsi_input_format()

static int adsi_input_format ( unsigned char *  buf,
int  num,
int  dir,
int  wrap,
char *  format1,
char *  format2 
)
static

Definition at line 906 of file res_adsi.c.

907{
908 int bytes = 0;
909
910 if (ast_strlen_zero((char *) format1)) {
911 return -1;
912 }
913
914 buf[bytes++] = ADSI_INPUT_FORMAT;
915 bytes++;
916 buf[bytes++] = ((dir & 1) << 7) | ((wrap & 1) << 6) | (num & 0x7);
917 bytes += ccopy(buf + bytes, (unsigned char *) format1, 20);
918 buf[bytes++] = 0xff;
919 if (!ast_strlen_zero(format2)) {
920 bytes += ccopy(buf + bytes, (unsigned char *) format2, 20);
921 }
922 buf[1] = bytes - 2;
923 return bytes;
924}
#define ADSI_INPUT_FORMAT
Definition: adsi.h:46
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

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

◆ adsi_load()

static void adsi_load ( int  reload)
static

Definition at line 1103 of file res_adsi.c.

1104{
1105 int x = 0;
1106 struct ast_config *conf = NULL;
1107 struct ast_variable *v;
1108 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1109 char *name, *sname;
1110 init_state();
1111
1112 conf = ast_config_load("adsi.conf", config_flags);
1114 return;
1115 }
1116 for (v = ast_variable_browse(conf, "intro"); v; v = v->next) {
1117 if (!strcasecmp(v->name, "alignment")) {
1119 } else if (!strcasecmp(v->name, "greeting")) {
1120 if (x < ADSI_MAX_INTRO) {
1121 aligns[x] = alignment;
1122 ast_copy_string(intro[x], v->value, sizeof(intro[x]));
1123 x++;
1124 }
1125 } else if (!strcasecmp(v->name, "maxretries")) {
1126 if (atoi(v->value) > 0) {
1127 maxretries = atoi(v->value);
1128 }
1129 }
1130 }
1131 if (x) {
1132 total = x;
1133 }
1134
1135 x = 0;
1136 for (v = ast_variable_browse(conf, "speeddial"); v; v = v->next) {
1137 char buf[3 * SPEEDDIAL_MAX_LEN];
1138 char *stringp = buf;
1139 ast_copy_string(buf, v->value, sizeof(buf));
1140 name = strsep(&stringp, ",");
1141 sname = strsep(&stringp, ",");
1142 if (!sname) {
1143 sname = name;
1144 }
1145 if (x < ADSI_MAX_SPEED_DIAL) {
1146 ast_copy_string(speeddial[x][0], v->name, sizeof(speeddial[x][0]));
1147 ast_copy_string(speeddial[x][1], name, 18);
1148 ast_copy_string(speeddial[x][2], sname, 7);
1149 x++;
1150 }
1151 }
1152 if (x) {
1153 speeds = x;
1154 }
1156
1157 return;
1158}
static const char name[]
Definition: format_mp3.c:68
char * strsep(char **str, const char *delims)
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition: extconf.c:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
static int aligns[ADSI_MAX_INTRO]
Definition: res_adsi.c:66
#define SPEEDDIAL_MAX_LEN
Definition: res_adsi.c:68
#define ADSI_MAX_SPEED_DIAL
Definition: res_adsi.c:56
static int alignment
Definition: res_adsi.c:71
#define ADSI_MAX_INTRO
Definition: res_adsi.c:55
static char speeddial[ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN]
Definition: res_adsi.c:69
static char intro[ADSI_MAX_INTRO][20]
Definition: res_adsi.c:65
static int total
Definition: res_adsi.c:970
static int reload(void)
Definition: res_adsi.c:1160
static void init_state(void)
Definition: res_adsi.c:1084
static int str2align(const char *s)
Definition: res_adsi.c:1071
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Structure used to handle boolean flags.
Definition: utils.h:199
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
All configuration options for http media cache.

References ADSI_MAX_INTRO, ADSI_MAX_SPEED_DIAL, alignment, aligns, ast_config_destroy(), ast_config_load, ast_copy_string(), ast_variable_browse(), buf, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, init_state(), intro, maxretries, name, ast_variable::name, ast_variable::next, NULL, reload(), speeddial, SPEEDDIAL_MAX_LEN, speeds, str2align(), strsep(), total, and ast_variable::value.

Referenced by load_module(), and reload().

◆ adsi_load_session()

static int adsi_load_session ( struct ast_channel chan,
unsigned char *  app,
int  ver,
int  data 
)
static

Definition at line 1015 of file res_adsi.c.

1016{
1017 unsigned char dsp[256] = "";
1018 int bytes = 0, res;
1019 char resp[2];
1020
1021 /* Connect to session */
1022 bytes += adsi_connect_session(dsp + bytes, app, ver);
1023
1024 if (data) {
1025 bytes += adsi_data_mode(dsp + bytes);
1026 }
1027
1028 /* Prepare key setup messages */
1029 if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1030 return -1;
1031 }
1032 if (app) {
1033 if ((res = ast_readstring(chan, resp, 1, 1200, 1200, "")) < 0) {
1034 return -1;
1035 }
1036 if (res) {
1037 ast_debug(1, "No response from CPE about version. Assuming not there.\n");
1038 return 0;
1039 }
1040 if (!strcmp(resp, "B")) {
1041 ast_debug(1, "CPE has script '%s' version %d already loaded\n", app, ver);
1042 return 1;
1043 } else if (!strcmp(resp, "A")) {
1044 ast_debug(1, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
1045 } else {
1046 ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
1047 }
1048 } else
1049 return 1;
1050 return 0;
1051
1052}
static const char app[]
Definition: app_adsiprog.c:56
static int adsi_connect_session(unsigned char *buf, unsigned char *fdn, int ver)
Definition: res_adsi.c:523

References adsi_connect_session(), adsi_data_mode(), ADSI_MSG_DISPLAY, adsi_transmit_message_full(), app, ast_debug, ast_log, ast_readstring(), ast_frame::data, and LOG_WARNING.

◆ adsi_load_soft_key()

static int adsi_load_soft_key ( unsigned char *  buf,
int  key,
const char *  llabel,
const char *  slabel,
char *  ret,
int  data 
)
static

Definition at line 482 of file res_adsi.c.

483{
484 int bytes = 0;
485
486 /* Abort if invalid key specified */
487 if ((key < 2) || (key > 33)) {
488 return -1;
489 }
490
491 buf[bytes++] = ADSI_LOAD_SOFTKEY;
492 /* Reserve for length */
493 bytes++;
494 /* Which key */
495 buf[bytes++] = key;
496
497 /* Carefully copy long label */
498 bytes += ccopy(buf + bytes, (const unsigned char *)llabel, 18);
499
500 /* Place delimiter */
501 buf[bytes++] = 0xff;
502
503 /* Short label */
504 bytes += ccopy(buf + bytes, (const unsigned char *)slabel, 7);
505
506
507 /* If specified, copy return string */
508 if (ret) {
509 /* Place delimiter */
510 buf[bytes++] = 0xff;
511 if (data) {
512 buf[bytes++] = ADSI_SWITCH_TO_DATA2;
513 }
514 /* Carefully copy return string */
515 bytes += ccopy(buf + bytes, (const unsigned char *)ret, 20);
516
517 }
518 /* Replace parameter length */
519 buf[1] = bytes - 2;
520 return bytes;
521}
#define ADSI_SWITCH_TO_DATA2
Definition: adsi.h:87
#define ADSI_LOAD_SOFTKEY
Definition: adsi.h:36

References ADSI_LOAD_SOFTKEY, ADSI_SWITCH_TO_DATA2, buf, ccopy(), and ast_frame::data.

◆ adsi_print()

static int adsi_print ( struct ast_channel chan,
char **  lines,
int *  align,
int  voice 
)
static

Definition at line 995 of file res_adsi.c.

996{
997 unsigned char buf[4096];
998 int bytes = 0, res, x;
999
1000 for (x = 0; lines[x]; x++) {
1001 bytes += adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, alignments[x], 0, lines[x], "");
1002 }
1003 bytes += adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
1004 if (voice) {
1005 bytes += adsi_voice_mode(buf + bytes, 0);
1006 }
1007 res = adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
1008 if (voice) {
1009 /* Ignore the resulting DTMF B announcing it's in voice mode */
1010 ast_waitfordigit(chan, 1000);
1011 }
1012 return res;
1013}
static int adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Definition: res_adsi.c:836

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

◆ adsi_query_cpeid()

static int adsi_query_cpeid ( unsigned char *  buf)
static

Definition at line 594 of file res_adsi.c.

595{
596 int bytes = 0;
597 buf[bytes++] = ADSI_QUERY_CPEID;
598 /* Reserve space for length */
599 bytes++;
600 buf[1] = bytes - 2;
601 return bytes;
602}
#define ADSI_QUERY_CPEID
Definition: adsi.h:58

References ADSI_QUERY_CPEID, and buf.

Referenced by adsi_get_cpeid().

◆ adsi_query_cpeinfo()

static int adsi_query_cpeinfo ( unsigned char *  buf)
static

Definition at line 604 of file res_adsi.c.

605{
606 int bytes = 0;
607 buf[bytes++] = ADSI_QUERY_CONFIG;
608 /* Reserve space for length */
609 bytes++;
610 buf[1] = bytes - 2;
611 return bytes;
612}
#define ADSI_QUERY_CONFIG
Definition: adsi.h:57

References ADSI_QUERY_CONFIG, and buf.

Referenced by adsi_get_cpeinfo().

◆ adsi_read_encoded_dtmf()

static int adsi_read_encoded_dtmf ( struct ast_channel chan,
unsigned char *  buf,
int  maxlen 
)
static

Definition at line 614 of file res_adsi.c.

615{
616 int bytes = 0, res, gotstar = 0, pos = 0;
617 unsigned char current = 0;
618
619 memset(buf, 0, maxlen);
620
621 while (bytes <= maxlen) {
622 /* Wait up to a second for a digit */
623 if (!(res = ast_waitfordigit(chan, 1000))) {
624 break;
625 }
626 if (res == '*') {
627 gotstar = 1;
628 continue;
629 }
630 /* Ignore anything other than a digit */
631 if ((res < '0') || (res > '9')) {
632 continue;
633 }
634 res -= '0';
635 if (gotstar) {
636 res += 9;
637 }
638 if (pos) {
639 pos = 0;
640 buf[bytes++] = (res << 4) | current;
641 } else {
642 pos = 1;
643 current = res;
644 }
645 gotstar = 0;
646 }
647
648 return bytes;
649}
size_t current
Definition: main/cli.c:113

References ast_waitfordigit(), buf, and current.

Referenced by adsi_get_cpeid().

◆ adsi_set_keys()

static int adsi_set_keys ( unsigned char *  buf,
unsigned char *  keys 
)
static

Definition at line 926 of file res_adsi.c.

927{
928 int bytes = 0, x;
929
930 /* Message type */
931 buf[bytes++] = ADSI_INIT_SOFTKEY_LINE;
932 /* Space for size */
933 bytes++;
934 /* Key definitions */
935 for (x = 0; x < 6; x++) {
936 buf[bytes++] = (keys[x] & 0x3f) ? keys[x] : (keys[x] | 0x1);
937 }
938 buf[1] = bytes - 2;
939 return bytes;
940}
#define ADSI_INIT_SOFTKEY_LINE
Definition: adsi.h:37

References ADSI_INIT_SOFTKEY_LINE, and buf.

Referenced by adsi_channel_restore().

◆ adsi_set_line()

static int adsi_set_line ( unsigned char *  buf,
int  page,
int  line 
)
static

Definition at line 942 of file res_adsi.c.

943{
944 int bytes = 0;
945
946 /* Sanity check line number */
947
948 if (page) {
949 if (line > 4) return -1;
950 } else {
951 if (line > 33) return -1;
952 }
953
954 if (line < 1) {
955 return -1;
956 }
957 /* Parameter type */
958 buf[bytes++] = ADSI_LINE_CONTROL;
959
960 /* Reserve space for size */
961 bytes++;
962
963 /* Page and line */
964 buf[bytes++] = ((page & 0x1) << 7) | (line & 0x3f);
965
966 buf[1] = bytes - 2;
967 return bytes;
968}
#define ADSI_LINE_CONTROL
Definition: adsi.h:39

References ADSI_LINE_CONTROL, and buf.

Referenced by adsi_channel_restore(), and adsi_print().

◆ adsi_transmit_message()

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

Definition at line 466 of file res_adsi.c.

467{
468 return adsi_transmit_message_full(chan, msg, msglen, msgtype, 1);
469}

References adsi_transmit_message_full().

◆ adsi_transmit_message_full()

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

Definition at line 390 of file res_adsi.c.

391{
392 unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
393 int msglens[5], msgtypes[5], newdatamode = (ast_channel_adsicpe(chan) & ADSI_FLAG_DATAMODE), res, x, waitforswitch = 0;
394 RAII_VAR(struct ast_format *, writeformat, NULL, ao2_cleanup);
395 RAII_VAR(struct ast_format *, readformat, NULL, ao2_cleanup);
396
397 for (x = 0; x < msglen; x += (msg[x+1]+2)) {
398 if (msg[x] == ADSI_SWITCH_TO_DATA) {
399 ast_debug(1, "Switch to data is sent!\n");
400 waitforswitch++;
401 newdatamode = ADSI_FLAG_DATAMODE;
402 }
403
404 if (msg[x] == ADSI_SWITCH_TO_VOICE) {
405 ast_debug(1, "Switch to voice is sent!\n");
406 waitforswitch++;
407 newdatamode = 0;
408 }
409 }
410 msgs[0] = msg;
411
412 msglens[0] = msglen;
413 msgtypes[0] = msgtype;
414
415 if (msglen > 253) {
416 ast_log(LOG_WARNING, "Can't send ADSI message of %d bytes, too large\n", msglen);
417 return -1;
418 }
419
420 ast_stopstream(chan);
421
422 writeformat = ao2_bump(ast_channel_writeformat(chan));
423 readformat = ao2_bump(ast_channel_readformat(chan));
424
426 ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
427 return -1;
428 }
429
431 ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
432 if (writeformat) {
433 if (ast_set_write_format(chan, writeformat)) {
434 ast_log(LOG_WARNING, "Unable to restore write format to %s\n", ast_format_get_name(writeformat));
435 }
436 }
437 return -1;
438 }
439 res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
440
441 if (dowait) {
442 ast_debug(1, "Wait for switch is '%d'\n", waitforswitch);
443 while (waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) {
444 res = 0;
445 ast_debug(1, "Waiting for 'B'...\n");
446 }
447 }
448
449 if (!res) {
450 ast_channel_adsicpe_set(chan, (ast_channel_adsicpe(chan) & ~ADSI_FLAG_DATAMODE) | newdatamode);
451 }
452
453 if (writeformat) {
454 ast_set_write_format(chan, writeformat);
455 }
456 if (readformat) {
457 ast_set_read_format(chan, readformat);
458 }
459
460 if (!res) {
461 res = ast_safe_sleep(chan, 100 );
462 }
463 return res;
464}
#define ADSI_SWITCH_TO_VOICE
Definition: adsi.h:43
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5762
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5803
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:222
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
Definition: res_adsi.c:230
Definition of a media format.
Definition: format.c:43
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References __adsi_transmit_messages(), ADSI_FLAG_DATAMODE, ADSI_SWITCH_TO_DATA, ADSI_SWITCH_TO_VOICE, ao2_bump, ao2_cleanup, ast_channel_adsicpe_set(), ast_channel_readformat(), ast_channel_writeformat(), ast_debug, ast_format_get_name(), ast_format_ulaw, ast_log, ast_safe_sleep(), ast_set_read_format(), ast_set_write_format(), ast_stopstream(), ast_waitfordigit(), LOG_WARNING, NULL, and RAII_VAR.

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

◆ adsi_unload_session()

static int adsi_unload_session ( struct ast_channel chan)
static

Definition at line 1054 of file res_adsi.c.

1055{
1056 unsigned char dsp[256] = "";
1057 int bytes = 0;
1058
1059 /* Connect to session */
1060 bytes += adsi_disconnect_session(dsp + bytes);
1061 bytes += adsi_voice_mode(dsp + bytes, 0);
1062
1063 /* Prepare key setup messages */
1064 if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1065 return -1;
1066 }
1067
1068 return 0;
1069}
static int adsi_disconnect_session(unsigned char *buf)
Definition: res_adsi.c:579

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

◆ adsi_voice_mode()

static int adsi_voice_mode ( unsigned char *  buf,
int  when 
)
static

Definition at line 794 of file res_adsi.c.

795{
796 int bytes = 0;
797
798 /* Message type */
799 buf[bytes++] = ADSI_SWITCH_TO_VOICE;
800
801 /* Reserve space for length */
802 bytes++;
803
804 buf[bytes++] = when & 0x7f;
805
806 buf[1] = bytes - 2;
807 return bytes;
808
809}

References ADSI_SWITCH_TO_VOICE, and buf.

Referenced by adsi_get_cpeid(), adsi_get_cpeinfo(), adsi_print(), and adsi_unload_session().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1218 of file res_adsi.c.

◆ ccopy()

static int ccopy ( unsigned char *  dst,
const unsigned char *  src,
int  max 
)
inlinestatic

Definition at line 471 of file res_adsi.c.

472{
473 int x = 0;
474 /* Carefully copy the requested data */
475 while ((x < max) && src[x] && (src[x] != 0xff)) {
476 dst[x] = src[x];
477 x++;
478 }
479 return x;
480}
#define max(a, b)
Definition: f2c.h:198

References max, and ast_frame::src.

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

◆ init_state()

static void init_state ( void  )
static

Definition at line 1084 of file res_adsi.c.

1085{
1086 int x;
1087
1088 for (x = 0; x < ADSI_MAX_INTRO; x++) {
1090 }
1091 ast_copy_string(intro[0], "Welcome to the", sizeof(intro[0]));
1092 ast_copy_string(intro[1], "Asterisk", sizeof(intro[1]));
1093 ast_copy_string(intro[2], "Open Source PBX", sizeof(intro[2]));
1094 total = 3;
1095 speeds = 0;
1096 for (x = 3; x < ADSI_MAX_INTRO; x++) {
1097 intro[x][0] = '\0';
1098 }
1099 memset(speeddial, 0, sizeof(speeddial));
1101}
#define ADSI_JUST_CENT
Definition: adsi.h:114

References ADSI_JUST_CENT, ADSI_MAX_INTRO, alignment, aligns, ast_copy_string(), intro, speeddial, speeds, and total.

Referenced by adsi_load().

◆ load_module()

static int load_module ( void  )
static

Definition at line 1198 of file res_adsi.c.

1199{
1200 adsi_load(0);
1203}
void ast_adsi_install_funcs(const struct adsi_funcs *funcs)
Definition: adsi.c:340
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
static struct adsi_funcs res_adsi_funcs
Definition: res_adsi.c:1166
static void adsi_load(int reload)
Definition: res_adsi.c:1103

References adsi_load(), ast_adsi_install_funcs(), AST_MODULE_LOAD_SUCCESS, and res_adsi_funcs.

◆ reload()

static int reload ( void  )
static

Definition at line 1160 of file res_adsi.c.

1161{
1162 adsi_load(1);
1163 return 0;
1164}

References adsi_load().

Referenced by adsi_load().

◆ str2align()

static int str2align ( const char *  s)
static

Definition at line 1071 of file res_adsi.c.

1072{
1073 if (!strncasecmp(s, "l", 1)) {
1074 return ADSI_JUST_LEFT;
1075 } else if (!strncasecmp(s, "r", 1)) {
1076 return ADSI_JUST_RIGHT;
1077 } else if (!strncasecmp(s, "i", 1)) {
1078 return ADSI_JUST_IND;
1079 } else {
1080 return ADSI_JUST_CENT;
1081 }
1082}
#define ADSI_JUST_RIGHT
Definition: adsi.h:113
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_JUST_IND
Definition: adsi.h:115

References ADSI_JUST_CENT, ADSI_JUST_IND, ADSI_JUST_LEFT, and ADSI_JUST_RIGHT.

Referenced by adsi_load().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1205 of file res_adsi.c.

1206{
1207 /* Can't unload this once we're loaded */
1209 return -1;
1210}

References ast_adsi_install_funcs(), and NULL.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = 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, .support_level = AST_MODULE_SUPPORT_DEPRECATED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_APP_DEPEND, }
static

Definition at line 1218 of file res_adsi.c.

◆ alignment

int alignment = 0
static

Definition at line 71 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

◆ aligns

int aligns[ADSI_MAX_INTRO]
static

Definition at line 66 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1218 of file res_adsi.c.

◆ intro

char intro[ADSI_MAX_INTRO][20]
static

Definition at line 65 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

◆ maxretries

int maxretries = DEFAULT_ADSI_MAX_RETRIES
static

◆ res_adsi_funcs

struct adsi_funcs res_adsi_funcs
static

Definition at line 1166 of file res_adsi.c.

Referenced by load_module().

◆ speeddial

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

Definition at line 69 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

◆ speeds

int speeds = 0
static

Definition at line 971 of file res_adsi.c.

Referenced by adsi_channel_restore(), adsi_load(), and init_state().

◆ total

int total = 0
static