Asterisk - The Open Source Telephony Project  18.5.0
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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .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.

Referenced by __adsi_transmit_messages(), and adsi_transmit_message_full().

◆ ADSI_MAX_INTRO

#define ADSI_MAX_INTRO   20

Definition at line 55 of file res_adsi.c.

Referenced by adsi_load(), and init_state().

◆ ADSI_MAX_SPEED_DIAL

#define ADSI_MAX_SPEED_DIAL   6

Definition at line 56 of file res_adsi.c.

Referenced by adsi_load().

◆ ADSI_SPEED_DIAL

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

Definition at line 63 of file res_adsi.c.

Referenced by adsi_channel_restore().

◆ 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.

Referenced by adsi_load().

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

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_waitfor(), buf, errno, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, maxretries, NULL, and ast_frame::subclass.

Referenced by adsi_transmit_message_full().

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

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1216 of file res_adsi.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1216 of file res_adsi.c.

◆ adsi_available()

static int adsi_available ( struct ast_channel chan)
static

Definition at line 809 of file res_adsi.c.

References AST_ADSI_AVAILABLE, and AST_ADSI_UNKNOWN.

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

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

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

353 {
354  int bytes = 0;
355  unsigned char buf[256];
356  char ack[2];
357 
358  /* Setup the resident soft key stuff, a piece at a time */
359  /* Upload what scripts we can for voicemail ahead of time */
360  bytes += adsi_download_connect(buf + bytes, service, fdn, sec, version);
361  if (adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DOWNLOAD, 0)) {
362  return -1;
363  }
364  if (ast_readstring(chan, ack, 1, 10000, 10000, "")) {
365  return -1;
366  }
367  if (ack[0] == 'B') {
368  return 0;
369  }
370  ast_debug(1, "Download was denied by CPE\n");
371  return -1;
372 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
enum ast_cc_service_type service
Definition: chan_sip.c:949
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:388
static char version[AST_MAX_EXTENSION]
Definition: chan_ooh323.c:391
#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:6655
static int adsi_download_connect(unsigned char *buf, char *service, unsigned char *fdn, unsigned char *sec, int ver)
Definition: res_adsi.c:545

◆ 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.

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::datalen, ast_frame_subclass::format, ast_frame::frametype, len(), LOG_WARNING, ast_frame::samples, and ast_frame::subclass.

Referenced by __adsi_transmit_messages().

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  .data.ptr = buf,
161  };
162  int amt;
163 
164  if (remain && *remain) {
165  amt = len;
166 
167  /* Send remainder if provided */
168  if (amt > *remain) {
169  amt = *remain;
170  } else {
171  *remain = *remain - amt;
172  }
173 
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.datalen = amt;
215  outf.samples = amt;
216  if (ast_write(chan, &outf)) {
217  ast_log(LOG_WARNING, "Failed to carefully write frame\n");
218  ast_frfree(inf);
219  return -1;
220  }
221  /* Update pointers and lengths */
222  buf += amt;
223  len -= amt;
224  ast_frfree(inf);
225  }
226  return 0;
227 }
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 LOG_WARNING
Definition: logger.h:274
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4302
struct ast_frame_subclass subclass
#define ast_log
Definition: astobj2.c:42
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
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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:5189
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3171
#define ast_frfree(fr)
Data structure associated with a single frame of data.
enum ast_frame_type frametype
struct ast_format * format

◆ adsi_channel_restore()

static int adsi_channel_restore ( struct ast_channel chan)
static

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

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

◆ adsi_clear_screen()

static int adsi_clear_screen ( unsigned char *  buf)
static

Definition at line 777 of file res_adsi.c.

References ADSI_CLEAR_SCREEN.

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

◆ adsi_clear_soft_keys()

static int adsi_clear_soft_keys ( unsigned char *  buf)
static

Definition at line 762 of file res_adsi.c.

References ADSI_CLEAR_SOFTKEY.

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

◆ adsi_connect_session()

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

Definition at line 521 of file res_adsi.c.

References ADSI_CONNECT_SESSION.

Referenced by adsi_load_session().

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

◆ adsi_data_mode()

static int adsi_data_mode ( unsigned char *  buf)
static

Definition at line 747 of file res_adsi.c.

References ADSI_SWITCH_TO_DATA.

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

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

◆ adsi_disconnect_session()

static int adsi_disconnect_session ( unsigned char *  buf)
static

Definition at line 577 of file res_adsi.c.

References ADSI_DISC_SESSION.

Referenced by adsi_unload_session().

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

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

References ADSI_LOAD_VIRTUAL_DISP, and ccopy().

Referenced by adsi_print().

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

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

References ADSI_DOWNLOAD_CONNECT, and ccopy().

Referenced by adsi_begin_download().

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

◆ adsi_download_disconnect()

static int adsi_download_disconnect ( unsigned char *  buf)
static

Definition at line 819 of file res_adsi.c.

References ADSI_DOWNLOAD_DISC.

Referenced by adsi_end_download().

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

◆ adsi_end_download()

static int adsi_end_download ( struct ast_channel chan)
static

Definition at line 374 of file res_adsi.c.

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

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

◆ 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.

References PUT_CLID, and PUT_CLID_MARKMS.

Referenced by __adsi_transmit_messages().

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_meetme.c:1092
#define PUT_CLID(byte)
Definition: callerid.h:304
#define PUT_CLID_MARKMS
Definition: callerid.h:289

◆ adsi_get_cpeid()

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

Definition at line 649 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(), buf, and LOG_WARNING.

650 {
651  unsigned char buf[256] = "";
652  int bytes = 0, res;
653 
654  bytes += adsi_data_mode(buf);
655  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
656 
657  bytes = 0;
658  bytes += adsi_query_cpeid(buf);
659  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
660 
661  /* Get response */
662  res = adsi_read_encoded_dtmf(chan, cpeid, 4);
663  if (res != 4) {
664  ast_log(LOG_WARNING, "Got %d bytes back of encoded DTMF, expecting 4\n", res);
665  res = 0;
666  } else {
667  res = 1;
668  }
669 
670  if (voice) {
671  bytes = 0;
672  bytes += adsi_voice_mode(buf, 0);
673  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
674  /* Ignore the resulting DTMF B announcing it's in voice mode */
675  ast_waitfordigit(chan, 1000);
676  }
677  return res;
678 }
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:388
static int adsi_read_encoded_dtmf(struct ast_channel *chan, unsigned char *buf, int maxlen)
Definition: res_adsi.c:612
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:747
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:792
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
static int adsi_query_cpeid(unsigned char *buf)
Definition: res_adsi.c:592

◆ adsi_get_cpeinfo()

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

Definition at line 680 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(), buf, and LOG_WARNING.

681 {
682  unsigned char buf[256] = "";
683  int bytes = 0, res;
684 
685  bytes += adsi_data_mode(buf);
686  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
687 
688  bytes = 0;
689  bytes += adsi_query_cpeinfo(buf);
690  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
691 
692  /* Get width */
693  if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
694  return res;
695  }
696  if (strlen((char *) buf) != 2) {
697  ast_log(LOG_WARNING, "Got %d bytes of width, expecting 2\n", res);
698  res = 0;
699  } else {
700  res = 1;
701  }
702  if (width) {
703  *width = atoi((char *) buf);
704  }
705  /* Get height */
706  memset(buf, 0, sizeof(buf));
707  if (res) {
708  if ((res = ast_readstring(chan, (char *) buf, 2, 1000, 500, "")) < 0) {
709  return res;
710  }
711  if (strlen((char *) buf) != 2) {
712  ast_log(LOG_WARNING, "Got %d bytes of height, expecting 2\n", res);
713  res = 0;
714  } else {
715  res = 1;
716  }
717  if (height) {
718  *height = atoi((char *) buf);
719  }
720  }
721  /* Get buttons */
722  memset(buf, 0, sizeof(buf));
723  if (res) {
724  if ((res = ast_readstring(chan, (char *) buf, 1, 1000, 500, "")) < 0) {
725  return res;
726  }
727  if (strlen((char *) buf) != 1) {
728  ast_log(LOG_WARNING, "Got %d bytes of buttons, expecting 1\n", res);
729  res = 0;
730  } else {
731  res = 1;
732  }
733  if (buttons) {
734  *buttons = atoi((char *) buf);
735  }
736  }
737  if (voice) {
738  bytes = 0;
739  bytes += adsi_voice_mode(buf, 0);
740  adsi_transmit_message_full(chan, buf, bytes, ADSI_MSG_DISPLAY, 0);
741  /* Ignore the resulting DTMF B announcing it's in voice mode */
742  ast_waitfordigit(chan, 1000);
743  }
744  return res;
745 }
static int adsi_query_cpeinfo(unsigned char *buf)
Definition: res_adsi.c:602
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:388
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:747
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:792
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
Definition: channel.c:3184
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6655

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

References ADSI_INPUT_CONTROL.

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

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

References ADSI_INPUT_FORMAT, ast_strlen_zero, and ccopy().

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

◆ adsi_load()

static void adsi_load ( int  reload)
static

Definition at line 1101 of file res_adsi.c.

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, speeddial, SPEEDDIAL_MAX_LEN, speeds, str2align(), strsep(), total, and ast_variable::value.

Referenced by load_module(), and reload().

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

◆ adsi_load_session()

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

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

1014 {
1015  unsigned char dsp[256] = "";
1016  int bytes = 0, res;
1017  char resp[2];
1018 
1019  /* Connect to session */
1020  bytes += adsi_connect_session(dsp + bytes, app, ver);
1021 
1022  if (data) {
1023  bytes += adsi_data_mode(dsp + bytes);
1024  }
1025 
1026  /* Prepare key setup messages */
1027  if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1028  return -1;
1029  }
1030  if (app) {
1031  if ((res = ast_readstring(chan, resp, 1, 1200, 1200, "")) < 0) {
1032  return -1;
1033  }
1034  if (res) {
1035  ast_debug(1, "No response from CPE about version. Assuming not there.\n");
1036  return 0;
1037  }
1038  if (!strcmp(resp, "B")) {
1039  ast_debug(1, "CPE has script '%s' version %d already loaded\n", app, ver);
1040  return 1;
1041  } else if (!strcmp(resp, "A")) {
1042  ast_debug(1, "CPE hasn't script '%s' version %d already loaded\n", app, ver);
1043  } else {
1044  ast_log(LOG_WARNING, "Unexpected CPE response to script query: %s\n", resp);
1045  }
1046  } else
1047  return 1;
1048  return 0;
1049 
1050 }
#define ADSI_MSG_DISPLAY
Definition: adsi.h:32
#define LOG_WARNING
Definition: logger.h:274
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static int adsi_transmit_message_full(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
Definition: res_adsi.c:388
static int adsi_connect_session(unsigned char *buf, unsigned char *fdn, int ver)
Definition: res_adsi.c:521
static int adsi_data_mode(unsigned char *buf)
Definition: res_adsi.c:747
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
Reads multiple digits.
Definition: channel.c:6655
static const char app[]
Definition: app_mysql.c:62

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

References ADSI_LOAD_SOFTKEY, ADSI_SWITCH_TO_DATA2, and ccopy().

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

◆ adsi_print()

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

Definition at line 993 of file res_adsi.c.

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

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

◆ adsi_query_cpeid()

static int adsi_query_cpeid ( unsigned char *  buf)
static

Definition at line 592 of file res_adsi.c.

References ADSI_QUERY_CPEID.

Referenced by adsi_get_cpeid().

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

◆ adsi_query_cpeinfo()

static int adsi_query_cpeinfo ( unsigned char *  buf)
static

Definition at line 602 of file res_adsi.c.

References ADSI_QUERY_CONFIG.

Referenced by adsi_get_cpeinfo().

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

◆ adsi_read_encoded_dtmf()

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

Definition at line 612 of file res_adsi.c.

References ast_waitfordigit().

Referenced by adsi_get_cpeid().

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

◆ adsi_set_keys()

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

Definition at line 924 of file res_adsi.c.

References ADSI_INIT_SOFTKEY_LINE.

Referenced by adsi_channel_restore().

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

◆ adsi_set_line()

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

Definition at line 940 of file res_adsi.c.

References ADSI_LINE_CONTROL.

Referenced by adsi_channel_restore(), and adsi_print().

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

◆ adsi_transmit_message()

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

Definition at line 464 of file res_adsi.c.

References adsi_transmit_message_full().

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

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

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

389 {
390  unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
391  int msglens[5], msgtypes[5], newdatamode = (ast_channel_adsicpe(chan) & ADSI_FLAG_DATAMODE), res, x, waitforswitch = 0;
392  RAII_VAR(struct ast_format *, writeformat, NULL, ao2_cleanup);
393  RAII_VAR(struct ast_format *, readformat, NULL, ao2_cleanup);
394 
395  for (x = 0; x < msglen; x += (msg[x+1]+2)) {
396  if (msg[x] == ADSI_SWITCH_TO_DATA) {
397  ast_debug(1, "Switch to data is sent!\n");
398  waitforswitch++;
399  newdatamode = ADSI_FLAG_DATAMODE;
400  }
401 
402  if (msg[x] == ADSI_SWITCH_TO_VOICE) {
403  ast_debug(1, "Switch to voice is sent!\n");
404  waitforswitch++;
405  newdatamode = 0;
406  }
407  }
408  msgs[0] = msg;
409 
410  msglens[0] = msglen;
411  msgtypes[0] = msgtype;
412 
413  if (msglen > 253) {
414  ast_log(LOG_WARNING, "Can't send ADSI message of %d bytes, too large\n", msglen);
415  return -1;
416  }
417 
418  ast_stopstream(chan);
419 
420  writeformat = ao2_bump(ast_channel_writeformat(chan));
421  readformat = ao2_bump(ast_channel_readformat(chan));
422 
424  ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
425  return -1;
426  }
427 
429  ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
430  if (writeformat) {
431  if (ast_set_write_format(chan, writeformat)) {
432  ast_log(LOG_WARNING, "Unable to restore write format to %s\n", ast_format_get_name(writeformat));
433  }
434  }
435  return -1;
436  }
437  res = __adsi_transmit_messages(chan, msgs, msglens, msgtypes);
438 
439  if (dowait) {
440  ast_debug(1, "Wait for switch is '%d'\n", waitforswitch);
441  while (waitforswitch-- && ((res = ast_waitfordigit(chan, 1000)) > 0)) {
442  res = 0;
443  ast_debug(1, "Waiting for 'B'...\n");
444  }
445  }
446 
447  if (!res) {
448  ast_channel_adsicpe_set(chan, (ast_channel_adsicpe(chan) & ~ADSI_FLAG_DATAMODE) | newdatamode);
449  }
450 
451  if (writeformat) {
452  ast_set_write_format(chan, writeformat);
453  }
454  if (readformat) {
455  ast_set_read_format(chan, readformat);
456  }
457 
458  if (!res) {
459  res = ast_safe_sleep(chan, 100 );
460  }
461  return res;
462 }
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **msg, int *msglen, int *msgtype)
Definition: res_adsi.c:229
struct ast_format * ast_format_ulaw
Built-in cached ulaw format.
Definition: format_cache.c:86
#define LOG_WARNING
Definition: logger.h:274
Definition of a media format.
Definition: format.c:43
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
#define NULL
Definition: resample.c:96
#define ADSI_FLAG_DATAMODE
Definition: res_adsi.c:58
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
#define ao2_bump(obj)
Definition: astobj2.h:491
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
Definition: channel.c:5849
#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:911
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition: channel.c:5890
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
ast_channel_adsicpe
Definition: channel.h:869
#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:3184
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ADSI_SWITCH_TO_DATA
Definition: adsi.h:42
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
int ast_stopstream(struct ast_channel *c)
Stops a stream.
Definition: file.c:187

◆ adsi_unload_session()

static int adsi_unload_session ( struct ast_channel chan)
static

Definition at line 1052 of file res_adsi.c.

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

1053 {
1054  unsigned char dsp[256] = "";
1055  int bytes = 0;
1056 
1057  /* Connect to session */
1058  bytes += adsi_disconnect_session(dsp + bytes);
1059  bytes += adsi_voice_mode(dsp + bytes, 0);
1060 
1061  /* Prepare key setup messages */
1062  if (adsi_transmit_message_full(chan, dsp, bytes, ADSI_MSG_DISPLAY, 0)) {
1063  return -1;
1064  }
1065 
1066  return 0;
1067 }
static int adsi_disconnect_session(unsigned char *buf)
Definition: res_adsi.c:577
#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:388
static int adsi_voice_mode(unsigned char *buf, int when)
Definition: res_adsi.c:792

◆ adsi_voice_mode()

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

Definition at line 792 of file res_adsi.c.

References ADSI_SWITCH_TO_VOICE.

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

793 {
794  int bytes = 0;
795 
796  /* Message type */
797  buf[bytes++] = ADSI_SWITCH_TO_VOICE;
798 
799  /* Reserve space for length */
800  bytes++;
801 
802  buf[bytes++] = when & 0x7f;
803 
804  buf[1] = bytes - 2;
805  return bytes;
806 
807 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ADSI_SWITCH_TO_VOICE
Definition: adsi.h:43

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1216 of file res_adsi.c.

◆ ccopy()

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

Definition at line 469 of file res_adsi.c.

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

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

◆ init_state()

static void init_state ( void  )
static

Definition at line 1082 of file res_adsi.c.

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

Referenced by adsi_load().

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

◆ load_module()

static int load_module ( void  )
static

Definition at line 1196 of file res_adsi.c.

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

Referenced by unload_module().

1197 {
1198  adsi_load(0);
1200  return AST_MODULE_LOAD_SUCCESS;
1201 }
static void adsi_load(int reload)
Definition: res_adsi.c:1101
static struct adsi_funcs res_adsi_funcs
Definition: res_adsi.c:1164
void ast_adsi_install_funcs(const struct adsi_funcs *funcs)
Definition: adsi.c:340

◆ reload()

static int reload ( void  )
static

Definition at line 1158 of file res_adsi.c.

References adsi_load().

Referenced by unload_module().

1159 {
1160  adsi_load(1);
1161  return 0;
1162 }
static void adsi_load(int reload)
Definition: res_adsi.c:1101

◆ str2align()

static int str2align ( const char *  s)
static

Definition at line 1069 of file res_adsi.c.

References ADSI_JUST_CENT, ADSI_JUST_IND, ADSI_JUST_LEFT, and ADSI_JUST_RIGHT.

Referenced by adsi_load().

1070 {
1071  if (!strncasecmp(s, "l", 1)) {
1072  return ADSI_JUST_LEFT;
1073  } else if (!strncasecmp(s, "r", 1)) {
1074  return ADSI_JUST_RIGHT;
1075  } else if (!strncasecmp(s, "i", 1)) {
1076  return ADSI_JUST_IND;
1077  } else {
1078  return ADSI_JUST_CENT;
1079  }
1080 }
#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

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1203 of file res_adsi.c.

References ast_adsi_install_funcs(), AST_MODFLAG_LOAD_ORDER, AST_MODPRI_APP_DEPEND, AST_MODULE_INFO(), AST_MODULE_SUPPORT_DEPRECATED, ASTERISK_GPL_KEY, load_module(), NULL, and reload().

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

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

Definition at line 1216 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 1216 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(), init_state(), and play_message().

◆ maxretries

int maxretries = DEFAULT_ADSI_MAX_RETRIES
static

◆ res_adsi_funcs

struct adsi_funcs res_adsi_funcs
static

Definition at line 1164 of file res_adsi.c.

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

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

◆ total

int total = 0
static