Wed Jan 8 2020 09:50:17

Asterisk developer's documentation


res_adsi.c File Reference

ADSI support. More...

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

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, format_t 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)
 
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_APP_DEPEND, }
 
static int alignment = 0
 
static int aligns [ADSI_MAX_INTRO]
 
static struct ast_module_infoast_module_info = &__mod_info
 
static char intro [ADSI_MAX_INTRO][20]
 
static int maxretries = DEFAULT_ADSI_MAX_RETRIES
 
static 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

#define ADSI_FLAG_DATAMODE   (1 << 8)

Definition at line 59 of file res_adsi.c.

Referenced by __adsi_transmit_messages(), and adsi_transmit_message_full().

#define ADSI_MAX_INTRO   20

Definition at line 56 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

#define ADSI_MAX_SPEED_DIAL   6

Definition at line 57 of file res_adsi.c.

Referenced by adsi_load().

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

Definition at line 64 of file res_adsi.c.

Referenced by adsi_channel_restore().

#define DEFAULT_ADSI_MAX_RETRIES   3

Definition at line 54 of file res_adsi.c.

#define SPEEDDIAL_MAX_LEN   20

Definition at line 69 of file res_adsi.c.

Referenced by adsi_load().

Function Documentation

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

Definition at line 233 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_debug, AST_FORMAT_ULAW, AST_FRAME_DTMF, ast_frfree, ast_gen_cas(), ast_log(), ast_read(), ast_readstring(), ast_waitfor(), errno, f, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, and ast_frame::subclass.

Referenced by adsi_transmit_message_full().

234 {
235  /* msglen must be no more than 256 bits, each */
236  unsigned char buf[24000 * 5];
237  int pos = 0, res, x, start = 0, retries = 0, waittime, rem = 0, def;
238  char ack[3];
239  struct ast_frame *f;
240 
241  if (chan->adsicpe == AST_ADSI_UNAVAILABLE) {
242  /* Don't bother if we know they don't support ADSI */
243  errno = ENOSYS;
244  return -1;
245  }
246 
247  while (retries < maxretries) {
248  if (!(chan->adsicpe & ADSI_FLAG_DATAMODE)) {
249  /* Generate CAS (no SAS) */
250  ast_gen_cas(buf, 0, 680, AST_FORMAT_ULAW);
251 
252  /* Send CAS */
253  if (adsi_careful_send(chan, buf, 680, NULL)) {
254  ast_log(LOG_WARNING, "Unable to send CAS\n");
255  }
256 
257  /* Wait For DTMF result */
258  waittime = 500;
259  for (;;) {
260  if (((res = ast_waitfor(chan, waittime)) < 1)) {
261  /* Didn't get back DTMF A in time */
262  ast_debug(1, "No ADSI CPE detected (%d)\n", res);
263  if (!chan->adsicpe) {
265  }
266  errno = ENOSYS;
267  return -1;
268  }
269  waittime = res;
270  if (!(f = ast_read(chan))) {
271  ast_debug(1, "Hangup in ADSI\n");
272  return -1;
273  }
274  if (f->frametype == AST_FRAME_DTMF) {
275  if (f->subclass.integer == 'A') {
276  /* Okay, this is an ADSI CPE. Note this for future reference, too */
277  if (!chan->adsicpe) {
278  chan->adsicpe = AST_ADSI_AVAILABLE;
279  }
280  break;
281  } else {
282  if (f->subclass.integer == 'D') {
283  ast_debug(1, "Off-hook capable CPE only, not ADSI\n");
284  } else {
285  ast_log(LOG_WARNING, "Unknown ADSI response '%c'\n", f->subclass.integer);
286  }
287  if (!chan->adsicpe) {
289  }
290  errno = ENOSYS;
291  ast_frfree(f);
292  return -1;
293  }
294  }
295  ast_frfree(f);
296  }
297 
298  ast_debug(1, "ADSI Compatible CPE Detected\n");
299  } else {
300  ast_debug(1, "Already in data mode\n");
301  }
302 
303  x = 0;
304  pos = 0;
305 #if 1
306  def= ast_channel_defer_dtmf(chan);
307 #endif
308  while ((x < 6) && msg[x]) {
309  if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], AST_FORMAT_ULAW)) < 0) {
310  ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, chan->name);
311  return -1;
312  }
313  ast_debug(1, "Message %d, of %d input bytes, %d output bytes\n", x + 1, msglen[x], res);
314  pos += res;
315  x++;
316  }
317 
318 
319  rem = 0;
320  res = adsi_careful_send(chan, buf, pos, &rem);
321  if (!def) {
323  }
324  if (res) {
325  return -1;
326  }
327 
328  ast_debug(1, "Sent total spill of %d bytes\n", pos);
329 
330  memset(ack, 0, sizeof(ack));
331  /* Get real result and check for hangup */
332  if ((res = ast_readstring(chan, ack, 2, 1000, 1000, "")) < 0) {
333  return -1;
334  }
335  if (ack[0] == 'D') {
336  ast_debug(1, "Acked up to message %d\n", atoi(ack + 1)); start += atoi(ack + 1);
337  if (start >= x) {
338  break;
339  } else {
340  retries++;
341  ast_debug(1, "Retransmitting (%d), from %d\n", retries, start + 1);
342  }
343  } else {
344  retries++;
345  ast_log(LOG_WARNING, "Unexpected response to ack: %s (retry %d)\n", ack, retries);
346  }
347  }
348  if (retries >= maxretries) {
349  ast_log(LOG_WARNING, "Maximum ADSI Retries (%d) exceeded\n", maxretries);
350  errno = ETIMEDOUT;
351  return -1;
352  }
353  return 0;
354 }
union ast_frame_subclass subclass
Definition: frame.h:146
#define LOG_WARNING
Definition: logger.h:144
#define AST_FRAME_DTMF
Definition: frame.h:128
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
#define ADSI_FLAG_DATAMODE
Definition: res_adsi.c:59
enum ast_channel_adsicpe adsicpe
Definition: channel.h:844
int ast_channel_defer_dtmf(struct ast_channel *chan)
Defers DTMF so that you only read things like hangups and audio.
Definition: channel.c:1616
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_channel_undefer_dtmf(struct ast_channel *chan)
Unset defer DTMF flag on channel.
Definition: channel.c:1628
static int adsi_generate(unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, format_t codec)
Definition: res_adsi.c:103
static int maxretries
Definition: res_adsi.c:61
#define AST_FORMAT_ULAW
Definition: frame.h:246
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
int ast_gen_cas(unsigned char *outbuf, int sas, int len, format_t codec)
Generate a CAS (CPE Alert Signal) tone for &#39;n&#39; samples.
Definition: callerid.c:262
static struct ast_format f[]
Definition: format_g726.c:181
static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int len, int *remain)
Definition: res_adsi.c:153
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
static void __reg_module ( void  )
static

Definition at line 1214 of file res_adsi.c.

static void __unreg_module ( void  )
static

Definition at line 1214 of file res_adsi.c.

static int adsi_available ( struct ast_channel chan)
static

Definition at line 808 of file res_adsi.c.

References ast_channel::adsicpe, AST_ADSI_AVAILABLE, and AST_ADSI_UNKNOWN.

809 {
810  int cpe = chan->adsicpe & 0xff;
811  if ((cpe == AST_ADSI_AVAILABLE) ||
812  (cpe == AST_ADSI_UNKNOWN)) {
813  return 1;
814  }
815  return 0;
816 }
enum ast_channel_adsicpe adsicpe
Definition: channel.h:844
static int adsi_begin_download ( struct ast_channel chan,
char *  service,
unsigned char *  fdn,
unsigned char *  sec,
int  version 
)
static

Definition at line 356 of file res_adsi.c.

References adsi_download_connect(), ADSI_MSG_DOWNLOAD, adsi_transmit_message_full(), ast_debug, and ast_readstring().

357 {
358  int bytes = 0;
359  unsigned char buf[256];
360  char ack[2];
361 
362  /* Setup the resident soft key stuff, a piece at a time */
363  /* Upload what scripts we can for voicemail ahead of time */
364  bytes += adsi_download_connect(buf + bytes, service, fdn, sec, version);
365  if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
366  return -1;
367  }
368  if (ast_readstring(chan, ack, 1, 10000, 10000, "")) {
369  return -1;
370  }
371  if (ack[0] == 'B') {
372  return 0;
373  }
374  ast_debug(1, "Download was denied by CPE\n");
375  return -1;
376 }
uint32_t version
enum ast_cc_service_type service
Definition: chan_sip.c:821
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
static int adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
Definition: res_adsi.c:544
static int adsi_careful_send ( struct ast_channel chan,
unsigned char *  buf,
int  len,
int *  remain 
)
static

Definition at line 153 of file res_adsi.c.

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

Referenced by __adsi_transmit_messages().

154 {
155  /* Sends carefully on a full duplex channel by using reading for
156  timing */
157  struct ast_frame *inf, outf;
158  int amt;
159 
160  /* Zero out our outgoing frame */
161  memset(&outf, 0, sizeof(outf));
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  outf.frametype = AST_FRAME_VOICE;
174  outf.data.ptr = buf;
175  outf.datalen = amt;
176  outf.samples = amt;
177  if (ast_write(chan, &outf)) {
178  ast_log(LOG_WARNING, "Failed to carefully write frame\n");
179  return -1;
180  }
181  /* Update pointers and lengths */
182  buf += amt;
183  len -= amt;
184  }
185 
186  while (len) {
187  amt = len;
188  /* If we don't get anything at all back in a second, forget
189  about it */
190  if (ast_waitfor(chan, 1000) < 1) {
191  return -1;
192  }
193  /* Detect hangup */
194  if (!(inf = ast_read(chan))) {
195  return -1;
196  }
197 
198  /* Drop any frames that are not voice */
199  if (inf->frametype != AST_FRAME_VOICE) {
200  ast_frfree(inf);
201  continue;
202  }
203 
204  if (inf->subclass.codec != AST_FORMAT_ULAW) {
205  ast_log(LOG_WARNING, "Channel not in ulaw?\n");
206  ast_frfree(inf);
207  return -1;
208  }
209  /* Send no more than they sent us */
210  if (amt > inf->datalen) {
211  amt = inf->datalen;
212  } else if (remain) {
213  *remain = inf->datalen - amt;
214  }
215  outf.frametype = AST_FRAME_VOICE;
217  outf.data.ptr = buf;
218  outf.datalen = amt;
219  outf.samples = amt;
220  if (ast_write(chan, &outf)) {
221  ast_log(LOG_WARNING, "Failed to carefully write frame\n");
222  ast_frfree(inf);
223  return -1;
224  }
225  /* Update pointers and lengths */
226  buf += amt;
227  len -= amt;
228  ast_frfree(inf);
229  }
230  return 0;
231 }
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
format_t codec
Definition: frame.h:137
int datalen
Definition: frame.h:148
#define AST_FORMAT_ULAW
Definition: frame.h:246
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
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:4916
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3539
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
union ast_frame::@172 data
int samples
Definition: frame.h:150
static int adsi_channel_restore ( struct ast_channel chan)
static

Definition at line 970 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 speeds.

971 {
972  unsigned char dsp[256] = "", keyd[6] = "";
973  int bytes, x;
974 
975  /* Start with initial display setup */
976  bytes = 0;
977  bytes += adsi_set_line(dsp + bytes, ADSI_INFO_PAGE, 1);
978 
979  /* Prepare key setup messages */
980 
981  if (speeds) {
982  for (x = 0; x < speeds; x++) {
983  keyd[x] = ADSI_SPEED_DIAL + x;
984  }
985  bytes += adsi_set_keys(dsp + bytes, keyd);
986  }
987  adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0);
988  return 0;
989 
990 }
#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:923
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static int speeds
Definition: res_adsi.c:968
#define ADSI_SPEED_DIAL
Definition: res_adsi.c:64
static int adsi_set_line(unsigned char *buf, int page, int line)
Definition: res_adsi.c:939
static int adsi_clear_screen ( unsigned char *  buf)
static

Definition at line 776 of file res_adsi.c.

References ADSI_CLEAR_SCREEN.

777 {
778  int bytes = 0;
779 
780  /* Message type */
781  buf[bytes++] = ADSI_CLEAR_SCREEN;
782 
783  /* Reserve space for length */
784  bytes++;
785 
786  buf[1] = bytes - 2;
787  return bytes;
788 
789 }
#define ADSI_CLEAR_SCREEN
Definition: adsi.h:56
static int adsi_clear_soft_keys ( unsigned char *  buf)
static

Definition at line 761 of file res_adsi.c.

References ADSI_CLEAR_SOFTKEY.

762 {
763  int bytes = 0;
764 
765  /* Message type */
766  buf[bytes++] = ADSI_CLEAR_SOFTKEY;
767 
768  /* Reserve space for length */
769  bytes++;
770 
771  buf[1] = bytes - 2;
772  return bytes;
773 
774 }
#define ADSI_CLEAR_SOFTKEY
Definition: adsi.h:44
static int adsi_connect_session ( unsigned char *  buf,
unsigned char *  fdn,
int  ver 
)
static

Definition at line 520 of file res_adsi.c.

References ADSI_CONNECT_SESSION.

Referenced by adsi_load_session().

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

Definition at line 746 of file res_adsi.c.

References ADSI_SWITCH_TO_DATA.

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

747 {
748  int bytes = 0;
749 
750  /* Message type */
751  buf[bytes++] = ADSI_SWITCH_TO_DATA;
752 
753  /* Reserve space for length */
754  bytes++;
755 
756  buf[1] = bytes - 2;
757  return bytes;
758 
759 }
#define ADSI_SWITCH_TO_DATA
Definition: adsi.h:42
static int adsi_disconnect_session ( unsigned char *  buf)
static

Definition at line 576 of file res_adsi.c.

References ADSI_DISC_SESSION.

Referenced by adsi_unload_session().

577 {
578  int bytes = 0;
579 
580  /* Message type */
581  buf[bytes++] = ADSI_DISC_SESSION;
582 
583  /* Reserve space for length */
584  bytes++;
585 
586  buf[1] = bytes - 2;
587  return bytes;
588 
589 }
#define ADSI_DISC_SESSION
Definition: adsi.h:41
static int adsi_display ( unsigned char *  buf,
int  page,
int  line,
int  just,
int  wrap,
char *  col1,
char *  col2 
)
static

Definition at line 833 of file res_adsi.c.

References ADSI_LOAD_VIRTUAL_DISP, and ccopy().

Referenced by adsi_print().

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

Definition at line 544 of file res_adsi.c.

References ADSI_DOWNLOAD_CONNECT, and ccopy().

Referenced by adsi_begin_download().

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

Definition at line 818 of file res_adsi.c.

References ADSI_DOWNLOAD_DISC.

Referenced by adsi_end_download().

819 {
820  int bytes = 0;
821 
822  /* Message type */
823  buf[bytes++] = ADSI_DOWNLOAD_DISC;
824 
825  /* Reserve space for length */
826  bytes++;
827 
828  buf[1] = bytes - 2;
829  return bytes;
830 
831 }
#define ADSI_DOWNLOAD_DISC
Definition: adsi.h:66
static int adsi_end_download ( struct ast_channel chan)
static

Definition at line 378 of file res_adsi.c.

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

379 {
380  int bytes = 0;
381  unsigned char buf[256];
382 
383  /* Setup the resident soft key stuff, a piece at a time */
384  /* Upload what scripts we can for voicemail ahead of time */
385  bytes += adsi_download_disconnect(buf + bytes);
386  if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
387  return -1;
388  }
389  return 0;
390 }
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
#define ADSI_MSG_DOWNLOAD
Definition: adsi.h:33
static int adsi_download_disconnect(unsigned char *buf)
Definition: res_adsi.c:818
static int adsi_generate ( unsigned char *  buf,
int  msgtype,
unsigned char *  msg,
int  msglen,
int  msgnum,
int  last,
format_t  codec 
)
static

Definition at line 103 of file res_adsi.c.

References PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __adsi_transmit_messages().

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

Definition at line 648 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.

649 {
650  unsigned char buf[256] = "";
651  int bytes = 0, res;
652 
653  bytes += adsi_data_mode(buf);
654  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
655 
656  bytes = 0;
657  bytes += adsi_query_cpeid(buf);
658  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
659 
660  /* Get response */
661  res = adsi_read_encoded_dtmf(chan, cpeid, 4);
662  if (res != 4) {
663  ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
664  res = 0;
665  } else {
666  res = 1;
667  }
668 
669  if (voice) {
670  bytes = 0;
671  bytes += adsi_voice_mode(buf, 0);
672  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
673  /* Ignore the resulting DTMF B announcing it's in voice mode */
674  ast_waitfordigit(chan, 1000);
675  }
676  return res;
677 }
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define LOG_WARNING
Definition: logger.h:144
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static int adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen)
Definition: res_adsi.c:611
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:746
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:791
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static int adsi_query_cpeid(unsigned char *buf)
Definition: res_adsi.c:591
static int adsi_get_cpeinfo ( struct ast_channel chan,
int *  width,
int *  height,
int *  buttons,
int  voice 
)
static

Definition at line 679 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.

680 {
681  unsigned char buf[256] = "";
682  int bytes = 0, res;
683 
684  bytes += adsi_data_mode(buf);
685  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
686 
687  bytes = 0;
688  bytes += adsi_query_cpeinfo(buf);
689  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
690 
691  /* Get width */
692  if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
693  return res;
694  }
695  if (strlen((char *) buf) != 2) {
696  ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
697  res = 0;
698  } else {
699  res = 1;
700  }
701  if (width) {
702  *width = atoi((char *) buf);
703  }
704  /* Get height */
705  memset(buf, 0, sizeof(buf));
706  if (res) {
707  if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
708  return res;
709  }
710  if (strlen((char *) buf) != 2) {
711  ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
712  res = 0;
713  } else {
714  res = 1;
715  }
716  if (height) {
717  *height = atoi((char *) buf);
718  }
719  }
720  /* Get buttons */
721  memset(buf, 0, sizeof(buf));
722  if (res) {
723  if ((res = ast_readstring(chan, (char *) buf, 1, 1000, 500, "")) < 0) {
724  return res;
725  }
726  if (strlen((char *) buf) != 1) {
727  ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
728  res = 0;
729  } else {
730  res = 1;
731  }
732  if (buttons) {
733  *buttons = atoi((char *) buf);
734  }
735  }
736  if (voice) {
737  bytes = 0;
738  bytes += adsi_voice_mode(buf, 0);
739  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
740  /* Ignore the resulting DTMF B announcing it's in voice mode */
741  ast_waitfordigit(chan, 1000);
742  }
743  return res;
744 }
static int adsi_query_cpeinfo(unsigned char *buf)
Definition: res_adsi.c:601
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define LOG_WARNING
Definition: logger.h:144
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:746
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:791
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
static int adsi_input_control ( unsigned char *  buf,
int  page,
int  line,
int  display,
int  format,
int  just 
)
static

Definition at line 880 of file res_adsi.c.

References ADSI_INPUT_CONTROL.

881 {
882  int bytes = 0;
883 
884  if (page) {
885  if (line > 4) return -1;
886  } else {
887  if (line > 33) return -1;
888  }
889 
890  if (line < 1) {
891  return -1;
892  }
893 
894  buf[bytes++] = ADSI_INPUT_CONTROL;
895  bytes++;
896  buf[bytes++] = ((page & 1) << 7) | (line & 0x3f);
897  buf[bytes++] = ((display & 1) << 7) | ((just & 0x3) << 4) | (format & 0x7);
898 
899  buf[1] = bytes - 2;
900  return bytes;
901 }
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ADSI_INPUT_CONTROL
Definition: adsi.h:45
static int adsi_input_format ( unsigned char *  buf,
int  num,
int  dir,
int  wrap,
char *  format1,
char *  format2 
)
static

Definition at line 903 of file res_adsi.c.

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

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

Definition at line 1100 of file res_adsi.c.

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

Referenced by load_module(), and reload().

1101 {
1102  int x = 0;
1103  struct ast_config *conf = NULL;
1104  struct ast_variable *v;
1105  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1106  char *name, *sname;
1107  init_state();
1108 
1109  conf = ast_config_load("adsi.conf", config_flags);
1111  return;
1112  }
1113  for (v = ast_variable_browse(conf, "intro"); v; v = v->next) {
1114  if (!strcasecmp(v->name, "alignment")) {
1115  alignment = str2align(v->value);
1116  } else if (!strcasecmp(v->name, "greeting")) {
1117  if (x < ADSI_MAX_INTRO) {
1118  aligns[x] = alignment;
1119  ast_copy_string(intro[x], v->value, sizeof(intro[x]));
1120  x++;
1121  }
1122  } else if (!strcasecmp(v->name, "maxretries")) {
1123  if (atoi(v->value) > 0) {
1124  maxretries = atoi(v->value);
1125  }
1126  }
1127  }
1128  if (x) {
1129  total = x;
1130  }
1131 
1132  x = 0;
1133  for (v = ast_variable_browse(conf, "speeddial"); v; v = v->next) {
1134  char buf[3 * SPEEDDIAL_MAX_LEN];
1135  char *stringp = buf;
1136  ast_copy_string(buf, v->value, sizeof(buf));
1137  name = strsep(&stringp, ",");
1138  sname = strsep(&stringp, ",");
1139  if (!sname) {
1140  sname = name;
1141  }
1142  if (x < ADSI_MAX_SPEED_DIAL) {
1143  ast_copy_string(speeddial[x][0], v->name, sizeof(speeddial[x][0]));
1144  ast_copy_string(speeddial[x][1], name, 18);
1145  ast_copy_string(speeddial[x][2], sname, 7);
1146  x++;
1147  }
1148  }
1149  if (x) {
1150  speeds = x;
1151  }
1152  ast_config_destroy(conf);
1153 
1154  return;
1155 }
char * strsep(char **str, const char *delims)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
static char intro[ADSI_MAX_INTRO][20]
Definition: res_adsi.c:66
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static int aligns[ADSI_MAX_INTRO]
Definition: res_adsi.c:67
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
const char * value
Definition: config.h:79
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int speeds
Definition: res_adsi.c:968
static int alignment
Definition: res_adsi.c:72
const char * name
Definition: config.h:77
static int str2align(const char *s)
Definition: res_adsi.c:1068
static int reload(void)
Definition: res_adsi.c:1157
#define ADSI_MAX_SPEED_DIAL
Definition: res_adsi.c:57
static int maxretries
Definition: res_adsi.c:61
static const char name[]
Structure used to handle boolean flags.
Definition: utils.h:200
static char speeddial[ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN]
Definition: res_adsi.c:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int total
Definition: res_adsi.c:967
#define ADSI_MAX_INTRO
Definition: res_adsi.c:56
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define SPEEDDIAL_MAX_LEN
Definition: res_adsi.c:69
static void init_state(void)
Definition: res_adsi.c:1081
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int adsi_load_session ( struct ast_channel chan,
unsigned char *  app,
int  ver,
int  data 
)
static

Definition at line 1012 of file res_adsi.c.

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

1013 {
1014  unsigned char dsp[256] = "";
1015  int bytes = 0, res;
1016  char resp[2];
1017 
1018  /* Connect to session */
1019  bytes += adsi_connect_session(dsp + bytes, app, ver);
1020 
1021  if (data) {
1022  bytes += adsi_data_mode(dsp + bytes);
1023  }
1024 
1025  /* Prepare key setup messages */
1026  if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1027  return -1;
1028  }
1029  if (app) {
1030  if ((res = ast_readstring(chan, resp, 1, 1200, 1200, "")) < 0) {
1031  return -1;
1032  }
1033  if (res) {
1034  ast_debug(1, "No response from CPE about version. Assuming not there.\n");
1035  return 0;
1036  }
1037  if (!strcmp(resp, "B")) {
1038  ast_debug(1, "CPE has script '%s' version %d already loaded\n", app, ver);
1039  return 1;
1040  } else if (!strcmp(resp, "A")) {
1041  ast_debug(1, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
1042  } else {
1043  ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
1044  }
1045  } else
1046  return 1;
1047  return 0;
1048 
1049 }
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define LOG_WARNING
Definition: logger.h:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static const char app[]
Definition: app_adsiprog.c:49
static int adsi_connect_session(unsigned char *buf, unsigned char *fdn, int ver)
Definition: res_adsi.c:520
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:746
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:5837
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 479 of file res_adsi.c.

References ADSI_LOAD_SOFTKEY, ADSI_SWITCH_TO_DATA2, and ccopy().

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

Definition at line 992 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().

993 {
994  unsigned char buf[4096];
995  int bytes = 0, res, x;
996 
997  for (x = 0; lines[x]; x++) {
998  bytes += adsi_display(buf + bytes, ADSI_INFO_PAGE, x+1, alignments[x], 0, lines[x], "");
999  }
1000  bytes += adsi_set_line(buf + bytes, ADSI_INFO_PAGE, 1);
1001  if (voice) {
1002  bytes += adsi_voice_mode(buf + bytes, 0);
1003  }
1004  res = adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
1005  if (voice) {
1006  /* Ignore the resulting DTMF B announcing it's in voice mode */
1007  ast_waitfordigit(chan, 1000);
1008  }
1009  return res;
1010 }
#define ADSI_INFO_PAGE
Definition: adsi.h:106
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static int adsi_display(unsigned char *buf, int page, int line, int just, int wrap, char *col1, char *col2)
Definition: res_adsi.c:833
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:791
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
static int adsi_set_line(unsigned char *buf, int page, int line)
Definition: res_adsi.c:939
static int adsi_query_cpeid ( unsigned char *  buf)
static

Definition at line 591 of file res_adsi.c.

References ADSI_QUERY_CPEID.

Referenced by adsi_get_cpeid().

592 {
593  int bytes = 0;
594  buf[bytes++] = ADSI_QUERY_CPEID;
595  /* Reserve space for length */
596  bytes++;
597  buf[1] = bytes - 2;
598  return bytes;
599 }
#define ADSI_QUERY_CPEID
Definition: adsi.h:58
static int adsi_query_cpeinfo ( unsigned char *  buf)
static

Definition at line 601 of file res_adsi.c.

References ADSI_QUERY_CONFIG.

Referenced by adsi_get_cpeinfo().

602 {
603  int bytes = 0;
604  buf[bytes++] = ADSI_QUERY_CONFIG;
605  /* Reserve space for length */
606  bytes++;
607  buf[1] = bytes - 2;
608  return bytes;
609 }
#define ADSI_QUERY_CONFIG
Definition: adsi.h:57
static int adsi_read_encoded_dtmf ( struct ast_channel chan,
unsigned char *  buf,
int  maxlen 
)
static

Definition at line 611 of file res_adsi.c.

References ast_waitfordigit().

Referenced by adsi_get_cpeid().

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

Definition at line 923 of file res_adsi.c.

References ADSI_INIT_SOFTKEY_LINE.

Referenced by adsi_channel_restore().

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

Definition at line 939 of file res_adsi.c.

References ADSI_LINE_CONTROL.

Referenced by adsi_channel_restore(), and adsi_print().

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

Definition at line 463 of file res_adsi.c.

References adsi_transmit_message_full().

464 {
465  return adsi_transmit_message_full(chan, msg, msglen, msgtype, 1);
466 }
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static int adsi_transmit_message_full ( struct ast_channel chan,
unsigned char *  msg,
int  msglen,
int  msgtype,
int  dowait 
)
static

Definition at line 392 of file res_adsi.c.

References __adsi_transmit_messages(), ADSI_FLAG_DATAMODE, ADSI_SWITCH_TO_DATA, ADSI_SWITCH_TO_VOICE, ast_channel::adsicpe, ast_debug, AST_FORMAT_ULAW, ast_log(), ast_safe_sleep(), ast_set_read_format(), ast_set_write_format(), ast_stopstream(), ast_waitfordigit(), for(), 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().

393 {
394  unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
395  int msglens[5], msgtypes[5], newdatamode = (chan->adsicpe & ADSI_FLAG_DATAMODE), res, x, writeformat = chan->writeformat, readformat = chan->readformat, waitforswitch = 0;
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 
423  ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
424  return -1;
425  }
426 
428  ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
429  if (writeformat) {
430  if (ast_set_write_format(chan, writeformat)) {
431  ast_log(LOG_WARNING, "Unable to restore write format to %d\n", writeformat);
432  }
433  }
434  return -1;
435  }
436  res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
437 
438  if (dowait) {
439  ast_debug(1, "Wait for switch is '%d'\n", waitforswitch);
440  while (waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) {
441  res = 0;
442  ast_debug(1, "Waiting for 'B'...\n");
443  }
444  }
445 
446  if (!res) {
447  chan->adsicpe = (chan->adsicpe & ~ADSI_FLAG_DATAMODE) | newdatamode;
448  }
449 
450  if (writeformat) {
451  ast_set_write_format(chan, writeformat);
452  }
453  if (readformat) {
454  ast_set_read_format(chan, readformat);
455  }
456 
457  if (!res) {
458  res = ast_safe_sleep(chan, 100 );
459  }
460  return res;
461 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1916
format_t writeformat
Definition: channel.h:854
static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
Definition: res_adsi.c:233
#define LOG_WARNING
Definition: logger.h:144
for(;;)
Definition: ast_expr2.c:2460
#define ADSI_FLAG_DATAMODE
Definition: res_adsi.c:59
enum ast_channel_adsicpe adsicpe
Definition: channel.h:844
int ast_set_write_format(struct ast_channel *chan, format_t format)
Sets write format on channel chan Set write format for channel to whichever component of &quot;format&quot; is ...
Definition: channel.c:5307
int ast_set_read_format(struct ast_channel *chan, format_t format)
Sets read format on channel chan Set read format for channel to whichever component of &quot;format&quot; is be...
Definition: channel.c:5301
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_FORMAT_ULAW
Definition: frame.h:246
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ADSI_SWITCH_TO_VOICE
Definition: adsi.h:43
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3552
format_t readformat
Definition: channel.h:853
#define ADSI_SWITCH_TO_DATA
Definition: adsi.h:42
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:128
static int adsi_unload_session ( struct ast_channel chan)
static

Definition at line 1051 of file res_adsi.c.

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

1052 {
1053  unsigned char dsp[256] = "";
1054  int bytes = 0;
1055 
1056  /* Connect to session */
1057  bytes += adsi_disconnect_session(dsp + bytes);
1058  bytes += adsi_voice_mode(dsp + bytes, 0);
1059 
1060  /* Prepare key setup messages */
1061  if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1062  return -1;
1063  }
1064 
1065  return 0;
1066 }
static int adsi_disconnect_session(unsigned char *buf)
Definition: res_adsi.c:576
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:392
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:791
static int adsi_voice_mode ( unsigned char *  buf,
int  when 
)
static

Definition at line 791 of file res_adsi.c.

References ADSI_SWITCH_TO_VOICE.

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

792 {
793  int bytes = 0;
794 
795  /* Message type */
796  buf[bytes++] = ADSI_SWITCH_TO_VOICE;
797 
798  /* Reserve space for length */
799  bytes++;
800 
801  buf[bytes++] = when & 0x7f;
802 
803  buf[1] = bytes - 2;
804  return bytes;
805 
806 }
#define ADSI_SWITCH_TO_VOICE
Definition: adsi.h:43
static int ccopy ( unsigned char *  dst,
const unsigned char *  src,
int  max 
)
inlinestatic

Definition at line 468 of file res_adsi.c.

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

469 {
470  int x = 0;
471  /* Carefully copy the requested data */
472  while ((x < max) && src[x] && (src[x] != 0xff)) {
473  dst[x] = src[x];
474  x++;
475  }
476  return x;
477 }
static void init_state ( void  )
static

Definition at line 1081 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_MAX_INTRO, and ast_copy_string().

Referenced by adsi_load().

1082 {
1083  int x;
1084 
1085  for (x = 0; x < ADSI_MAX_INTRO; x++) {
1086  aligns[x] = ADSI_JUST_CENT;
1087  }
1088  ast_copy_string(intro[0], "Welcome to the", sizeof(intro[0]));
1089  ast_copy_string(intro[1], "Asterisk", sizeof(intro[1]));
1090  ast_copy_string(intro[2], "Open Source PBX", sizeof(intro[2]));
1091  total = 3;
1092  speeds = 0;
1093  for (x = 3; x < ADSI_MAX_INTRO; x++) {
1094  intro[x][0] = '\0';
1095  }
1096  memset(speeddial, 0, sizeof(speeddial));
1098 }
static char intro[ADSI_MAX_INTRO][20]
Definition: res_adsi.c:66
static int aligns[ADSI_MAX_INTRO]
Definition: res_adsi.c:67
static int speeds
Definition: res_adsi.c:968
static int alignment
Definition: res_adsi.c:72
static char speeddial[ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN]
Definition: res_adsi.c:70
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int total
Definition: res_adsi.c:967
#define ADSI_MAX_INTRO
Definition: res_adsi.c:56
#define ADSI_JUST_CENT
Definition: adsi.h:114
static int load_module ( void  )
static

Definition at line 1195 of file res_adsi.c.

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

1196 {
1197  adsi_load(0);
1199  return AST_MODULE_LOAD_SUCCESS;
1200 }
static void adsi_load(int reload)
Definition: res_adsi.c:1100
static struct adsi_funcs res_adsi_funcs
Definition: res_adsi.c:1163
void ast_adsi_install_funcs(const struct adsi_funcs *funcs)
Definition: adsi.c:340
static int reload ( void  )
static

Definition at line 1157 of file res_adsi.c.

References adsi_load().

1158 {
1159  adsi_load(1);
1160  return 0;
1161 }
static void adsi_load(int reload)
Definition: res_adsi.c:1100
static int str2align ( const char *  s)
static

Definition at line 1068 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_JUST_IND, ADSI_JUST_LEFT, and ADSI_JUST_RIGHT.

Referenced by adsi_load().

1069 {
1070  if (!strncasecmp(s, "l", 1)) {
1071  return ADSI_JUST_LEFT;
1072  } else if (!strncasecmp(s, "r", 1)) {
1073  return ADSI_JUST_RIGHT;
1074  } else if (!strncasecmp(s, "i", 1)) {
1075  return ADSI_JUST_IND;
1076  } else {
1077  return ADSI_JUST_CENT;
1078  }
1079 }
#define ADSI_JUST_RIGHT
Definition: adsi.h:113
#define ADSI_JUST_LEFT
Definition: adsi.h:112
#define ADSI_JUST_IND
Definition: adsi.h:115
#define ADSI_JUST_CENT
Definition: adsi.h:114
static int unload_module ( void  )
static

Definition at line 1202 of file res_adsi.c.

References ast_adsi_install_funcs().

1203 {
1204  /* Can't unload this once we're loaded */
1205  ast_adsi_install_funcs(NULL);
1206  return -1;
1207 }
void ast_adsi_install_funcs(const struct adsi_funcs *funcs)
Definition: adsi.c:340

Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_APP_DEPEND, }
static

Definition at line 1214 of file res_adsi.c.

int alignment = 0
static

Definition at line 72 of file res_adsi.c.

Referenced by adsi_load().

int aligns[ADSI_MAX_INTRO]
static

Definition at line 67 of file res_adsi.c.

Definition at line 1214 of file res_adsi.c.

char intro[ADSI_MAX_INTRO][20]
static

Definition at line 66 of file res_adsi.c.

int maxretries = DEFAULT_ADSI_MAX_RETRIES
static

Definition at line 61 of file res_adsi.c.

Referenced by ast_ivr_menu_run_internal(), and privacy_exec().

struct adsi_funcs res_adsi_funcs
static

Definition at line 1163 of file res_adsi.c.

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

Definition at line 70 of file res_adsi.c.

int speeds = 0
static

Definition at line 968 of file res_adsi.c.

Referenced by adsi_channel_restore().