Wed Jan 8 2020 09:49:53

Asterisk developer's documentation


app_dahdibarge.c File Reference

DAHDI Barge support. More...

#include "asterisk.h"
#include <dahdi/user.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/config.h"
#include "asterisk/app.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/utils.h"

Go to the source code of this file.

Macros

#define CONF_SIZE   160
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int careful_write (int fd, unsigned char *data, int len)
 
static int conf_exec (struct ast_channel *chan, const char *data)
 
static int conf_run (struct ast_channel *chan, int confno, int confflags)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Barge in on DAHDI channel application" , .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, .load_pri = AST_MODPRI_DEFAULT, }
 
static const char app [] = "DAHDIBarge"
 
static struct ast_module_infoast_module_info = &__mod_info
 

Detailed Description

DAHDI Barge support.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
Special thanks to comphealth.com for sponsoring this GPL application.

Definition in file app_dahdibarge.c.

Macro Definition Documentation

#define CONF_SIZE   160

Definition at line 77 of file app_dahdibarge.c.

Referenced by conf_run().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 310 of file app_dahdibarge.c.

static void __unreg_module ( void  )
static

Definition at line 310 of file app_dahdibarge.c.

static int careful_write ( int  fd,
unsigned char *  data,
int  len 
)
static

Definition at line 79 of file app_dahdibarge.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by conf_run().

80 {
81  int res;
82  while(len) {
83  res = write(fd, data, len);
84  if (res < 1) {
85  if (errno != EAGAIN) {
86  ast_log(LOG_WARNING, "Failed to write audio data to conference: %s\n", strerror(errno));
87  return -1;
88  } else
89  return 0;
90  }
91  len -= res;
92  data += res;
93  }
94  return 0;
95 }
#define LOG_WARNING
Definition: logger.h:144
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 errno
static int conf_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 263 of file app_dahdibarge.c.

References ast_channel::_state, ast_answer(), ast_app_getdata(), ast_log(), AST_STATE_UP, ast_strlen_zero(), conf_run(), and LOG_WARNING.

Referenced by load_module().

264 {
265  int res = -1;
266  int retrycnt = 0;
267  int confflags = 0;
268  int confno = 0;
269  char confnostr[80] = "";
270 
271  if (!ast_strlen_zero(data)) {
272  if ((sscanf(data, "DAHDI/%30d", &confno) != 1) &&
273  (sscanf(data, "%30d", &confno) != 1)) {
274  ast_log(LOG_WARNING, "DAHDIBarge Argument (if specified) must be a channel number, not '%s'\n", (char *)data);
275  return 0;
276  }
277  }
278 
279  if (chan->_state != AST_STATE_UP)
280  ast_answer(chan);
281 
282  while(!confno && (++retrycnt < 4)) {
283  /* Prompt user for conference number */
284  confnostr[0] = '\0';
285  res = ast_app_getdata(chan, "conf-getchannel",confnostr, sizeof(confnostr) - 1, 0);
286  if (res <0) goto out;
287  if (sscanf(confnostr, "%30d", &confno) != 1)
288  confno = 0;
289  }
290  if (confno) {
291  /* XXX Should prompt user for pin if pin is required XXX */
292  /* Run the conference */
293  res = conf_run(chan, confno, confflags);
294  }
295 out:
296  /* Do the conference */
297  return res;
298 }
int ast_app_getdata(struct ast_channel *c, const char *prompt, char *s, int maxlen, int timeout)
Plays a stream and gets DTMF data from a channel.
Definition: app.c:178
#define LOG_WARNING
Definition: logger.h:144
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
enum ast_channel_state _state
Definition: channel.h:839
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 conf_run(struct ast_channel *chan, int confno, int confflags)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:3086
static int conf_run ( struct ast_channel chan,
int  confno,
int  confflags 
)
static

Definition at line 97 of file app_dahdibarge.c.

References ast_debug, AST_FORMAT_ULAW, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree, AST_FRIENDLY_OFFSET, ast_getformatname(), ast_indicate(), ast_log(), ast_read(), ast_set_read_format(), ast_set_write_format(), ast_waitfor_nandfds(), ast_write(), careful_write(), ast_frame_subclass::codec, CONF_SIZE, ast_frame::data, ast_frame::datalen, errno, f, ast_channel::fds, ast_frame::flags, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::subclass, ast_channel::tech, and ast_channel_tech::type.

Referenced by conf_exec().

98 {
99  int fd;
100  struct dahdi_confinfo dahdic;
101  struct ast_frame *f;
102  struct ast_channel *c;
103  struct ast_frame fr;
104  int outfd;
105  int ms;
106  int nfds;
107  int res;
108  int flags;
109  int retrydahdi;
110  int origfd;
111  int ret = -1;
112 
113  struct dahdi_bufferinfo bi;
114  char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
115  char *buf = __buf + AST_FRIENDLY_OFFSET;
116 
117  /* Set it into U-law mode (write) */
118  if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
119  ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
120  goto outrun;
121  }
122 
123  /* Set it into U-law mode (read) */
124  if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
125  ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
126  goto outrun;
127  }
128  ast_indicate(chan, -1);
129  retrydahdi = strcasecmp(chan->tech->type, "DAHDI");
130 dahdiretry:
131  origfd = chan->fds[0];
132  if (retrydahdi) {
133  fd = open("/dev/dahdi/pseudo", O_RDWR);
134  if (fd < 0) {
135  ast_log(LOG_WARNING, "Unable to open pseudo channel: %s\n", strerror(errno));
136  goto outrun;
137  }
138  /* Make non-blocking */
139  flags = fcntl(fd, F_GETFL);
140  if (flags < 0) {
141  ast_log(LOG_WARNING, "Unable to get flags: %s\n", strerror(errno));
142  close(fd);
143  goto outrun;
144  }
145  if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
146  ast_log(LOG_WARNING, "Unable to set flags: %s\n", strerror(errno));
147  close(fd);
148  goto outrun;
149  }
150  /* Setup buffering information */
151  memset(&bi, 0, sizeof(bi));
152  bi.bufsize = CONF_SIZE;
153  bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
154  bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
155  bi.numbufs = 4;
156  if (ioctl(fd, DAHDI_SET_BUFINFO, &bi)) {
157  ast_log(LOG_WARNING, "Unable to set buffering information: %s\n", strerror(errno));
158  close(fd);
159  goto outrun;
160  }
161  nfds = 1;
162  } else {
163  /* XXX Make sure we're not running on a pseudo channel XXX */
164  fd = chan->fds[0];
165  nfds = 0;
166  }
167  memset(&dahdic, 0, sizeof(dahdic));
168  /* Check to see if we're in a conference... */
169  dahdic.chan = 0;
170  if (ioctl(fd, DAHDI_GETCONF, &dahdic)) {
171  ast_log(LOG_WARNING, "Error getting conference\n");
172  close(fd);
173  goto outrun;
174  }
175  if (dahdic.confmode) {
176  /* Whoa, already in a conference... Retry... */
177  if (!retrydahdi) {
178  ast_debug(1, "DAHDI channel is in a conference already, retrying with pseudo\n");
179  retrydahdi = 1;
180  goto dahdiretry;
181  }
182  }
183  memset(&dahdic, 0, sizeof(dahdic));
184  /* Add us to the conference */
185  dahdic.chan = 0;
186  dahdic.confno = confno;
187  dahdic.confmode = DAHDI_CONF_MONITORBOTH;
188 
189  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
190  ast_log(LOG_WARNING, "Error setting conference\n");
191  close(fd);
192  goto outrun;
193  }
194  ast_debug(1, "Placed channel %s in DAHDI channel %d monitor\n", chan->name, confno);
195 
196  for(;;) {
197  outfd = -1;
198  ms = -1;
199  c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
200  if (c) {
201  if (c->fds[0] != origfd) {
202  if (retrydahdi) {
203  /* Kill old pseudo */
204  close(fd);
205  }
206  ast_debug(1, "Ooh, something swapped out under us, starting over\n");
207  retrydahdi = 0;
208  goto dahdiretry;
209  }
210  f = ast_read(c);
211  if (!f)
212  break;
213  if ((f->frametype == AST_FRAME_DTMF) && (f->subclass.integer == '#')) {
214  ret = 0;
215  ast_frfree(f);
216  break;
217  } else if (fd != chan->fds[0]) {
218  if (f->frametype == AST_FRAME_VOICE) {
219  if (f->subclass.codec == AST_FORMAT_ULAW) {
220  /* Carefully write */
221  careful_write(fd, f->data.ptr, f->datalen);
222  } else
223  ast_log(LOG_WARNING, "Huh? Got a non-ulaw (%s) frame in the conference\n", ast_getformatname(f->subclass.codec));
224  }
225  }
226  ast_frfree(f);
227  } else if (outfd > -1) {
228  res = read(outfd, buf, CONF_SIZE);
229  if (res > 0) {
230  memset(&fr, 0, sizeof(fr));
231  fr.frametype = AST_FRAME_VOICE;
232  fr.subclass.codec = AST_FORMAT_ULAW;
233  fr.datalen = res;
234  fr.samples = res;
235  fr.data.ptr = buf;
236  fr.offset = AST_FRIENDLY_OFFSET;
237  if (ast_write(chan, &fr) < 0) {
238  ast_log(LOG_WARNING, "Unable to write frame to channel: %s\n", strerror(errno));
239  /* break; */
240  }
241  } else
242  ast_log(LOG_WARNING, "Failed to read frame: %s\n", strerror(errno));
243  }
244  }
245  if (fd != chan->fds[0])
246  close(fd);
247  else {
248  /* Take out of conference */
249  /* Add us to the conference */
250  dahdic.chan = 0;
251  dahdic.confno = 0;
252  dahdic.confmode = 0;
253  if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
254  ast_log(LOG_WARNING, "Error setting conference\n");
255  }
256  }
257 
258 outrun:
259 
260  return ret;
261 }
union ast_frame_subclass subclass
Definition: frame.h:146
Main Channel structure associated with a channel.
Definition: channel.h:742
const char *const type
Definition: channel.h:508
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4393
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
#define AST_FRAME_DTMF
Definition: frame.h:128
#define CONF_SIZE
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
format_t codec
Definition: frame.h:137
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition: channel.c:3188
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_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
int datalen
Definition: frame.h:148
int fds[AST_MAX_FDS]
Definition: channel.h:829
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
#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
unsigned int flags
Definition: frame.h:166
static struct ast_format f[]
Definition: format_g726.c:181
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
static int careful_write(int fd, unsigned char *data, int len)
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
struct ast_channel_tech * tech
Definition: channel.h:743
static int load_module ( void  )
static

Definition at line 305 of file app_dahdibarge.c.

References AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, and conf_exec().

306 {
308 }
static const char app[]
static int conf_exec(struct ast_channel *chan, const char *data)
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int unload_module ( void  )
static

Definition at line 300 of file app_dahdibarge.c.

References ast_unregister_application().

301 {
303 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char app[]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Barge in on DAHDI channel application" , .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, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 310 of file app_dahdibarge.c.

const char app[] = "DAHDIBarge"
static

Definition at line 75 of file app_dahdibarge.c.

Definition at line 310 of file app_dahdibarge.c.