Wed Jan 8 2020 09:49:43

Asterisk developer's documentation


chan_h323.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005
5  *
6  * OpenH323 Channel Driver for ASTERISK PBX.
7  * By Jeremy McNamara
8  * For The NuFone Network
9  *
10  * chan_h323 has been derived from code created by
11  * Michael Manousos and Mark Spencer
12  *
13  * See http://www.asterisk.org for more information about
14  * the Asterisk project. Please do not directly contact
15  * any of the maintainers of this project for assistance;
16  * the project provides a web site, mailing lists and IRC
17  * channels for your use.
18  *
19  * This program is free software, distributed under the terms of
20  * the GNU General Public License Version 2. See the LICENSE file
21  * at the top of the source tree.
22  */
23 
24 /*! \file
25  *
26  * \brief This file is part of the chan_h323 driver for Asterisk
27  *
28  * \author Jeremy McNamara
29  *
30  * \par See also
31  * \arg Config_h323
32  * \extref OpenH323 http://www.voxgratia.org/
33  *
34  * \ingroup channel_drivers
35  */
36 
37 /*** MODULEINFO
38  <depend>openh323</depend>
39  <defaultenabled>yes</defaultenabled>
40  <support_level>deprecated</support_level>
41  <replacement>chan_ooh323</replacement>
42  ***/
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 #include "asterisk.h"
49 
50 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 350789 $")
51 
52 #ifdef __cplusplus
53 }
54 #endif
55 
56 #include <sys/types.h>
57 #include <sys/socket.h>
58 #include <sys/signal.h>
59 #include <sys/param.h>
60 #include <arpa/inet.h>
61 #include <net/if.h>
62 #include <netinet/in.h>
63 #include <netinet/in_systm.h>
64 #include <netinet/ip.h>
65 #include <netdb.h>
66 #include <fcntl.h>
67 
68 #ifdef __cplusplus
69 extern "C" {
70 #endif
71 
72 #include "asterisk/lock.h"
73 #include "asterisk/channel.h"
74 #include "asterisk/config.h"
75 #include "asterisk/module.h"
76 #include "asterisk/musiconhold.h"
77 #include "asterisk/pbx.h"
78 #include "asterisk/utils.h"
79 #include "asterisk/sched.h"
80 #include "asterisk/io.h"
81 #include "asterisk/rtp_engine.h"
82 #include "asterisk/acl.h"
83 #include "asterisk/callerid.h"
84 #include "asterisk/cli.h"
85 #include "asterisk/dsp.h"
86 #include "asterisk/causes.h"
87 #include "asterisk/stringfields.h"
88 #include "asterisk/abstract_jb.h"
89 #include "asterisk/astobj.h"
90 
91 #ifdef __cplusplus
92 }
93 #endif
94 
95 #undef open
96 #undef close
97 #include "h323/chan_h323.h"
98 
99 receive_digit_cb on_receive_digit;
101 start_rtp_cb on_start_rtp_channel;
102 setup_incoming_cb on_incoming_call;
103 setup_outbound_cb on_outgoing_call;
104 chan_ringing_cb on_chan_ringing;
105 con_established_cb on_connection_established;
107 answer_call_cb on_answer_call;
108 progress_cb on_progress;
110 hangup_cb on_hangup;
111 setcapabilities_cb on_setcapabilities;
112 setpeercapabilities_cb on_setpeercapabilities;
113 onhold_cb on_hold;
114 
115 int h323debug; /*!< global debug flag */
116 
117 /*! \brief Global jitterbuffer configuration - by default, jb is disabled
118  * \note Values shown here match the defaults shown in h323.conf.sample */
120 {
121  .flags = 0,
122  .max_size = 200,
123  .resync_threshold = 1000,
124  .impl = "fixed",
125  .target_extra = 40,
126 };
128 
129 /** Variables required by Asterisk */
130 static const char tdesc[] = "The NuFone Network's Open H.323 Channel Driver";
131 static const char config[] = "h323.conf";
132 static char default_context[AST_MAX_CONTEXT] = "default";
133 static struct sockaddr_in bindaddr;
134 
135 #define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261)
136 
137 /** H.323 configuration values */
138 static int h323_signalling_port = 1720;
139 static char gatekeeper[100];
140 static int gatekeeper_disable = 1;
141 static int gatekeeper_discover = 0;
142 static int gkroute = 0;
143 /* Find user by alias (h.323 id) is default, alternative is the incoming call's source IP address*/
144 static int userbyalias = 1;
145 static int acceptAnonymous = 1;
146 static unsigned int tos = 0;
147 static unsigned int cos = 0;
148 static char secret[50];
149 static unsigned int unique = 0;
150 
151 static call_options_t global_options;
152 
153 /*! \brief Private structure of a OpenH323 channel */
154 static struct oh323_pvt {
155  ast_mutex_t lock; /*!< Channel private lock */
156  call_options_t options; /*!<!< Options to be used during call setup */
157  int alreadygone; /*!< Whether or not we've already been destroyed by our peer */
158  int needdestroy; /*!< if we need to be destroyed */
159  call_details_t cd; /*!< Call details */
160  struct ast_channel *owner; /*!< Who owns us */
161  struct sockaddr_in sa; /*!< Our peer */
162  struct sockaddr_in redirip; /*!< Where our RTP should be going if not to us */
163  int nonCodecCapability; /*!< non-audio capability */
164  int outgoing; /*!< Outgoing or incoming call? */
165  char exten[AST_MAX_EXTENSION]; /*!< Requested extension */
166  char context[AST_MAX_CONTEXT]; /*!< Context where to start */
167  char accountcode[256]; /*!< Account code */
168  char rdnis[80]; /*!< Referring DNIS, if available */
169  int amaflags; /*!< AMA Flags */
170  struct ast_rtp_instance *rtp; /*!< RTP Session */
171  struct ast_dsp *vad; /*!< Used for in-band DTMF detection */
172  int nativeformats; /*!< Codec formats supported by a channel */
173  int needhangup; /*!< Send hangup when Asterisk is ready */
174  int hangupcause; /*!< Hangup cause from OpenH323 layer */
175  int newstate; /*!< Pending state change */
176  int newcontrol; /*!< Pending control to send */
177  int newdigit; /*!< Pending DTMF digit to send */
178  int newduration; /*!< Pending DTMF digit duration to send */
179  format_t pref_codec; /*!< Preferred codec */
180  format_t peercapability; /*!< Capabilities learned from peer */
181  format_t jointcapability; /*!< Common capabilities for local and remote side */
182  struct ast_codec_pref peer_prefs; /*!< Preferenced list of codecs which remote side supports */
183  int dtmf_pt[2]; /*!< Payload code used for RFC2833/CISCO messages */
184  int curDTMF; /*!< DTMF tone being generated to Asterisk side */
185  int DTMFsched; /*!< Scheduler descriptor for DTMF */
186  int update_rtp_info; /*!< Configuration of fd's array is pending */
187  int recvonly; /*!< Peer isn't wish to receive our voice stream */
188  int txDtmfDigit; /*!< DTMF digit being to send to H.323 side */
189  int noInbandDtmf; /*!< Inband DTMF processing by DSP isn't available */
190  int connection_established; /*!< Call got CONNECT message */
191  int got_progress; /*!< Call got PROGRESS message, pass inband audio */
192  struct oh323_pvt *next; /*!< Next channel in list */
193 } *iflist = NULL;
194 
195 /*! \brief H323 User list */
196 static struct h323_user_list {
197  ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user);
198 } userl;
199 
200 /*! \brief H323 peer list */
201 static struct h323_peer_list {
202  ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer);
203 } peerl;
204 
205 /*! \brief H323 alias list */
206 static struct h323_alias_list {
207  ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias);
208 } aliasl;
209 
210 /* Asterisk RTP stuff */
211 static struct sched_context *sched;
212 static struct io_context *io;
213 
214 AST_MUTEX_DEFINE_STATIC(iflock); /*!< Protect the interface list (oh323_pvt) */
215 
216 /*! \brief Protect the H.323 monitoring thread, so only one process can kill or start it, and not
217  when it's doing something critical. */
219 
220 /*! \brief Protect the H.323 capabilities list, to avoid more than one channel to set the capabilities simultaneaously in the h323 stack. */
222 
223 /*! \brief Protect the reload process */
225 static int h323_reloading = 0;
226 
227 /*! \brief This is the thread for the monitor which checks for input on the channels
228  which are not currently in use. */
230 static int restart_monitor(void);
231 static int h323_do_reload(void);
232 
233 static void delete_users(void);
234 static void delete_aliases(void);
235 static void prune_peers(void);
236 
237 static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
238 static int oh323_digit_begin(struct ast_channel *c, char digit);
239 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
240 static int oh323_call(struct ast_channel *c, char *dest, int timeout);
241 static int oh323_hangup(struct ast_channel *c);
242 static int oh323_answer(struct ast_channel *c);
243 static struct ast_frame *oh323_read(struct ast_channel *c);
244 static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
245 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
246 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
247 
248 static const struct ast_channel_tech oh323_tech = {
249  .type = "H323",
250  .description = tdesc,
251  .capabilities = AST_FORMAT_AUDIO_MASK,
253  .requester = oh323_request,
254  .send_digit_begin = oh323_digit_begin,
255  .send_digit_end = oh323_digit_end,
256  .call = oh323_call,
257  .hangup = oh323_hangup,
258  .answer = oh323_answer,
259  .read = oh323_read,
260  .write = oh323_write,
261  .indicate = oh323_indicate,
262  .fixup = oh323_fixup,
263  .bridge = ast_rtp_instance_bridge,
264 };
265 
266 static const char* redirectingreason2str(int redirectingreason)
267 {
268  switch (redirectingreason) {
269  case 0:
270  return "UNKNOWN";
271  case 1:
272  return "BUSY";
273  case 2:
274  return "NO_REPLY";
275  case 0xF:
276  return "UNCONDITIONAL";
277  default:
278  return "NOREDIRECT";
279  }
280 }
281 
282 static void oh323_destroy_alias(struct oh323_alias *alias)
283 {
284  if (h323debug)
285  ast_debug(1, "Destroying alias '%s'\n", alias->name);
286  ast_free(alias);
287 }
288 
289 static void oh323_destroy_user(struct oh323_user *user)
290 {
291  if (h323debug)
292  ast_debug(1, "Destroying user '%s'\n", user->name);
293  ast_free_ha(user->ha);
294  ast_free(user);
295 }
296 
297 static void oh323_destroy_peer(struct oh323_peer *peer)
298 {
299  if (h323debug)
300  ast_debug(1, "Destroying peer '%s'\n", peer->name);
301  ast_free_ha(peer->ha);
302  ast_free(peer);
303 }
304 
305 static int oh323_simulate_dtmf_end(const void *data)
306 {
307  struct oh323_pvt *pvt = (struct oh323_pvt *)data;
308 
309  if (pvt) {
310  ast_mutex_lock(&pvt->lock);
311  /* Don't hold pvt lock while trying to lock the channel */
312  while (pvt->owner && ast_channel_trylock(pvt->owner)) {
313  DEADLOCK_AVOIDANCE(&pvt->lock);
314  }
315 
316  if (pvt->owner) {
317  struct ast_frame f = {
319  .subclass.integer = pvt->curDTMF,
320  .samples = 0,
321  .src = "SIMULATE_DTMF_END",
322  };
323  ast_queue_frame(pvt->owner, &f);
325  }
326 
327  pvt->DTMFsched = -1;
328  ast_mutex_unlock(&pvt->lock);
329  }
330 
331  return 0;
332 }
333 
334 /*! \brief Channel and private structures should be already locked */
335 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
336 {
337  if (c->nativeformats != pvt->nativeformats) {
338  if (h323debug)
339  ast_debug(1, "Preparing %s for new native format\n", c->name);
340  c->nativeformats = pvt->nativeformats;
343  }
344  if (pvt->needhangup) {
345  if (h323debug)
346  ast_debug(1, "Process pending hangup for %s\n", c->name);
348  c->hangupcause = pvt->hangupcause;
350  pvt->needhangup = 0;
351  pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->DTMFsched = -1;
352  }
353  if (pvt->newstate >= 0) {
354  ast_setstate(c, pvt->newstate);
355  pvt->newstate = -1;
356  }
357  if (pvt->newcontrol >= 0) {
358  ast_queue_control(c, pvt->newcontrol);
359  pvt->newcontrol = -1;
360  }
361  if (pvt->newdigit >= 0) {
362  struct ast_frame f = {
364  .subclass.integer = pvt->newdigit,
365  .samples = pvt->newduration * 8,
366  .len = pvt->newduration,
367  .src = "UPDATE_INFO",
368  };
369  if (pvt->newdigit == ' ') { /* signalUpdate message */
370  f.subclass.integer = pvt->curDTMF;
371  if (pvt->DTMFsched >= 0) {
372  AST_SCHED_DEL(sched, pvt->DTMFsched);
373  }
374  } else { /* Regular input or signal message */
375  if (pvt->newduration) { /* This is a signal, signalUpdate follows */
377  AST_SCHED_DEL(sched, pvt->DTMFsched);
379  if (h323debug)
380  ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", pvt->newduration, pvt->DTMFsched);
381  }
382  pvt->curDTMF = pvt->newdigit;
383  }
384  ast_queue_frame(c, &f);
385  pvt->newdigit = -1;
386  }
387  if (pvt->update_rtp_info > 0) {
388  if (pvt->rtp) {
392  ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */
393  }
394  pvt->update_rtp_info = -1;
395  }
396 }
397 
398 /*! \brief Only channel structure should be locked */
399 static void oh323_update_info(struct ast_channel *c)
400 {
401  struct oh323_pvt *pvt = c->tech_pvt;
402 
403  if (pvt) {
404  ast_mutex_lock(&pvt->lock);
405  __oh323_update_info(c, pvt);
406  ast_mutex_unlock(&pvt->lock);
407  }
408 }
409 
410 static void cleanup_call_details(call_details_t *cd)
411 {
412  if (cd->call_token) {
413  ast_free(cd->call_token);
414  cd->call_token = NULL;
415  }
416  if (cd->call_source_aliases) {
417  ast_free(cd->call_source_aliases);
418  cd->call_source_aliases = NULL;
419  }
420  if (cd->call_dest_alias) {
421  ast_free(cd->call_dest_alias);
422  cd->call_dest_alias = NULL;
423  }
424  if (cd->call_source_name) {
425  ast_free(cd->call_source_name);
426  cd->call_source_name = NULL;
427  }
428  if (cd->call_source_e164) {
429  ast_free(cd->call_source_e164);
430  cd->call_source_e164 = NULL;
431  }
432  if (cd->call_dest_e164) {
433  ast_free(cd->call_dest_e164);
434  cd->call_dest_e164 = NULL;
435  }
436  if (cd->sourceIp) {
437  ast_free(cd->sourceIp);
438  cd->sourceIp = NULL;
439  }
440  if (cd->redirect_number) {
441  ast_free(cd->redirect_number);
442  cd->redirect_number = NULL;
443  }
444 }
445 
446 static void __oh323_destroy(struct oh323_pvt *pvt)
447 {
448  struct oh323_pvt *cur, *prev = NULL;
449 
450  AST_SCHED_DEL(sched, pvt->DTMFsched);
451 
452  if (pvt->rtp) {
454  }
455 
456  /* Free dsp used for in-band DTMF detection */
457  if (pvt->vad) {
458  ast_dsp_free(pvt->vad);
459  }
460  cleanup_call_details(&pvt->cd);
461 
462  /* Unlink us from the owner if we have one */
463  if (pvt->owner) {
464  ast_channel_lock(pvt->owner);
465  if (h323debug)
466  ast_debug(1, "Detaching from %s\n", pvt->owner->name);
467  pvt->owner->tech_pvt = NULL;
469  }
470  cur = iflist;
471  while(cur) {
472  if (cur == pvt) {
473  if (prev)
474  prev->next = cur->next;
475  else
476  iflist = cur->next;
477  break;
478  }
479  prev = cur;
480  cur = cur->next;
481  }
482  if (!cur) {
483  ast_log(LOG_WARNING, "%p is not in list?!?! \n", cur);
484  } else {
485  ast_mutex_unlock(&pvt->lock);
486  ast_mutex_destroy(&pvt->lock);
487  ast_free(pvt);
488  }
489 }
490 
491 static void oh323_destroy(struct oh323_pvt *pvt)
492 {
493  if (h323debug) {
494  ast_debug(1, "Destroying channel %s\n", (pvt->owner ? pvt->owner->name : "<unknown>"));
495  }
497  ast_mutex_lock(&pvt->lock);
498  __oh323_destroy(pvt);
500 }
501 
502 static int oh323_digit_begin(struct ast_channel *c, char digit)
503 {
504  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
505  char *token;
506 
507  if (!pvt) {
508  ast_log(LOG_ERROR, "No private structure?! This is bad\n");
509  return -1;
510  }
511  ast_mutex_lock(&pvt->lock);
512  if (pvt->rtp &&
513  (((pvt->options.dtmfmode & H323_DTMF_RFC2833) && pvt->dtmf_pt[0])
514  /*|| ((pvt->options.dtmfmode & H323_DTMF_CISCO) && pvt->dtmf_pt[1]))*/)) {
515  /* out-of-band DTMF */
516  if (h323debug) {
517  ast_log(LOG_DTMF, "Begin sending out-of-band digit %c on %s\n", digit, c->name);
518  }
519  ast_rtp_instance_dtmf_begin(pvt->rtp, digit);
520  ast_mutex_unlock(&pvt->lock);
521  } else if (pvt->txDtmfDigit != digit) {
522  /* in-band DTMF */
523  if (h323debug) {
524  ast_log(LOG_DTMF, "Begin sending inband digit %c on %s\n", digit, c->name);
525  }
526  pvt->txDtmfDigit = digit;
527  token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
528  ast_mutex_unlock(&pvt->lock);
529  h323_send_tone(token, digit);
530  if (token) {
531  ast_free(token);
532  }
533  } else
534  ast_mutex_unlock(&pvt->lock);
536  return 0;
537 }
538 
539 /*! \brief
540  * Send (play) the specified digit to the channel.
541  *
542  */
543 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
544 {
545  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
546  char *token;
547 
548  if (!pvt) {
549  ast_log(LOG_ERROR, "No private structure?! This is bad\n");
550  return -1;
551  }
552  ast_mutex_lock(&pvt->lock);
553  if (pvt->rtp && (pvt->options.dtmfmode & H323_DTMF_RFC2833) && ((pvt->dtmf_pt[0] > 0) || (pvt->dtmf_pt[0] > 0))) {
554  /* out-of-band DTMF */
555  if (h323debug) {
556  ast_log(LOG_DTMF, "End sending out-of-band digit %c on %s, duration %d\n", digit, c->name, duration);
557  }
558  ast_rtp_instance_dtmf_end(pvt->rtp, digit);
559  ast_mutex_unlock(&pvt->lock);
560  } else {
561  /* in-band DTMF */
562  if (h323debug) {
563  ast_log(LOG_DTMF, "End sending inband digit %c on %s, duration %d\n", digit, c->name, duration);
564  }
565  pvt->txDtmfDigit = ' ';
566  token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
567  ast_mutex_unlock(&pvt->lock);
568  h323_send_tone(token, ' ');
569  if (token) {
570  ast_free(token);
571  }
572  }
574  return 0;
575 }
576 
577 /*! \brief
578  * Make a call over the specified channel to the specified
579  * destination.
580  * Returns -1 on error, 0 on success.
581  */
582 static int oh323_call(struct ast_channel *c, char *dest, int timeout)
583 {
584  int res = 0;
585  struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
586  const char *addr;
587  char called_addr[1024];
588 
589  if (h323debug) {
590  ast_debug(1, "Calling to %s on %s\n", dest, c->name);
591  }
592  if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
593  ast_log(LOG_WARNING, "Line is already in use (%s)\n", c->name);
594  return -1;
595  }
596  ast_mutex_lock(&pvt->lock);
597  if (!gatekeeper_disable) {
598  if (ast_strlen_zero(pvt->exten)) {
599  ast_copy_string(called_addr, dest, sizeof(called_addr));
600  } else {
601  snprintf(called_addr, sizeof(called_addr), "%s@%s", pvt->exten, dest);
602  }
603  } else {
604  res = htons(pvt->sa.sin_port);
605  addr = ast_inet_ntoa(pvt->sa.sin_addr);
606  if (ast_strlen_zero(pvt->exten)) {
607  snprintf(called_addr, sizeof(called_addr), "%s:%d", addr, res);
608  } else {
609  snprintf(called_addr, sizeof(called_addr), "%s@%s:%d", pvt->exten, addr, res);
610  }
611  }
612  /* make sure null terminated */
613  called_addr[sizeof(called_addr) - 1] = '\0';
614 
615  if (c->connected.id.number.valid && c->connected.id.number.str) {
616  ast_copy_string(pvt->options.cid_num, c->connected.id.number.str, sizeof(pvt->options.cid_num));
617  }
618 
619  if (c->connected.id.name.valid && c->connected.id.name.str) {
620  ast_copy_string(pvt->options.cid_name, c->connected.id.name.str, sizeof(pvt->options.cid_name));
621  }
622 
624  ast_copy_string(pvt->options.cid_rdnis, c->redirecting.from.number.str, sizeof(pvt->options.cid_rdnis));
625  }
626 
627  pvt->options.presentation = ast_party_id_presentation(&c->connected.id);
628  pvt->options.type_of_number = c->connected.id.number.plan;
629 
630  if ((addr = pbx_builtin_getvar_helper(c, "PRIREDIRECTREASON"))) {
631  if (!strcasecmp(addr, "UNKNOWN"))
632  pvt->options.redirect_reason = 0;
633  else if (!strcasecmp(addr, "BUSY"))
634  pvt->options.redirect_reason = 1;
635  else if (!strcasecmp(addr, "NO_REPLY"))
636  pvt->options.redirect_reason = 2;
637  else if (!strcasecmp(addr, "UNCONDITIONAL"))
638  pvt->options.redirect_reason = 15;
639  else
640  pvt->options.redirect_reason = -1;
641  } else
642  pvt->options.redirect_reason = -1;
643 
644  pvt->options.transfer_capability = c->transfercapability;
645 
646  /* indicate that this is an outgoing call */
647  pvt->outgoing = 1;
648 
649  ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", c->transfercapability, ast_transfercapability2str(c->transfercapability));
650  if (h323debug)
651  ast_debug(1, "Placing outgoing call to %s, %d/%d\n", called_addr, pvt->options.dtmfcodec[0], pvt->options.dtmfcodec[1]);
652  ast_mutex_unlock(&pvt->lock);
653  res = h323_make_call(called_addr, &(pvt->cd), &pvt->options);
654  if (res) {
655  ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
656  return -1;
657  }
659  return 0;
660 }
661 
662 static int oh323_answer(struct ast_channel *c)
663 {
664  int res;
665  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
666  char *token;
667 
668  if (h323debug)
669  ast_debug(1, "Answering on %s\n", c->name);
670 
671  ast_mutex_lock(&pvt->lock);
672  token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
673  ast_mutex_unlock(&pvt->lock);
674  res = h323_answering_call(token, 0);
675  if (token)
676  ast_free(token);
677 
679  if (c->_state != AST_STATE_UP) {
681  }
682  return res;
683 }
684 
685 static int oh323_hangup(struct ast_channel *c)
686 {
687  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
688  int q931cause = AST_CAUSE_NORMAL_CLEARING;
689  char *call_token;
690 
691 
692  if (h323debug)
693  ast_debug(1, "Hanging up and scheduling destroy of call %s\n", c->name);
694 
695  if (!c->tech_pvt) {
696  ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
697  return 0;
698  }
699  ast_mutex_lock(&pvt->lock);
700  /* Determine how to disconnect */
701  if (pvt->owner != c) {
702  ast_log(LOG_WARNING, "Huh? We aren't the owner?\n");
703  ast_mutex_unlock(&pvt->lock);
704  return 0;
705  }
706 
707  pvt->owner = NULL;
708  c->tech_pvt = NULL;
709 
710  if (c->hangupcause) {
711  q931cause = c->hangupcause;
712  } else {
713  const char *cause = pbx_builtin_getvar_helper(c, "DIALSTATUS");
714  if (cause) {
715  if (!strcmp(cause, "CONGESTION")) {
717  } else if (!strcmp(cause, "BUSY")) {
718  q931cause = AST_CAUSE_USER_BUSY;
719  } else if (!strcmp(cause, "CHANISUNVAIL")) {
721  } else if (!strcmp(cause, "NOANSWER")) {
722  q931cause = AST_CAUSE_NO_ANSWER;
723  } else if (!strcmp(cause, "CANCEL")) {
724  q931cause = AST_CAUSE_CALL_REJECTED;
725  }
726  }
727  }
728 
729  /* Start the process if it's not already started */
730  if (!pvt->alreadygone && !pvt->hangupcause) {
731  call_token = pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL;
732  if (call_token) {
733  /* Release lock to eliminate deadlock */
734  ast_mutex_unlock(&pvt->lock);
735  if (h323_clear_call(call_token, q931cause)) {
736  ast_log(LOG_WARNING, "ClearCall failed.\n");
737  }
738  ast_free(call_token);
739  ast_mutex_lock(&pvt->lock);
740  }
741  }
742  pvt->needdestroy = 1;
743  ast_mutex_unlock(&pvt->lock);
744 
745  /* Update usage counter */
747 
748  return 0;
749 }
750 
751 /*! \brief Retrieve audio/etc from channel. Assumes pvt->lock is already held. */
752 static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
753 {
754  struct ast_frame *f;
755 
756  /* Only apply it for the first packet, we just need the correct ip/port */
757  if (pvt->options.nat) {
759  pvt->options.nat = 0;
760  }
761 
762  f = ast_rtp_instance_read(pvt->rtp, 0);
763  /* Don't send RFC2833 if we're not supposed to */
764  if (f && (f->frametype == AST_FRAME_DTMF) && !(pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO))) {
765  return &ast_null_frame;
766  }
767  if (f && pvt->owner) {
768  /* We already hold the channel lock */
769  if (f->frametype == AST_FRAME_VOICE) {
770  if (f->subclass.codec != pvt->owner->nativeformats) {
771  /* Try to avoid deadlock */
772  if (ast_channel_trylock(pvt->owner)) {
773  ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
774  return &ast_null_frame;
775  }
776  if (h323debug)
777  ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(f->subclass.codec));
778  pvt->owner->nativeformats = f->subclass.codec;
779  pvt->nativeformats = f->subclass.codec;
783  }
784  /* Do in-band DTMF detection */
785  if ((pvt->options.dtmfmode & H323_DTMF_INBAND) && pvt->vad) {
787  if (!ast_channel_trylock(pvt->owner)) {
788  f = ast_dsp_process(pvt->owner, pvt->vad, f);
790  }
791  else
792  ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
793  } else if (pvt->nativeformats && !pvt->noInbandDtmf) {
794  ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass.codec));
795  pvt->noInbandDtmf = 1;
796  }
797  if (f &&(f->frametype == AST_FRAME_DTMF)) {
798  if (h323debug)
799  ast_log(LOG_DTMF, "Received in-band digit %c.\n", f->subclass.integer);
800  }
801  }
802  }
803  }
804  return f;
805 }
806 
807 static struct ast_frame *oh323_read(struct ast_channel *c)
808 {
809  struct ast_frame *fr;
810  struct oh323_pvt *pvt = (struct oh323_pvt *)c->tech_pvt;
811  ast_mutex_lock(&pvt->lock);
812  __oh323_update_info(c, pvt);
813  switch(c->fdno) {
814  case 0:
815  fr = oh323_rtp_read(pvt);
816  break;
817  case 1:
818  if (pvt->rtp)
819  fr = ast_rtp_instance_read(pvt->rtp, 1);
820  else
821  fr = &ast_null_frame;
822  break;
823  default:
824  ast_log(LOG_ERROR, "Unable to handle fd %d on channel %s\n", c->fdno, c->name);
825  fr = &ast_null_frame;
826  break;
827  }
828  ast_mutex_unlock(&pvt->lock);
829  return fr;
830 }
831 
832 static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
833 {
834  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
835  int res = 0;
836  if (frame->frametype != AST_FRAME_VOICE) {
837  if (frame->frametype == AST_FRAME_IMAGE) {
838  return 0;
839  } else {
840  ast_log(LOG_WARNING, "Can't send %d type frames with H323 write\n", frame->frametype);
841  return 0;
842  }
843  } else {
844  if (!(frame->subclass.codec & c->nativeformats)) {
845  char tmp[256];
846  ast_log(LOG_WARNING, "Asked to transmit frame type '%s', while native formats is '%s' (read/write = %s/%s)\n",
848  return 0;
849  }
850  }
851  if (pvt) {
852  ast_mutex_lock(&pvt->lock);
853  if (pvt->rtp && !pvt->recvonly)
854  res = ast_rtp_instance_write(pvt->rtp, frame);
855  __oh323_update_info(c, pvt);
856  ast_mutex_unlock(&pvt->lock);
857  }
858  return res;
859 }
860 
861 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
862 {
863 
864  struct oh323_pvt *pvt = (struct oh323_pvt *) c->tech_pvt;
865  char *token = (char *)NULL;
866  int res = -1;
867  int got_progress;
868 
869  ast_mutex_lock(&pvt->lock);
870  token = (pvt->cd.call_token ? ast_strdup(pvt->cd.call_token) : NULL);
871  got_progress = pvt->got_progress;
872  if (condition == AST_CONTROL_PROGRESS)
873  pvt->got_progress = 1;
874  else if ((condition == AST_CONTROL_BUSY) || (condition == AST_CONTROL_CONGESTION))
875  pvt->alreadygone = 1;
876  ast_mutex_unlock(&pvt->lock);
877 
878  if (h323debug)
879  ast_debug(1, "OH323: Indicating %d on %s (%s)\n", condition, token, c->name);
880 
881  switch(condition) {
882  case AST_CONTROL_RINGING:
883  if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
884  h323_send_alerting(token);
885  res = (got_progress ? 0 : -1); /* Do not simulate any audio tones if we got PROGRESS message */
886  }
887  break;
889  if (c->_state != AST_STATE_UP) {
890  /* Do not send PROGRESS message more than once */
891  if (!got_progress)
892  h323_send_progress(token);
893  res = 0;
894  }
895  break;
896  case AST_CONTROL_BUSY:
897  if (c->_state != AST_STATE_UP) {
898  h323_answering_call(token, 1);
900  res = 0;
901  }
902  break;
904  /* While h323 does support overlapped dialing, this channel driver does not
905  * at this time. Treat a response of Incomplete as if it were congestion.
906  */
908  if (c->_state != AST_STATE_UP) {
909  h323_answering_call(token, 1);
911  res = 0;
912  }
913  break;
914  case AST_CONTROL_HOLD:
915  h323_hold_call(token, 1);
916  /* We should start MOH only if remote party isn't provide audio for us */
917  ast_moh_start(c, data, NULL);
918  res = 0;
919  break;
920  case AST_CONTROL_UNHOLD:
921  h323_hold_call(token, 0);
922  ast_moh_stop(c);
923  res = 0;
924  break;
927  res = 0;
928  break;
931  res = 0;
932  break;
934  case -1:
935  break;
936  default:
937  ast_log(LOG_WARNING, "OH323: Don't know how to indicate condition %d on %s\n", condition, token);
938  break;
939  }
940 
941  if (h323debug)
942  ast_debug(1, "OH323: Indicated %d on %s, res=%d\n", condition, token, res);
943  if (token)
944  ast_free(token);
946 
947  return res;
948 }
949 
950 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
951 {
952  struct oh323_pvt *pvt = (struct oh323_pvt *) newchan->tech_pvt;
953 
954  ast_mutex_lock(&pvt->lock);
955  if (pvt->owner != oldchan) {
956  ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, pvt->owner);
957  return -1;
958  }
959  pvt->owner = newchan;
960  ast_mutex_unlock(&pvt->lock);
961  return 0;
962 }
963 
964 static int __oh323_rtp_create(struct oh323_pvt *pvt)
965 {
966  struct ast_sockaddr our_addr;
967 
968  if (pvt->rtp)
969  return 0;
970 
971  {
972  struct ast_sockaddr tmp;
973 
975  if (ast_find_ourip(&our_addr, &tmp, AF_INET)) {
976  ast_mutex_unlock(&pvt->lock);
977  ast_log(LOG_ERROR, "Unable to locate local IP address for RTP stream\n");
978  return -1;
979  }
980  }
981  our_addr.ss.ss_family = AF_INET;
982  pvt->rtp = ast_rtp_instance_new("asterisk", sched, &our_addr, NULL);
983  if (!pvt->rtp) {
984  ast_mutex_unlock(&pvt->lock);
985  ast_log(LOG_WARNING, "Unable to create RTP session: %s\n", strerror(errno));
986  return -1;
987  }
988  if (h323debug)
989  ast_debug(1, "Created RTP channel\n");
990 
991  ast_rtp_instance_set_qos(pvt->rtp, tos, cos, "H323 RTP");
992 
993  if (h323debug)
994  ast_debug(1, "Setting NAT on RTP to %d\n", pvt->options.nat);
996 
997  if (pvt->dtmf_pt[0] > 0)
998  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pvt->dtmf_pt[0], "audio", "telephone-event", 0);
999  if (pvt->dtmf_pt[1] > 0)
1000  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, pvt->dtmf_pt[1], "audio", "cisco-telephone-event", 0);
1001 
1002  if (pvt->peercapability)
1004 
1005  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
1007  ast_channel_set_fd(pvt->owner, 0, ast_rtp_instance_fd(pvt->rtp, 0));
1008  ast_channel_set_fd(pvt->owner, 1, ast_rtp_instance_fd(pvt->rtp, 1));
1009  ast_queue_frame(pvt->owner, &ast_null_frame); /* Tell Asterisk to apply changes */
1010  ast_channel_unlock(pvt->owner);
1011  } else
1012  pvt->update_rtp_info = 1;
1013 
1014  return 0;
1015 }
1016 
1017 /*! \brief Private structure should be locked on a call */
1018 static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
1019 {
1020  struct ast_channel *ch;
1021  char *cid_num, *cid_name;
1022  int fmt;
1023 
1024  if (!ast_strlen_zero(pvt->options.cid_num))
1025  cid_num = pvt->options.cid_num;
1026  else
1027  cid_num = pvt->cd.call_source_e164;
1028 
1029  if (!ast_strlen_zero(pvt->options.cid_name))
1030  cid_name = pvt->options.cid_name;
1031  else
1032  cid_name = pvt->cd.call_source_name;
1033 
1034  /* Don't hold a oh323_pvt lock while we allocate a chanel */
1035  ast_mutex_unlock(&pvt->lock);
1036  ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, linkedid, pvt->amaflags, "H323/%s", host);
1037  /* Update usage counter */
1039  ast_mutex_lock(&pvt->lock);
1040  if (ch) {
1041  ch->tech = &oh323_tech;
1042  if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
1043  fmt = global_options.capability;
1044  ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
1045  pvt->nativeformats = ch->nativeformats;
1046  fmt = ast_best_codec(ch->nativeformats);
1047  ch->writeformat = fmt;
1048  ch->rawwriteformat = fmt;
1049  ch->readformat = fmt;
1050  ch->rawreadformat = fmt;
1051  if (!pvt->rtp)
1052  __oh323_rtp_create(pvt);
1053 #if 0
1054  ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(pvt->rtp, 0));
1055  ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(pvt->rtp, 1));
1056 #endif
1057 #ifdef VIDEO_SUPPORT
1058  if (pvt->vrtp) {
1059  ast_channel_set_fd(ch, 2, ast_rtp_instance_fd(pvt->vrtp, 0));
1060  ast_channel_set_fd(ch, 3, ast_rtp_instance_fd(pvt->vrtp, 1));
1061  }
1062 #endif
1063 #ifdef T38_SUPPORT
1064  if (pvt->udptl) {
1065  ast_channel_set_fd(ch, 4, ast_udptl_fd(pvt->udptl));
1066  }
1067 #endif
1068  if (state == AST_STATE_RING) {
1069  ch->rings = 1;
1070  }
1071  /* Allocate dsp for in-band DTMF support */
1072  if (pvt->options.dtmfmode & H323_DTMF_INBAND) {
1073  pvt->vad = ast_dsp_new();
1075  }
1076  /* Register channel functions. */
1077  ch->tech_pvt = pvt;
1078  /* Set the owner of this channel */
1079  pvt->owner = ch;
1080 
1081  ast_copy_string(ch->context, pvt->context, sizeof(ch->context));
1082  ast_copy_string(ch->exten, pvt->exten, sizeof(ch->exten));
1083  ch->priority = 1;
1084  if (!ast_strlen_zero(pvt->accountcode)) {
1086  }
1087  if (pvt->amaflags) {
1088  ch->amaflags = pvt->amaflags;
1089  }
1090 
1091  /* Don't use ast_set_callerid() here because it will
1092  * generate a needless NewCallerID event */
1093  if (!ast_strlen_zero(cid_num)) {
1094  ch->caller.ani.number.valid = 1;
1095  ch->caller.ani.number.str = ast_strdup(cid_num);
1096  }
1097 
1098  if (pvt->cd.redirect_reason >= 0) {
1099  ch->redirecting.from.number.valid = 1;
1100  ch->redirecting.from.number.str = ast_strdup(pvt->cd.redirect_number);
1101  pbx_builtin_setvar_helper(ch, "PRIREDIRECTREASON", redirectingreason2str(pvt->cd.redirect_reason));
1102  }
1103  ch->caller.id.name.presentation = pvt->cd.presentation;
1104  ch->caller.id.number.presentation = pvt->cd.presentation;
1105  ch->caller.id.number.plan = pvt->cd.type_of_number;
1106 
1107  if (!ast_strlen_zero(pvt->exten) && strcmp(pvt->exten, "s")) {
1108  ch->dialed.number.str = ast_strdup(pvt->exten);
1109  }
1110  if (pvt->cd.transfer_capability >= 0)
1111  ch->transfercapability = pvt->cd.transfer_capability;
1112  if (state != AST_STATE_DOWN) {
1113  if (ast_pbx_start(ch)) {
1114  ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name);
1115  ast_hangup(ch);
1116  ch = NULL;
1117  }
1118  }
1119  } else {
1120  ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
1121  }
1122  return ch;
1123 }
1124 
1125 static struct oh323_pvt *oh323_alloc(int callid)
1126 {
1127  struct oh323_pvt *pvt;
1128 
1129  pvt = ast_calloc(1, sizeof(*pvt));
1130  if (!pvt) {
1131  ast_log(LOG_ERROR, "Couldn't allocate private structure. This is bad\n");
1132  return NULL;
1133  }
1134  pvt->cd.redirect_reason = -1;
1135  pvt->cd.transfer_capability = -1;
1136  /* Ensure the call token is allocated for outgoing call */
1137  if (!callid) {
1138  if ((pvt->cd).call_token == NULL) {
1139  (pvt->cd).call_token = ast_calloc(1, 128);
1140  }
1141  if (!pvt->cd.call_token) {
1142  ast_log(LOG_ERROR, "Not enough memory to alocate call token\n");
1144  ast_free(pvt);
1145  return NULL;
1146  }
1147  memset((char *)(pvt->cd).call_token, 0, 128);
1148  pvt->cd.call_reference = callid;
1149  }
1150  memcpy(&pvt->options, &global_options, sizeof(pvt->options));
1151  pvt->jointcapability = pvt->options.capability;
1152  if (pvt->options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) {
1154  } else {
1156  }
1157  ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
1158  pvt->newstate = pvt->newcontrol = pvt->newdigit = pvt->update_rtp_info = pvt->DTMFsched = -1;
1159  ast_mutex_init(&pvt->lock);
1160  /* Add to interface list */
1162  pvt->next = iflist;
1163  iflist = pvt;
1165  return pvt;
1166 }
1167 
1168 static struct oh323_pvt *find_call_locked(int call_reference, const char *token)
1169 {
1170  struct oh323_pvt *pvt;
1171 
1173  pvt = iflist;
1174  while(pvt) {
1175  if (!pvt->needdestroy && ((signed int)pvt->cd.call_reference == call_reference)) {
1176  /* Found the call */
1177  if ((token != NULL) && (pvt->cd.call_token != NULL) && (!strcmp(pvt->cd.call_token, token))) {
1178  ast_mutex_lock(&pvt->lock);
1180  return pvt;
1181  } else if (token == NULL) {
1182  ast_log(LOG_WARNING, "Call Token is NULL\n");
1183  ast_mutex_lock(&pvt->lock);
1185  return pvt;
1186  }
1187  }
1188  pvt = pvt->next;
1189  }
1191  return NULL;
1192 }
1193 
1194 static int update_state(struct oh323_pvt *pvt, int state, int signal)
1195 {
1196  if (!pvt)
1197  return 0;
1198  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
1199  if (state >= 0)
1200  ast_setstate(pvt->owner, state);
1201  if (signal >= 0)
1202  ast_queue_control(pvt->owner, signal);
1203  ast_channel_unlock(pvt->owner);
1204  return 1;
1205  }
1206  else {
1207  if (state >= 0)
1208  pvt->newstate = state;
1209  if (signal >= 0)
1210  pvt->newcontrol = signal;
1211  return 0;
1212  }
1213 }
1214 
1215 static struct oh323_alias *build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
1216 {
1217  struct oh323_alias *alias;
1218  int found = 0;
1219 
1220  alias = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&aliasl, name, name, 0, 0, strcasecmp);
1221 
1222  if (alias)
1223  found++;
1224  else {
1225  if (!(alias = ast_calloc(1, sizeof(*alias))))
1226  return NULL;
1227  ASTOBJ_INIT(alias);
1228  }
1229  if (!found && name)
1230  ast_copy_string(alias->name, name, sizeof(alias->name));
1231  for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
1232  if (!strcasecmp(v->name, "e164")) {
1233  ast_copy_string(alias->e164, v->value, sizeof(alias->e164));
1234  } else if (!strcasecmp(v->name, "prefix")) {
1235  ast_copy_string(alias->prefix, v->value, sizeof(alias->prefix));
1236  } else if (!strcasecmp(v->name, "context")) {
1237  ast_copy_string(alias->context, v->value, sizeof(alias->context));
1238  } else if (!strcasecmp(v->name, "secret")) {
1239  ast_copy_string(alias->secret, v->value, sizeof(alias->secret));
1240  } else {
1241  if (strcasecmp(v->value, "h323")) {
1242  ast_log(LOG_WARNING, "Keyword %s does not make sense in type=h323\n", v->name);
1243  }
1244  }
1245  }
1246  ASTOBJ_UNMARK(alias);
1247  return alias;
1248 }
1249 
1250 static struct oh323_alias *realtime_alias(const char *alias)
1251 {
1252  struct ast_variable *var, *tmp;
1253  struct oh323_alias *a;
1254 
1255  var = ast_load_realtime("h323", "name", alias, SENTINEL);
1256 
1257  if (!var)
1258  return NULL;
1259 
1260  for (tmp = var; tmp; tmp = tmp->next) {
1261  if (!strcasecmp(tmp->name, "type") &&
1262  !(!strcasecmp(tmp->value, "alias") || !strcasecmp(tmp->value, "h323"))) {
1263  ast_variables_destroy(var);
1264  return NULL;
1265  }
1266  }
1267 
1268  a = build_alias(alias, var, NULL, 1);
1269 
1270  ast_variables_destroy(var);
1271 
1272  return a;
1273 }
1274 
1275 static int update_common_options(struct ast_variable *v, struct call_options *options)
1276 {
1277  int tmp = 0;
1278  char *val, *opt;
1279 
1280  if (!strcasecmp(v->name, "allow")) {
1281  ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
1282  } else if (!strcasecmp(v->name, "autoframing")) {
1283  options->autoframing = ast_true(v->value);
1284  } else if (!strcasecmp(v->name, "disallow")) {
1285  ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
1286  } else if (!strcasecmp(v->name, "dtmfmode")) {
1287  val = ast_strdupa(v->value);
1288  if ((opt = strchr(val, ':')) != (char *)NULL) {
1289  *opt++ = '\0';
1290  tmp = atoi(opt);
1291  }
1292  if (!strcasecmp(v->value, "inband")) {
1293  options->dtmfmode |= H323_DTMF_INBAND;
1294  } else if (!strcasecmp(val, "rfc2833")) {
1295  options->dtmfmode |= H323_DTMF_RFC2833;
1296  if (!opt) {
1297  options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
1298  } else if ((tmp >= 96) && (tmp < 128)) {
1299  options->dtmfcodec[0] = tmp;
1300  } else {
1301  options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
1302  ast_log(LOG_WARNING, "Unknown rfc2833 payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[0]);
1303  }
1304  } else if (!strcasecmp(val, "cisco")) {
1305  options->dtmfmode |= H323_DTMF_CISCO;
1306  if (!opt) {
1307  options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
1308  } else if ((tmp >= 96) && (tmp < 128)) {
1309  options->dtmfcodec[1] = tmp;
1310  } else {
1311  options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
1312  ast_log(LOG_WARNING, "Unknown Cisco DTMF payload %s specified at line %d, using default %d\n", opt, v->lineno, options->dtmfcodec[1]);
1313  }
1314  } else if (!strcasecmp(v->value, "h245-signal")) {
1315  options->dtmfmode |= H323_DTMF_SIGNAL;
1316  } else {
1317  ast_log(LOG_WARNING, "Unknown dtmf mode '%s' at line %d\n", v->value, v->lineno);
1318  }
1319  } else if (!strcasecmp(v->name, "dtmfcodec")) {
1320  ast_log(LOG_NOTICE, "Option %s at line %d is deprecated. Use dtmfmode=rfc2833[:<payload>] instead.\n", v->name, v->lineno);
1321  tmp = atoi(v->value);
1322  if (tmp < 96)
1323  ast_log(LOG_WARNING, "Invalid %s value %s at line %d\n", v->name, v->value, v->lineno);
1324  else
1325  options->dtmfcodec[0] = tmp;
1326  } else if (!strcasecmp(v->name, "bridge")) {
1327  options->bridge = ast_true(v->value);
1328  } else if (!strcasecmp(v->name, "nat")) {
1329  options->nat = ast_true(v->value);
1330  } else if (!strcasecmp(v->name, "fastStart")) {
1331  options->fastStart = ast_true(v->value);
1332  } else if (!strcasecmp(v->name, "h245Tunneling")) {
1333  options->h245Tunneling = ast_true(v->value);
1334  } else if (!strcasecmp(v->name, "silenceSuppression")) {
1335  options->silenceSuppression = ast_true(v->value);
1336  } else if (!strcasecmp(v->name, "progress_setup")) {
1337  tmp = atoi(v->value);
1338  if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
1339  ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
1340  tmp = 0;
1341  }
1342  options->progress_setup = tmp;
1343  } else if (!strcasecmp(v->name, "progress_alert")) {
1344  tmp = atoi(v->value);
1345  if ((tmp != 0) && (tmp != 1) && (tmp != 8)) {
1346  ast_log(LOG_WARNING, "Invalid value %s for %s at line %d, assuming 0\n", v->value, v->name, v->lineno);
1347  tmp = 0;
1348  }
1349  options->progress_alert = tmp;
1350  } else if (!strcasecmp(v->name, "progress_audio")) {
1351  options->progress_audio = ast_true(v->value);
1352  } else if (!strcasecmp(v->name, "callerid")) {
1353  ast_callerid_split(v->value, options->cid_name, sizeof(options->cid_name), options->cid_num, sizeof(options->cid_num));
1354  } else if (!strcasecmp(v->name, "fullname")) {
1355  ast_copy_string(options->cid_name, v->value, sizeof(options->cid_name));
1356  } else if (!strcasecmp(v->name, "cid_number")) {
1357  ast_copy_string(options->cid_num, v->value, sizeof(options->cid_num));
1358  } else if (!strcasecmp(v->name, "tunneling")) {
1359  if (!strcasecmp(v->value, "none"))
1360  options->tunnelOptions = 0;
1361  else if (!strcasecmp(v->value, "cisco"))
1362  options->tunnelOptions |= H323_TUNNEL_CISCO;
1363  else if (!strcasecmp(v->value, "qsig"))
1364  options->tunnelOptions |= H323_TUNNEL_QSIG;
1365  else
1366  ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
1367  } else if (!strcasecmp(v->name, "hold")) {
1368  if (!strcasecmp(v->value, "none"))
1369  options->holdHandling = ~0;
1370  else if (!strcasecmp(v->value, "notify"))
1371  options->holdHandling |= H323_HOLD_NOTIFY;
1372  else if (!strcasecmp(v->value, "q931only"))
1373  options->holdHandling |= H323_HOLD_NOTIFY | H323_HOLD_Q931ONLY;
1374  else if (!strcasecmp(v->value, "h450"))
1375  options->holdHandling |= H323_HOLD_H450;
1376  else
1377  ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
1378  } else
1379  return 1;
1380 
1381  return 0;
1382 }
1383 
1384 static struct oh323_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
1385 {
1386  struct oh323_user *user;
1387  struct ast_ha *oldha;
1388  int found = 0;
1389  int format;
1390 
1391  user = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&userl, name, name, 0, 0, strcmp);
1392 
1393  if (user)
1394  found++;
1395  else {
1396  if (!(user = ast_calloc(1, sizeof(*user))))
1397  return NULL;
1398  ASTOBJ_INIT(user);
1399  }
1400  oldha = user->ha;
1401  user->ha = (struct ast_ha *)NULL;
1402  memcpy(&user->options, &global_options, sizeof(user->options));
1403  user->options.dtmfmode = 0;
1404  user->options.holdHandling = 0;
1405  /* Set default context */
1406  ast_copy_string(user->context, default_context, sizeof(user->context));
1407  if (user && !found)
1408  ast_copy_string(user->name, name, sizeof(user->name));
1409 
1410 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */
1411  if (user->chanvars) {
1412  ast_variables_destroy(user->chanvars);
1413  user->chanvars = NULL;
1414  }
1415 #endif
1416 
1417  for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
1418  if (!update_common_options(v, &user->options))
1419  continue;
1420  if (!strcasecmp(v->name, "context")) {
1421  ast_copy_string(user->context, v->value, sizeof(user->context));
1422  } else if (!strcasecmp(v->name, "secret")) {
1423  ast_copy_string(user->secret, v->value, sizeof(user->secret));
1424  } else if (!strcasecmp(v->name, "accountcode")) {
1425  ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
1426  } else if (!strcasecmp(v->name, "host")) {
1427  if (!strcasecmp(v->value, "dynamic")) {
1428  ast_log(LOG_ERROR, "A dynamic host on a type=user does not make any sense\n");
1430  return NULL;
1431  } else {
1432  struct ast_sockaddr tmp;
1433 
1434  tmp.ss.ss_family = AF_INET;
1435  if (ast_get_ip(&tmp, v->value)) {
1437  return NULL;
1438  }
1439  ast_sockaddr_to_sin(&tmp, &user->addr);
1440  }
1441  /* Let us know we need to use ip authentication */
1442  user->host = 1;
1443  } else if (!strcasecmp(v->name, "amaflags")) {
1444  format = ast_cdr_amaflags2int(v->value);
1445  if (format < 0) {
1446  ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
1447  } else {
1448  user->amaflags = format;
1449  }
1450  } else if (!strcasecmp(v->name, "permit") ||
1451  !strcasecmp(v->name, "deny")) {
1452  int ha_error = 0;
1453 
1454  user->ha = ast_append_ha(v->name, v->value, user->ha, &ha_error);
1455  if (ha_error)
1456  ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
1457  }
1458  }
1459  if (!user->options.dtmfmode)
1460  user->options.dtmfmode = global_options.dtmfmode;
1461  if (user->options.holdHandling == ~0)
1462  user->options.holdHandling = 0;
1463  else if (!user->options.holdHandling)
1464  user->options.holdHandling = global_options.holdHandling;
1465  ASTOBJ_UNMARK(user);
1466  ast_free_ha(oldha);
1467  return user;
1468 }
1469 
1470 static struct oh323_user *realtime_user(const call_details_t *cd)
1471 {
1472  struct ast_variable *var, *tmp;
1473  struct oh323_user *user;
1474  const char *username;
1475 
1476  if (userbyalias)
1477  var = ast_load_realtime("h323", "name", username = cd->call_source_aliases, SENTINEL);
1478  else {
1479  username = (char *)NULL;
1480  var = ast_load_realtime("h323", "host", cd->sourceIp, SENTINEL);
1481  }
1482 
1483  if (!var)
1484  return NULL;
1485 
1486  for (tmp = var; tmp; tmp = tmp->next) {
1487  if (!strcasecmp(tmp->name, "type") &&
1488  !(!strcasecmp(tmp->value, "user") || !strcasecmp(tmp->value, "friend"))) {
1489  ast_variables_destroy(var);
1490  return NULL;
1491  } else if (!username && !strcasecmp(tmp->name, "name"))
1492  username = tmp->value;
1493  }
1494 
1495  if (!username) {
1496  ast_log(LOG_WARNING, "Cannot determine user name for IP address %s\n", cd->sourceIp);
1497  ast_variables_destroy(var);
1498  return NULL;
1499  }
1500 
1501  user = build_user(username, var, NULL, 1);
1502 
1503  ast_variables_destroy(var);
1504 
1505  return user;
1506 }
1507 
1508 static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
1509 {
1510  struct oh323_peer *peer;
1511  struct ast_ha *oldha;
1512  int found = 0;
1513 
1514  peer = ASTOBJ_CONTAINER_FIND_UNLINK_FULL(&peerl, name, name, 0, 0, strcmp);
1515 
1516  if (peer)
1517  found++;
1518  else {
1519  if (!(peer = ast_calloc(1, sizeof(*peer))))
1520  return NULL;
1521  ASTOBJ_INIT(peer);
1522  }
1523  oldha = peer->ha;
1524  peer->ha = NULL;
1525  memcpy(&peer->options, &global_options, sizeof(peer->options));
1526  peer->options.dtmfmode = 0;
1527  peer->options.holdHandling = 0;
1528  peer->addr.sin_port = htons(h323_signalling_port);
1529  peer->addr.sin_family = AF_INET;
1530  if (!found && name)
1531  ast_copy_string(peer->name, name, sizeof(peer->name));
1532 
1533 #if 0 /* XXX Port channel variables functionality from chan_sip XXX */
1534  if (peer->chanvars) {
1535  ast_variables_destroy(peer->chanvars);
1536  peer->chanvars = NULL;
1537  }
1538 #endif
1539  /* Default settings for mailbox */
1540  peer->mailbox[0] = '\0';
1541 
1542  for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
1543  if (!update_common_options(v, &peer->options))
1544  continue;
1545  if (!strcasecmp(v->name, "host")) {
1546  if (!strcasecmp(v->value, "dynamic")) {
1547  ast_log(LOG_ERROR, "Dynamic host configuration not implemented.\n");
1549  return NULL;
1550  }
1551  {
1552  struct ast_sockaddr tmp;
1553 
1554  tmp.ss.ss_family = AF_INET;
1555  if (ast_get_ip(&tmp, v->value)) {
1556  ast_log(LOG_ERROR, "Could not determine IP for %s\n", v->value);
1558  return NULL;
1559  }
1560  ast_sockaddr_to_sin(&tmp, &peer->addr);
1561  }
1562  } else if (!strcasecmp(v->name, "port")) {
1563  peer->addr.sin_port = htons(atoi(v->value));
1564  } else if (!strcasecmp(v->name, "permit") ||
1565  !strcasecmp(v->name, "deny")) {
1566  int ha_error = 0;
1567 
1568  peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
1569  if (ha_error)
1570  ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
1571  } else if (!strcasecmp(v->name, "mailbox")) {
1572  ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
1573  } else if (!strcasecmp(v->name, "hasvoicemail")) {
1574  if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
1575  ast_copy_string(peer->mailbox, name, sizeof(peer->mailbox));
1576  }
1577  }
1578  }
1579  if (!peer->options.dtmfmode)
1580  peer->options.dtmfmode = global_options.dtmfmode;
1581  if (peer->options.holdHandling == ~0)
1582  peer->options.holdHandling = 0;
1583  else if (!peer->options.holdHandling)
1584  peer->options.holdHandling = global_options.holdHandling;
1585  ASTOBJ_UNMARK(peer);
1586  ast_free_ha(oldha);
1587  return peer;
1588 }
1589 
1590 static struct oh323_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
1591 {
1592  struct oh323_peer *peer;
1593  struct ast_variable *var;
1594  struct ast_variable *tmp;
1595  const char *addr = NULL;
1596 
1597  /* First check on peer name */
1598  if (peername)
1599  var = ast_load_realtime("h323", "name", peername, SENTINEL);
1600  else if (sin) /* Then check on IP address for dynamic peers */
1601  var = ast_load_realtime("h323", "host", addr = ast_inet_ntoa(sin->sin_addr), SENTINEL);
1602  else
1603  return NULL;
1604 
1605  if (!var)
1606  return NULL;
1607 
1608  for (tmp = var; tmp; tmp = tmp->next) {
1609  /* If this is type=user, then skip this object. */
1610  if (!strcasecmp(tmp->name, "type") &&
1611  !(!strcasecmp(tmp->value, "peer") || !strcasecmp(tmp->value, "friend"))) {
1612  ast_variables_destroy(var);
1613  return NULL;
1614  } else if (!peername && !strcasecmp(tmp->name, "name")) {
1615  peername = tmp->value;
1616  }
1617  }
1618 
1619  if (!peername) { /* Did not find peer in realtime */
1620  ast_log(LOG_WARNING, "Cannot determine peer name for IP address %s\n", addr);
1621  ast_variables_destroy(var);
1622  return NULL;
1623  }
1624 
1625  /* Peer found in realtime, now build it in memory */
1626  peer = build_peer(peername, var, NULL, 1);
1627 
1628  ast_variables_destroy(var);
1629 
1630  return peer;
1631 }
1632 
1633 static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
1634 {
1635  return strcmp(ast_inet_ntoa(inaddr), addr);
1636 }
1637 
1638 static struct oh323_user *find_user(const call_details_t *cd, int realtime)
1639 {
1640  struct oh323_user *u;
1641 
1642  if (userbyalias)
1643  u = ASTOBJ_CONTAINER_FIND(&userl, cd->call_source_aliases);
1644  else
1645  u = ASTOBJ_CONTAINER_FIND_FULL(&userl, cd->sourceIp, addr.sin_addr, 0, 0, oh323_addrcmp_str);
1646 
1647  if (!u && realtime)
1648  u = realtime_user(cd);
1649 
1650  if (!u && h323debug)
1651  ast_debug(1, "Could not find user by name %s or address %s\n", cd->call_source_aliases, cd->sourceIp);
1652 
1653  return u;
1654 }
1655 
1656 static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
1657 {
1658  int res;
1659 
1660  if (!sin)
1661  res = -1;
1662  else
1663  res = inaddrcmp(&addr , sin);
1664 
1665  return res;
1666 }
1667 
1668 static struct oh323_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
1669 {
1670  struct oh323_peer *p;
1671 
1672  if (peer)
1673  p = ASTOBJ_CONTAINER_FIND(&peerl, peer);
1674  else
1675  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, addr, 0, 0, oh323_addrcmp);
1676 
1677  if (!p && realtime)
1678  p = realtime_peer(peer, sin);
1679 
1680  if (!p && h323debug)
1681  ast_debug(1, "Could not find peer by name %s or address %s\n", (peer ? peer : "<NONE>"), (sin ? ast_inet_ntoa(sin->sin_addr) : "<NONE>"));
1682 
1683  return p;
1684 }
1685 
1686 static int create_addr(struct oh323_pvt *pvt, char *opeer)
1687 {
1688  struct hostent *hp;
1689  struct ast_hostent ahp;
1690  struct oh323_peer *p;
1691  int portno;
1692  int found = 0;
1693  char *port;
1694  char *hostn;
1695  char peer[256] = "";
1696 
1697  ast_copy_string(peer, opeer, sizeof(peer));
1698  port = strchr(peer, ':');
1699  if (port) {
1700  *port = '\0';
1701  port++;
1702  }
1703  pvt->sa.sin_family = AF_INET;
1704  p = find_peer(peer, NULL, 1);
1705  if (p) {
1706  found++;
1707  memcpy(&pvt->options, &p->options, sizeof(pvt->options));
1708  pvt->jointcapability = pvt->options.capability;
1709  if (pvt->options.dtmfmode) {
1710  if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
1712  } else {
1714  }
1715  }
1716  if (p->addr.sin_addr.s_addr) {
1717  pvt->sa.sin_addr = p->addr.sin_addr;
1718  pvt->sa.sin_port = p->addr.sin_port;
1719  }
1721  }
1722  if (!p && !found) {
1723  hostn = peer;
1724  if (port) {
1725  portno = atoi(port);
1726  } else {
1727  portno = h323_signalling_port;
1728  }
1729  hp = ast_gethostbyname(hostn, &ahp);
1730  if (hp) {
1731  memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
1732  pvt->sa.sin_port = htons(portno);
1733  /* Look peer by address */
1734  p = find_peer(NULL, &pvt->sa, 1);
1735  memcpy(&pvt->options, (p ? &p->options : &global_options), sizeof(pvt->options));
1736  pvt->jointcapability = pvt->options.capability;
1737  if (p) {
1739  }
1740  if (pvt->options.dtmfmode) {
1741  if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
1743  } else {
1745  }
1746  }
1747  return 0;
1748  } else {
1749  ast_log(LOG_WARNING, "No such host: %s\n", peer);
1750  return -1;
1751  }
1752  } else if (!found) {
1753  return -1;
1754  } else {
1755  return 0;
1756  }
1757 }
1758 static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
1759 {
1760  struct oh323_pvt *pvt;
1761  struct ast_channel *tmpc = NULL;
1762  char *dest = (char *)data;
1763  char *ext, *host;
1764  char *h323id = NULL;
1765  char tmp[256], tmp1[256];
1766 
1767  if (h323debug)
1768  ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), format), (char *)data);
1769 
1770  pvt = oh323_alloc(0);
1771  if (!pvt) {
1772  ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
1773  return NULL;
1774  }
1775  format &= AST_FORMAT_AUDIO_MASK;
1776  if (!format) {
1777  ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
1778  oh323_destroy(pvt);
1779  if (cause)
1781  return NULL;
1782  }
1783  ast_copy_string(tmp, dest, sizeof(tmp));
1784  host = strchr(tmp, '@');
1785  if (host) {
1786  *host = '\0';
1787  host++;
1788  ext = tmp;
1789  } else {
1790  ext = strrchr(tmp, '/');
1791  if (ext)
1792  *ext++ = '\0';
1793  host = tmp;
1794  }
1795  strtok_r(host, "/", &(h323id));
1796  if (!ast_strlen_zero(h323id)) {
1797  h323_set_id(h323id);
1798  }
1799  if (ext) {
1800  ast_copy_string(pvt->exten, ext, sizeof(pvt->exten));
1801  }
1802  if (h323debug)
1803  ast_debug(1, "Extension: %s Host: %s\n", pvt->exten, host);
1804 
1805  if (gatekeeper_disable) {
1806  if (create_addr(pvt, host)) {
1807  oh323_destroy(pvt);
1808  if (cause)
1810  return NULL;
1811  }
1812  }
1813  else {
1814  memcpy(&pvt->options, &global_options, sizeof(pvt->options));
1815  pvt->jointcapability = pvt->options.capability;
1816  if (pvt->options.dtmfmode) {
1817  if (pvt->options.dtmfmode & H323_DTMF_RFC2833) {
1819  } else {
1821  }
1822  }
1823  }
1824 
1826  /* Generate unique channel identifier */
1827  snprintf(tmp1, sizeof(tmp1)-1, "%s-%u", host, ++unique);
1828  tmp1[sizeof(tmp1)-1] = '\0';
1830 
1831  ast_mutex_lock(&pvt->lock);
1832  tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, requestor ? requestor->linkedid : NULL);
1833  ast_mutex_unlock(&pvt->lock);
1834  if (!tmpc) {
1835  oh323_destroy(pvt);
1836  if (cause)
1838  }
1840  restart_monitor();
1841  return tmpc;
1842 }
1843 
1844 /*! \brief Find a call by alias */
1845 static struct oh323_alias *find_alias(const char *source_aliases, int realtime)
1846 {
1847  struct oh323_alias *a;
1848 
1849  a = ASTOBJ_CONTAINER_FIND(&aliasl, source_aliases);
1850 
1851  if (!a && realtime)
1852  a = realtime_alias(source_aliases);
1853 
1854  return a;
1855 }
1856 
1857 /*! \brief
1858  * Callback for sending digits from H.323 up to asterisk
1859  *
1860  */
1861 static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
1862 {
1863  struct oh323_pvt *pvt;
1864  int res;
1865 
1866  pvt = find_call_locked(call_reference, token);
1867  if (!pvt) {
1868  ast_log(LOG_ERROR, "Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
1869  return -1;
1870  }
1871  if (h323debug)
1872  ast_log(LOG_DTMF, "Received %s digit '%c' (%u ms) for call %s\n", (digit == ' ' ? "update for" : "new"), (digit == ' ' ? pvt->curDTMF : digit), duration, token);
1873 
1874  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
1875  if (digit == '!')
1877  else {
1878  struct ast_frame f = {
1880  .subclass.integer = digit,
1881  .samples = duration * 8,
1882  .len = duration,
1883  .src = "SEND_DIGIT",
1884  };
1885  if (digit == ' ') { /* signalUpdate message */
1886  f.subclass.integer = pvt->curDTMF;
1887  AST_SCHED_DEL(sched, pvt->DTMFsched);
1888  } else { /* Regular input or signal message */
1889  if (pvt->DTMFsched >= 0) {
1890  /* We still don't send DTMF END from previous event, send it now */
1891  AST_SCHED_DEL(sched, pvt->DTMFsched);
1892  f.subclass.integer = pvt->curDTMF;
1893  f.samples = f.len = 0;
1894  ast_queue_frame(pvt->owner, &f);
1895  /* Restore values */
1896  f.subclass.integer = digit;
1897  f.samples = duration * 8;
1898  f.len = duration;
1899  }
1900  if (duration) { /* This is a signal, signalUpdate follows */
1902  pvt->DTMFsched = ast_sched_add(sched, duration, oh323_simulate_dtmf_end, pvt);
1903  if (h323debug)
1904  ast_log(LOG_DTMF, "Scheduled DTMF END simulation for %d ms, id=%d\n", duration, pvt->DTMFsched);
1905  }
1906  pvt->curDTMF = digit;
1907  }
1908  res = ast_queue_frame(pvt->owner, &f);
1909  }
1910  ast_channel_unlock(pvt->owner);
1911  } else {
1912  if (digit == '!')
1914  else {
1915  pvt->newduration = duration;
1916  pvt->newdigit = digit;
1917  }
1918  res = 0;
1919  }
1920  ast_mutex_unlock(&pvt->lock);
1921  return res;
1922 }
1923 
1924 /*! \brief
1925  * Callback function used to inform the H.323 stack of the local rtp ip/port details
1926  *
1927  * \return Returns the local RTP information
1928  */
1929 static struct rtp_info *external_rtp_create(unsigned call_reference, const char * token)
1930 {
1931  struct oh323_pvt *pvt;
1932  struct sockaddr_in us;
1933  struct rtp_info *info;
1934 
1935  info = ast_calloc(1, sizeof(*info));
1936  if (!info) {
1937  ast_log(LOG_ERROR, "Unable to allocated info structure, this is very bad\n");
1938  return NULL;
1939  }
1940  pvt = find_call_locked(call_reference, token);
1941  if (!pvt) {
1942  ast_free(info);
1943  ast_log(LOG_ERROR, "Unable to find call %s(%d)\n", token, call_reference);
1944  return NULL;
1945  }
1946  if (!pvt->rtp)
1947  __oh323_rtp_create(pvt);
1948  if (!pvt->rtp) {
1949  ast_mutex_unlock(&pvt->lock);
1950  ast_free(info);
1951  ast_log(LOG_ERROR, "No RTP stream is available for call %s (%d)", token, call_reference);
1952  return NULL;
1953  }
1954  /* figure out our local RTP port and tell the H.323 stack about it */
1955  {
1956  struct ast_sockaddr tmp;
1957 
1959  ast_sockaddr_to_sin(&tmp, &us);
1960  }
1961  ast_mutex_unlock(&pvt->lock);
1962 
1963  ast_copy_string(info->addr, ast_inet_ntoa(us.sin_addr), sizeof(info->addr));
1964  info->port = ntohs(us.sin_port);
1965  if (h323debug)
1966  ast_debug(1, "Sending RTP 'US' %s:%d\n", info->addr, info->port);
1967  return info;
1968 }
1969 
1970 /*! \brief
1971  * Call-back function passing remote ip/port information from H.323 to asterisk
1972  *
1973  * Returns nothing
1974  */
1975 static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
1976 {
1977  struct oh323_pvt *pvt;
1978  struct sockaddr_in them;
1979  int nativeformats_changed;
1980  enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
1981 
1982  if (h323debug)
1983  ast_debug(1, "Setting up RTP connection for %s\n", token);
1984 
1985  /* Find the call or allocate a private structure if call not found */
1986  pvt = find_call_locked(call_reference, token);
1987  if (!pvt) {
1988  ast_log(LOG_ERROR, "Something is wrong: rtp\n");
1989  return;
1990  }
1991  if (pvt->alreadygone) {
1992  ast_mutex_unlock(&pvt->lock);
1993  return;
1994  }
1995 
1996  if (!pvt->rtp)
1997  __oh323_rtp_create(pvt);
1998 
1999  if ((pt == 2) && (pvt->jointcapability & AST_FORMAT_G726_AAL2)) {
2001  }
2002 
2003  them.sin_family = AF_INET;
2004  /* only works for IPv4 */
2005  them.sin_addr.s_addr = inet_addr(remoteIp);
2006  them.sin_port = htons(remotePort);
2007 
2008  if (them.sin_addr.s_addr) {
2009  {
2010  struct ast_sockaddr tmp;
2011 
2012  ast_sockaddr_from_sin(&tmp, &them);
2014  }
2015  if (pvt->recvonly) {
2016  pvt->recvonly = 0;
2017  rtp_change = NEED_UNHOLD;
2018  }
2019  } else {
2020  ast_rtp_instance_stop(pvt->rtp);
2021  if (!pvt->recvonly) {
2022  pvt->recvonly = 1;
2023  rtp_change = NEED_HOLD;
2024  }
2025  }
2026 
2027  /* Change native format to reflect information taken from OLC/OLCAck */
2028  nativeformats_changed = 0;
2029  if (pt != 128 && pvt->rtp) { /* Payload type is invalid, so try to use previously decided */
2031  if (h323debug)
2032  ast_debug(1, "Native format is set to %llu from %d by RTP payload type %d\n", (unsigned long long) rtptype.code, pvt->nativeformats, pt);
2033  if (pvt->nativeformats != rtptype.code) {
2034  pvt->nativeformats = rtptype.code;
2035  nativeformats_changed = 1;
2036  }
2037  } else if (h323debug)
2038  ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
2039 
2040  /* Don't try to lock the channel if nothing changed */
2041  if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
2042  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
2043  /* Re-build translation path only if native format(s) has been changed */
2044  if (pvt->owner->nativeformats != pvt->nativeformats) {
2045  if (h323debug) {
2046  char tmp[256], tmp2[256];
2047  ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(pvt->owner->readformat), ast_getformatname(pvt->owner->writeformat));
2048  }
2049  pvt->owner->nativeformats = pvt->nativeformats;
2052  }
2053  if (pvt->options.progress_audio)
2055  switch (rtp_change) {
2056  case NEED_HOLD:
2058  break;
2059  case NEED_UNHOLD:
2061  break;
2062  default:
2063  break;
2064  }
2065  ast_channel_unlock(pvt->owner);
2066  }
2067  else {
2068  if (pvt->options.progress_audio)
2070  else if (rtp_change == NEED_HOLD)
2072  else if (rtp_change == NEED_UNHOLD)
2074  if (h323debug)
2075  ast_debug(1, "RTP connection preparation for %s is pending...\n", token);
2076  }
2077  }
2078  ast_mutex_unlock(&pvt->lock);
2079 
2080  if (h323debug)
2081  ast_debug(1, "RTP connection prepared for %s\n", token);
2082 
2083  return;
2084 }
2085 
2086 /*! \brief
2087  * Call-back function to signal asterisk that the channel has been answered
2088  * Returns nothing
2089  */
2090 static void connection_made(unsigned call_reference, const char *token)
2091 {
2092  struct oh323_pvt *pvt;
2093 
2094  if (h323debug)
2095  ast_debug(1, "Call %s answered\n", token);
2096 
2097  pvt = find_call_locked(call_reference, token);
2098  if (!pvt) {
2099  ast_log(LOG_ERROR, "Something is wrong: connection\n");
2100  return;
2101  }
2102 
2103  /* Inform asterisk about remote party connected only on outgoing calls */
2104  if (!pvt->outgoing) {
2105  ast_mutex_unlock(&pvt->lock);
2106  return;
2107  }
2108  /* Do not send ANSWER message more than once */
2109  if (!pvt->connection_established) {
2110  pvt->connection_established = 1;
2111  update_state(pvt, -1, AST_CONTROL_ANSWER);
2112  }
2113  ast_mutex_unlock(&pvt->lock);
2114  return;
2115 }
2116 
2117 static int progress(unsigned call_reference, const char *token, int inband)
2118 {
2119  struct oh323_pvt *pvt;
2120 
2121  if (h323debug)
2122  ast_debug(1, "Received ALERT/PROGRESS message for %s tones\n", (inband ? "inband" : "self-generated"));
2123 
2124  pvt = find_call_locked(call_reference, token);
2125  if (!pvt) {
2126  ast_log(LOG_ERROR, "Private structure not found in progress.\n");
2127  return -1;
2128  }
2129  if (!pvt->owner) {
2130  ast_mutex_unlock(&pvt->lock);
2131  ast_log(LOG_ERROR, "No Asterisk channel associated with private structure.\n");
2132  return -1;
2133  }
2134  update_state(pvt, -1, (inband ? AST_CONTROL_PROGRESS : AST_CONTROL_RINGING));
2135  ast_mutex_unlock(&pvt->lock);
2136 
2137  return 0;
2138 }
2139 
2140 /*! \brief
2141  * Call-back function for incoming calls
2142  *
2143  * Returns 1 on success
2144  */
2145 static call_options_t *setup_incoming_call(call_details_t *cd)
2146 {
2147  struct oh323_pvt *pvt;
2148  struct oh323_user *user = NULL;
2149  struct oh323_alias *alias = NULL;
2150 
2151  if (h323debug)
2152  ast_debug(1, "Setting up incoming call for %s\n", cd->call_token);
2153 
2154  /* allocate the call*/
2155  pvt = oh323_alloc(cd->call_reference);
2156 
2157  if (!pvt) {
2158  ast_log(LOG_ERROR, "Unable to allocate private structure, this is bad.\n");
2160  return NULL;
2161  }
2162 
2163  /* Populate the call details in the private structure */
2164  memcpy(&pvt->cd, cd, sizeof(pvt->cd));
2165  memcpy(&pvt->options, &global_options, sizeof(pvt->options));
2166  pvt->jointcapability = pvt->options.capability;
2167 
2168  if (h323debug) {
2169  ast_verb(3, "Setting up Call\n");
2170  ast_verb(3, " \tCall token: [%s]\n", pvt->cd.call_token);
2171  ast_verb(3, " \tCalling party name: [%s]\n", pvt->cd.call_source_name);
2172  ast_verb(3, " \tCalling party number: [%s]\n", pvt->cd.call_source_e164);
2173  ast_verb(3, " \tCalled party name: [%s]\n", pvt->cd.call_dest_alias);
2174  ast_verb(3, " \tCalled party number: [%s]\n", pvt->cd.call_dest_e164);
2175  if (pvt->cd.redirect_reason >= 0)
2176  ast_verb(3, " \tRedirecting party number: [%s] (reason %d)\n", pvt->cd.redirect_number, pvt->cd.redirect_reason);
2177  ast_verb(3, " \tCalling party IP: [%s]\n", pvt->cd.sourceIp);
2178  }
2179 
2180  /* Decide if we are allowing Gatekeeper routed calls*/
2181  if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
2182  if (!ast_strlen_zero(cd->call_dest_e164)) {
2183  ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
2184  ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
2185  } else {
2186  alias = find_alias(cd->call_dest_alias, 1);
2187  if (!alias) {
2188  ast_log(LOG_ERROR, "Call for %s rejected, alias not found\n", cd->call_dest_alias);
2189  oh323_destroy(pvt);
2190  return NULL;
2191  }
2192  ast_copy_string(pvt->exten, alias->name, sizeof(pvt->exten));
2193  ast_copy_string(pvt->context, alias->context, sizeof(pvt->context));
2194  }
2195  } else {
2196  /* Either this call is not from the Gatekeeper
2197  or we are not allowing gk routed calls */
2198  user = find_user(cd, 1);
2199  if (!user) {
2200  if (!acceptAnonymous) {
2201  ast_log(LOG_NOTICE, "Anonymous call from '%s@%s' rejected\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
2202  oh323_destroy(pvt);
2203  return NULL;
2204  }
2205  if (ast_strlen_zero(default_context)) {
2206  ast_log(LOG_ERROR, "Call from '%s@%s' rejected due to no default context\n", pvt->cd.call_source_aliases, pvt->cd.sourceIp);
2207  oh323_destroy(pvt);
2208  return NULL;
2209  }
2210  ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
2211  if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
2212  ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
2213  } else {
2214  ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
2215  }
2216  if (h323debug)
2217  ast_debug(1, "Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->context, pvt->exten);
2218  } else {
2219  if (user->host) {
2220  if (strcasecmp(cd->sourceIp, ast_inet_ntoa(user->addr.sin_addr))) {
2221  if (ast_strlen_zero(user->context)) {
2222  if (ast_strlen_zero(default_context)) {
2223  ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s) and no default context\n", user->name, cd->sourceIp);
2224  oh323_destroy(pvt);
2226  return NULL;
2227  }
2228  ast_copy_string(pvt->context, default_context, sizeof(pvt->context));
2229  } else {
2230  ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
2231  }
2232  pvt->exten[0] = 'i';
2233  pvt->exten[1] = '\0';
2234  ast_log(LOG_ERROR, "Call from '%s' rejected due to non-matching IP address (%s)s\n", user->name, cd->sourceIp);
2235  oh323_destroy(pvt);
2237  return NULL; /* XXX: Hmmm... Why to setup context if we drop connection immediately??? */
2238  }
2239  }
2240  ast_copy_string(pvt->context, user->context, sizeof(pvt->context));
2241  memcpy(&pvt->options, &user->options, sizeof(pvt->options));
2242  pvt->jointcapability = pvt->options.capability;
2243  if (!ast_strlen_zero(pvt->cd.call_dest_e164)) {
2244  ast_copy_string(pvt->exten, cd->call_dest_e164, sizeof(pvt->exten));
2245  } else {
2246  ast_copy_string(pvt->exten, cd->call_dest_alias, sizeof(pvt->exten));
2247  }
2248  if (!ast_strlen_zero(user->accountcode)) {
2249  ast_copy_string(pvt->accountcode, user->accountcode, sizeof(pvt->accountcode));
2250  }
2251  if (user->amaflags) {
2252  pvt->amaflags = user->amaflags;
2253  }
2255  }
2256  }
2257  return &pvt->options;
2258 }
2259 
2260 /*! \brief
2261  * Call-back function to start PBX when OpenH323 ready to serve incoming call
2262  *
2263  * Returns 1 on success
2264  */
2265 static int answer_call(unsigned call_reference, const char *token)
2266 {
2267  struct oh323_pvt *pvt;
2268  struct ast_channel *c = NULL;
2269  enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
2270  char tmp_exten[sizeof(pvt->exten)];
2271 
2272  if (h323debug)
2273  ast_debug(1, "Preparing Asterisk to answer for %s\n", token);
2274 
2275  /* Find the call or allocate a private structure if call not found */
2276  pvt = find_call_locked(call_reference, token);
2277  if (!pvt) {
2278  ast_log(LOG_ERROR, "Something is wrong: answer_call\n");
2279  return 0;
2280  }
2281  /* Check if requested extension@context pair exists in the dialplan */
2282  ast_copy_string(tmp_exten, pvt->exten, sizeof(tmp_exten));
2283 
2284  /* Try to find best extension in specified context */
2285  if ((tmp_exten[0] != '\0') && (tmp_exten[1] == '\0')) {
2286  if (tmp_exten[0] == 's')
2287  try_exten = ext_s;
2288  else if (tmp_exten[0] == 'i')
2289  try_exten = ext_i;
2290  else
2291  try_exten = ext_original;
2292  } else
2293  try_exten = ext_original;
2294  do {
2295  if (ast_exists_extension(NULL, pvt->context, tmp_exten, 1, NULL))
2296  break;
2297  switch (try_exten) {
2298  case ext_original:
2299  tmp_exten[0] = 's';
2300  tmp_exten[1] = '\0';
2301  try_exten = ext_s;
2302  break;
2303  case ext_s:
2304  tmp_exten[0] = 'i';
2305  try_exten = ext_i;
2306  break;
2307  case ext_i:
2308  try_exten = ext_notexists;
2309  break;
2310  default:
2311  break;
2312  }
2313  } while (try_exten != ext_notexists);
2314 
2315  /* Drop the call if we don't have <exten>, s and i extensions */
2316  if (try_exten == ext_notexists) {
2317  ast_log(LOG_NOTICE, "Dropping call because extensions '%s', 's' and 'i' doesn't exists in context [%s]\n", pvt->exten, pvt->context);
2318  ast_mutex_unlock(&pvt->lock);
2319  h323_clear_call(token, AST_CAUSE_UNALLOCATED);
2320  return 0;
2321  } else if ((try_exten != ext_original) && (strcmp(pvt->exten, tmp_exten) != 0)) {
2322  if (h323debug)
2323  ast_debug(1, "Going to extension %s@%s because %s@%s isn't exists\n", tmp_exten, pvt->context, pvt->exten, pvt->context);
2324  ast_copy_string(pvt->exten, tmp_exten, sizeof(pvt->exten));
2325  }
2326 
2327  /* allocate a channel and tell asterisk about it */
2328  c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL);
2329 
2330  /* And release when done */
2331  ast_mutex_unlock(&pvt->lock);
2332  if (!c) {
2333  ast_log(LOG_ERROR, "Couldn't create channel. This is bad\n");
2334  return 0;
2335  }
2336  return 1;
2337 }
2338 
2339 /*! \brief
2340  * Call-back function to establish an outgoing H.323 call
2341  *
2342  * Returns 1 on success
2343  */
2344 static int setup_outgoing_call(call_details_t *cd)
2345 {
2346  /* Use argument here or free it immediately */
2348 
2349  return 1;
2350 }
2351 
2352 /*! \brief
2353  * Call-back function to signal asterisk that the channel is ringing
2354  * Returns nothing
2355  */
2356 static void chan_ringing(unsigned call_reference, const char *token)
2357 {
2358  struct oh323_pvt *pvt;
2359 
2360  if (h323debug)
2361  ast_debug(1, "Ringing on %s\n", token);
2362 
2363  pvt = find_call_locked(call_reference, token);
2364  if (!pvt) {
2365  ast_log(LOG_ERROR, "Something is wrong: ringing\n");
2366  return;
2367  }
2368  if (!pvt->owner) {
2369  ast_mutex_unlock(&pvt->lock);
2370  ast_log(LOG_ERROR, "Channel has no owner\n");
2371  return;
2372  }
2374  ast_mutex_unlock(&pvt->lock);
2375  return;
2376 }
2377 
2378 /*! \brief
2379  * Call-back function to cleanup communication
2380  * Returns nothing,
2381  */
2382 static void cleanup_connection(unsigned call_reference, const char *call_token)
2383 {
2384  struct oh323_pvt *pvt;
2385 
2386  if (h323debug)
2387  ast_debug(1, "Cleaning connection to %s\n", call_token);
2388 
2389  while (1) {
2390  pvt = find_call_locked(call_reference, call_token);
2391  if (!pvt) {
2392  if (h323debug)
2393  ast_debug(1, "No connection for %s\n", call_token);
2394  return;
2395  }
2396  if (!pvt->owner || !ast_channel_trylock(pvt->owner))
2397  break;
2398 #if 1
2399  ast_log(LOG_NOTICE, "Avoiding H.323 destory deadlock on %s\n", call_token);
2400 #ifdef DEBUG_THREADS
2401  /* XXX to be completed
2402  * If we want to print more info on who is holding the lock,
2403  * implement the relevant code in lock.h and use the routines
2404  * supplied there.
2405  */
2406 #endif
2407 #endif
2408  ast_mutex_unlock(&pvt->lock);
2409  usleep(1);
2410  }
2411  if (pvt->rtp) {
2412  /* Immediately stop RTP */
2414  pvt->rtp = NULL;
2415  }
2416  /* Free dsp used for in-band DTMF detection */
2417  if (pvt->vad) {
2418  ast_dsp_free(pvt->vad);
2419  pvt->vad = NULL;
2420  }
2421  cleanup_call_details(&pvt->cd);
2422  pvt->alreadygone = 1;
2423  /* Send hangup */
2424  if (pvt->owner) {
2426  ast_queue_hangup(pvt->owner);
2427  ast_channel_unlock(pvt->owner);
2428  }
2429  ast_mutex_unlock(&pvt->lock);
2430  if (h323debug)
2431  ast_debug(1, "Connection to %s cleaned\n", call_token);
2432  return;
2433 }
2434 
2435 static void hangup_connection(unsigned int call_reference, const char *token, int cause)
2436 {
2437  struct oh323_pvt *pvt;
2438 
2439  if (h323debug)
2440  ast_debug(1, "Hanging up connection to %s with cause %d\n", token, cause);
2441 
2442  pvt = find_call_locked(call_reference, token);
2443  if (!pvt) {
2444  if (h323debug)
2445  ast_debug(1, "Connection to %s already cleared\n", token);
2446  return;
2447  }
2448  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
2450  pvt->owner->hangupcause = pvt->hangupcause = cause;
2451  ast_queue_hangup_with_cause(pvt->owner, cause);
2452  ast_channel_unlock(pvt->owner);
2453  }
2454  else {
2455  pvt->needhangup = 1;
2456  pvt->hangupcause = cause;
2457  if (h323debug)
2458  ast_debug(1, "Hangup for %s is pending\n", token);
2459  }
2460  ast_mutex_unlock(&pvt->lock);
2461 }
2462 
2463 static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
2464 {
2465  struct oh323_pvt *pvt;
2466 
2467  if (h323debug)
2468  ast_debug(1, "Setting %s DTMF payload to %d on %s\n", (is_cisco ? "Cisco" : "RFC2833"), payload, token);
2469 
2470  pvt = find_call_locked(call_reference, token);
2471  if (!pvt) {
2472  return;
2473  }
2474  if (pvt->rtp) {
2475  ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(pvt->rtp), pvt->rtp, payload, "audio", (is_cisco ? "cisco-telephone-event" : "telephone-event"), 0);
2476  }
2477  pvt->dtmf_pt[is_cisco ? 1 : 0] = payload;
2478  ast_mutex_unlock(&pvt->lock);
2479  if (h323debug)
2480  ast_debug(1, "DTMF payload on %s set to %d\n", token, payload);
2481 }
2482 
2483 static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
2484 {
2485  struct oh323_pvt *pvt;
2486 
2487  if (h323debug)
2488  ast_debug(1, "Got remote capabilities from connection %s\n", token);
2489 
2490  pvt = find_call_locked(call_reference, token);
2491  if (!pvt)
2492  return;
2494  pvt->jointcapability = pvt->options.capability & capabilities;
2495  if (prefs) {
2496  memcpy(&pvt->peer_prefs, prefs, sizeof(pvt->peer_prefs));
2497  if (h323debug) {
2498  int i;
2499  for (i = 0; i < 32; ++i) {
2500  if (!prefs->order[i])
2501  break;
2502  ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
2503  }
2504  }
2505  if (pvt->rtp) {
2506  if (pvt->options.autoframing) {
2507  ast_debug(2, "Autoframing option set, using peer's packetization settings\n");
2509  } else {
2510  ast_debug(2, "Autoframing option not set, ignoring peer's packetization settings\n");
2512  }
2513  }
2514  }
2515  ast_mutex_unlock(&pvt->lock);
2516 }
2517 
2518 static void set_local_capabilities(unsigned call_reference, const char *token)
2519 {
2520  struct oh323_pvt *pvt;
2522  struct ast_codec_pref prefs;
2523 
2524  if (h323debug)
2525  ast_debug(1, "Setting capabilities for connection %s\n", token);
2526 
2527  pvt = find_call_locked(call_reference, token);
2528  if (!pvt)
2529  return;
2530  capability = (pvt->jointcapability) ? pvt->jointcapability : pvt->options.capability;
2531  dtmfmode = pvt->options.dtmfmode;
2532  prefs = pvt->options.prefs;
2533  pref_codec = pvt->pref_codec;
2534  ast_mutex_unlock(&pvt->lock);
2535  h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
2536 
2537  if (h323debug) {
2538  int i;
2539  for (i = 0; i < 32; i++) {
2540  if (!prefs.order[i])
2541  break;
2542  ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(1 << (prefs.order[i]-1)) : "<none>"), prefs.framing[i]);
2543  }
2544  ast_debug(1, "Capabilities for connection %s is set\n", token);
2545  }
2546 }
2547 
2548 static void remote_hold(unsigned call_reference, const char *token, int is_hold)
2549 {
2550  struct oh323_pvt *pvt;
2551 
2552  if (h323debug)
2553  ast_debug(1, "Setting %shold status for connection %s\n", (is_hold ? "" : "un"), token);
2554 
2555  pvt = find_call_locked(call_reference, token);
2556  if (!pvt)
2557  return;
2558  if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
2559  if (is_hold)
2561  else
2563  ast_channel_unlock(pvt->owner);
2564  }
2565  else {
2566  if (is_hold)
2568  else
2570  }
2571  ast_mutex_unlock(&pvt->lock);
2572 }
2573 
2574 static void *do_monitor(void *data)
2575 {
2576  int res;
2577  int reloading;
2578  struct oh323_pvt *oh323 = NULL;
2579 
2580  for(;;) {
2581  /* Check for a reload request */
2583  reloading = h323_reloading;
2584  h323_reloading = 0;
2586  if (reloading) {
2587  ast_verb(1, "Reloading H.323\n");
2588  h323_do_reload();
2589  }
2590  /* Check for interfaces needing to be killed */
2591  if (!ast_mutex_trylock(&iflock)) {
2592 #if 1
2593  do {
2594  for (oh323 = iflist; oh323; oh323 = oh323->next) {
2595  if (!ast_mutex_trylock(&oh323->lock)) {
2596  if (oh323->needdestroy) {
2597  __oh323_destroy(oh323);
2598  break;
2599  }
2600  ast_mutex_unlock(&oh323->lock);
2601  }
2602  }
2603  } while (/*oh323*/ 0);
2604 #else
2605 restartsearch:
2606  oh323 = iflist;
2607  while(oh323) {
2608  if (!ast_mutex_trylock(&oh323->lock)) {
2609  if (oh323->needdestroy) {
2610  __oh323_destroy(oh323);
2611  goto restartsearch;
2612  }
2613  ast_mutex_unlock(&oh323->lock);
2614  oh323 = oh323->next;
2615  }
2616  }
2617 #endif
2619  } else
2620  oh323 = (struct oh323_pvt *)1; /* Force fast loop */
2621  pthread_testcancel();
2622  /* Wait for sched or io */
2623  res = ast_sched_wait(sched);
2624  if ((res < 0) || (res > 1000)) {
2625  res = 1000;
2626  }
2627  /* Do not wait if some channel(s) is destroyed, probably, more available too */
2628  if (oh323)
2629  res = 1;
2630  res = ast_io_wait(io, res);
2631  pthread_testcancel();
2633  if (res >= 0) {
2634  ast_sched_runq(sched);
2635  }
2637  }
2638  /* Never reached */
2639  return NULL;
2640 }
2641 
2642 static int restart_monitor(void)
2643 {
2644  /* If we're supposed to be stopped -- stay stopped */
2645  if (ast_mutex_lock(&monlock)) {
2646  ast_log(LOG_WARNING, "Unable to lock monitor\n");
2647  return -1;
2648  }
2649  if (monitor_thread == AST_PTHREADT_STOP) {
2651  return 0;
2652  }
2653  if (monitor_thread == pthread_self()) {
2655  ast_log(LOG_WARNING, "Cannot kill myself\n");
2656  return -1;
2657  }
2658  if (monitor_thread && (monitor_thread != AST_PTHREADT_NULL)) {
2659  /* Wake up the thread */
2660  pthread_kill(monitor_thread, SIGURG);
2661  } else {
2662  /* Start a new monitor */
2663  if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
2664  monitor_thread = AST_PTHREADT_NULL;
2666  ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
2667  return -1;
2668  }
2669  }
2671  return 0;
2672 }
2673 
2674 static char *handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2675 {
2676  switch (cmd) {
2677  case CLI_INIT:
2678  e->command = "h323 set trace [on|off]";
2679  e->usage =
2680  "Usage: h323 set trace (on|off|<trace level>)\n"
2681  " Enable/Disable H.323 stack tracing for debugging purposes\n";
2682  return NULL;
2683  case CLI_GENERATE:
2684  return NULL;
2685  }
2686 
2687  if (a->argc != e->args)
2688  return CLI_SHOWUSAGE;
2689  if (!strcasecmp(a->argv[3], "off")) {
2690  h323_debug(0, 0);
2691  ast_cli(a->fd, "H.323 Trace Disabled\n");
2692  } else if (!strcasecmp(a->argv[3], "on")) {
2693  h323_debug(1, 1);
2694  ast_cli(a->fd, "H.323 Trace Enabled\n");
2695  } else {
2696  int tracelevel = atoi(a->argv[3]);
2697  h323_debug(1, tracelevel);
2698  ast_cli(a->fd, "H.323 Trace Enabled (Trace Level: %d)\n", tracelevel);
2699  }
2700  return CLI_SUCCESS;
2701 }
2702 
2703 static char *handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2704 {
2705  switch (cmd) {
2706  case CLI_INIT:
2707  e->command = "h323 set debug [on|off]";
2708  e->usage =
2709  "Usage: h323 set debug [on|off]\n"
2710  " Enable/Disable H.323 debugging output\n";
2711  return NULL;
2712  case CLI_GENERATE:
2713  return NULL;
2714  }
2715 
2716  if (a->argc != e->args)
2717  return CLI_SHOWUSAGE;
2718  if (strcasecmp(a->argv[3], "on") && strcasecmp(a->argv[3], "off"))
2719  return CLI_SHOWUSAGE;
2720 
2721  h323debug = (strcasecmp(a->argv[3], "on")) ? 0 : 1;
2722  ast_cli(a->fd, "H.323 Debugging %s\n", h323debug ? "Enabled" : "Disabled");
2723  return CLI_SUCCESS;
2724 }
2725 
2726 static char *handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2727 {
2728  switch (cmd) {
2729  case CLI_INIT:
2730  e->command = "h323 cycle gk";
2731  e->usage =
2732  "Usage: h323 cycle gk\n"
2733  " Manually re-register with the Gatekeper (Currently Disabled)\n";
2734  return NULL;
2735  case CLI_GENERATE:
2736  return NULL;
2737  }
2738 
2739  if (a->argc != 3)
2740  return CLI_SHOWUSAGE;
2741 
2742  h323_gk_urq();
2743 
2744  /* Possibly register with a GK */
2745  if (!gatekeeper_disable) {
2746  if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
2747  ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
2748  }
2749  }
2750  return CLI_SUCCESS;
2751 }
2752 
2753 static char *handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2754 {
2755  switch (cmd) {
2756  case CLI_INIT:
2757  e->command = "h323 hangup";
2758  e->usage =
2759  "Usage: h323 hangup <token>\n"
2760  " Manually try to hang up the call identified by <token>\n";
2761  return NULL;
2762  case CLI_GENERATE:
2763  return NULL;
2764  }
2765 
2766  if (a->argc != 3)
2767  return CLI_SHOWUSAGE;
2768  if (h323_soft_hangup(a->argv[2])) {
2769  ast_verb(3, "Hangup succeeded on %s\n", a->argv[2]);
2770  } else {
2771  ast_verb(3, "Hangup failed for %s\n", a->argv[2]);
2772  }
2773  return CLI_SUCCESS;
2774 }
2775 
2776 static char *handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2777 {
2778  switch (cmd) {
2779  case CLI_INIT:
2780  e->command = "h323 show tokens";
2781  e->usage =
2782  "Usage: h323 show tokens\n"
2783  " Print out all active call tokens\n";
2784  return NULL;
2785  case CLI_GENERATE:
2786  return NULL;
2787  }
2788 
2789  if (a->argc != 3)
2790  return CLI_SHOWUSAGE;
2791 
2792  h323_show_tokens();
2793 
2794  return CLI_SUCCESS;
2795 }
2796 
2797 static char *handle_cli_h323_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2798 {
2799  switch (cmd) {
2800  case CLI_INIT:
2801  e->command = "h323 show version";
2802  e->usage =
2803  "Usage: h323 show version\n"
2804  " Show the version of the H.323 library in use\n";
2805  return NULL;
2806  case CLI_GENERATE:
2807  return NULL;
2808  }
2809 
2810  if (a->argc != 3)
2811  return CLI_SHOWUSAGE;
2812 
2813  h323_show_version();
2814 
2815  return CLI_SUCCESS;
2816 }
2817 
2818 static struct ast_cli_entry cli_h323[] = {
2819  AST_CLI_DEFINE(handle_cli_h323_set_trace, "Enable/Disable H.323 Stack Tracing"),
2820  AST_CLI_DEFINE(handle_cli_h323_set_debug, "Enable/Disable H.323 Debugging"),
2821  AST_CLI_DEFINE(handle_cli_h323_cycle_gk, "Manually re-register with the Gatekeper"),
2822  AST_CLI_DEFINE(handle_cli_h323_hangup, "Manually try to hang up a call"),
2823  AST_CLI_DEFINE(handle_cli_h323_show_tokens, "Show all active call tokens"),
2824  AST_CLI_DEFINE(handle_cli_h323_show_version, "Show the version of the H.323 library in use"),
2825 };
2826 
2827 static void delete_users(void)
2828 {
2829  int pruned = 0;
2830 
2831  /* Delete all users */
2834  ASTOBJ_RDLOCK(iterator);
2835  ASTOBJ_MARK(iterator);
2836  ++pruned;
2837  ASTOBJ_UNLOCK(iterator);
2838  } while (0) );
2839  if (pruned) {
2841  }
2843 
2846  ASTOBJ_RDLOCK(iterator);
2847  ASTOBJ_MARK(iterator);
2848  ASTOBJ_UNLOCK(iterator);
2849  } while (0) );
2851 }
2852 
2853 static void delete_aliases(void)
2854 {
2855  int pruned = 0;
2856 
2857  /* Delete all aliases */
2860  ASTOBJ_RDLOCK(iterator);
2861  ASTOBJ_MARK(iterator);
2862  ++pruned;
2863  ASTOBJ_UNLOCK(iterator);
2864  } while (0) );
2865  if (pruned) {
2867  }
2869 }
2870 
2871 static void prune_peers(void)
2872 {
2873  /* Prune peers who still are supposed to be deleted */
2875 }
2876 
2877 static int reload_config(int is_reload)
2878 {
2879  struct ast_config *cfg, *ucfg;
2880  struct ast_variable *v;
2881  struct oh323_peer *peer = NULL;
2882  struct oh323_user *user = NULL;
2883  struct oh323_alias *alias = NULL;
2884  struct ast_hostent ahp; struct hostent *hp;
2885  char *cat;
2886  const char *utype;
2887  int is_user, is_peer, is_alias;
2888  char _gatekeeper[100];
2889  int gk_discover, gk_disable, gk_changed;
2890  struct ast_flags config_flags = { is_reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2891 
2892  cfg = ast_config_load(config, config_flags);
2893 
2894  /* We *must* have a config file otherwise stop immediately */
2895  if (!cfg) {
2896  ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
2897  return 1;
2898  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
2899  ucfg = ast_config_load("users.conf", config_flags);
2900  if (ucfg == CONFIG_STATUS_FILEUNCHANGED) {
2901  return 0;
2902  } else if (ucfg == CONFIG_STATUS_FILEINVALID) {
2903  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
2904  return 0;
2905  }
2906  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
2907  if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
2908  ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
2909  ast_config_destroy(ucfg);
2910  return 0;
2911  }
2912  } else if (cfg == CONFIG_STATUS_FILEINVALID) {
2913  ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);
2914  return 0;
2915  } else {
2916  ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
2917  if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
2918  ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
2919  ast_config_destroy(cfg);
2920  return 0;
2921  }
2922  }
2923 
2924  if (is_reload) {
2925  delete_users();
2926  delete_aliases();
2927  prune_peers();
2928  }
2929 
2930  /* fire up the H.323 Endpoint */
2931  if (!h323_end_point_exist()) {
2932  h323_end_point_create();
2933  }
2934  ast_copy_string(_gatekeeper, gatekeeper, sizeof(_gatekeeper));
2935  gk_discover = gatekeeper_discover;
2936  gk_disable = gatekeeper_disable;
2937  memset(&bindaddr, 0, sizeof(bindaddr));
2938  memset(&global_options, 0, sizeof(global_options));
2939  global_options.fastStart = 1;
2940  global_options.h245Tunneling = 1;
2941  global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
2942  global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
2943  global_options.dtmfmode = 0;
2944  global_options.holdHandling = 0;
2945  global_options.capability = GLOBAL_CAPABILITY;
2946  global_options.bridge = 1; /* Do native bridging by default */
2947  global_options.autoframing = 0;
2948  strcpy(default_context, "default");
2949  h323_signalling_port = 1720;
2950  gatekeeper_disable = 1;
2951  gatekeeper_discover = 0;
2952  gkroute = 0;
2953  userbyalias = 1;
2954  acceptAnonymous = 1;
2955  tos = 0;
2956  cos = 0;
2957 
2958  /* Copy the default jb config over global_jbconf */
2959  memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
2960 
2961  if (ucfg) {
2962  struct ast_variable *gen;
2963  int genhas_h323;
2964  const char *has_h323;
2965 
2966  genhas_h323 = ast_true(ast_variable_retrieve(ucfg, "general", "hash323"));
2967  gen = ast_variable_browse(ucfg, "general");
2968  for (cat = ast_category_browse(ucfg, NULL); cat; cat = ast_category_browse(ucfg, cat)) {
2969  if (strcasecmp(cat, "general")) {
2970  has_h323 = ast_variable_retrieve(ucfg, cat, "hash323");
2971  if (ast_true(has_h323) || (!has_h323 && genhas_h323)) {
2972  user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
2973  if (user) {
2974  ASTOBJ_CONTAINER_LINK(&userl, user);
2976  }
2977  peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
2978  if (peer) {
2979  ASTOBJ_CONTAINER_LINK(&peerl, peer);
2981  }
2982  }
2983  }
2984  }
2985  ast_config_destroy(ucfg);
2986  }
2987 
2988  for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
2989  /* handle jb conf */
2990  if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
2991  continue;
2992  /* Create the interface list */
2993  if (!strcasecmp(v->name, "port")) {
2994  h323_signalling_port = (int)strtol(v->value, NULL, 10);
2995  } else if (!strcasecmp(v->name, "bindaddr")) {
2996  if (!(hp = ast_gethostbyname(v->value, &ahp))) {
2997  ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
2998  } else {
2999  memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
3000  }
3001  } else if (!strcasecmp(v->name, "tos")) { /* Needs to be removed in next release */
3002  ast_log(LOG_WARNING, "The \"tos\" setting is deprecated in this version of Asterisk. Please change to \"tos_audio\".\n");
3003  if (ast_str2tos(v->value, &tos)) {
3004  ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
3005  }
3006  } else if (!strcasecmp(v->name, "tos_audio")) {
3007  if (ast_str2tos(v->value, &tos)) {
3008  ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
3009  }
3010  } else if (!strcasecmp(v->name, "cos")) {
3011  ast_log(LOG_WARNING, "The \"cos\" setting is deprecated in this version of Asterisk. Please change to \"cos_audio\".\n");
3012  if (ast_str2cos(v->value, &cos)) {
3013  ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
3014  }
3015  } else if (!strcasecmp(v->name, "cos_audio")) {
3016  if (ast_str2cos(v->value, &cos)) {
3017  ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
3018  }
3019  } else if (!strcasecmp(v->name, "gatekeeper")) {
3020  if (!strcasecmp(v->value, "DISABLE")) {
3021  gatekeeper_disable = 1;
3022  } else if (!strcasecmp(v->value, "DISCOVER")) {
3023  gatekeeper_disable = 0;
3024  gatekeeper_discover = 1;
3025  } else {
3026  gatekeeper_disable = 0;
3027  ast_copy_string(gatekeeper, v->value, sizeof(gatekeeper));
3028  }
3029  } else if (!strcasecmp(v->name, "secret")) {
3030  ast_copy_string(secret, v->value, sizeof(secret));
3031  } else if (!strcasecmp(v->name, "AllowGKRouted")) {
3032  gkroute = ast_true(v->value);
3033  } else if (!strcasecmp(v->name, "context")) {
3034  ast_copy_string(default_context, v->value, sizeof(default_context));
3035  ast_verb(2, "Setting default context to %s\n", default_context);
3036  } else if (!strcasecmp(v->name, "UserByAlias")) {
3037  userbyalias = ast_true(v->value);
3038  } else if (!strcasecmp(v->name, "AcceptAnonymous")) {
3039  acceptAnonymous = ast_true(v->value);
3040  } else if (!update_common_options(v, &global_options)) {
3041  /* dummy */
3042  }
3043  }
3044  if (!global_options.dtmfmode)
3045  global_options.dtmfmode = H323_DTMF_RFC2833;
3046  if (global_options.holdHandling == ~0)
3047  global_options.holdHandling = 0;
3048  else if (!global_options.holdHandling)
3049  global_options.holdHandling = H323_HOLD_H450;
3050 
3051  for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
3052  if (strcasecmp(cat, "general")) {
3053  utype = ast_variable_retrieve(cfg, cat, "type");
3054  if (utype) {
3055  is_user = is_peer = is_alias = 0;
3056  if (!strcasecmp(utype, "user"))
3057  is_user = 1;
3058  else if (!strcasecmp(utype, "peer"))
3059  is_peer = 1;
3060  else if (!strcasecmp(utype, "friend"))
3061  is_user = is_peer = 1;
3062  else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias"))
3063  is_alias = 1;
3064  else {
3065  ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
3066  continue;
3067  }
3068  if (is_user) {
3069  user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
3070  if (user) {
3071  ASTOBJ_CONTAINER_LINK(&userl, user);
3073  }
3074  }
3075  if (is_peer) {
3076  peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
3077  if (peer) {
3078  ASTOBJ_CONTAINER_LINK(&peerl, peer);
3080  }
3081  }
3082  if (is_alias) {
3083  alias = build_alias(cat, ast_variable_browse(cfg, cat), NULL, 0);
3084  if (alias) {
3085  ASTOBJ_CONTAINER_LINK(&aliasl, alias);
3087  }
3088  }
3089  } else {
3090  ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
3091  }
3092  }
3093  }
3094  ast_config_destroy(cfg);
3095 
3096  /* Register our H.323 aliases if any*/
3099  ASTOBJ_RDLOCK(iterator);
3100  if (h323_set_alias(iterator)) {
3101  ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
3102  ASTOBJ_UNLOCK(iterator);
3103  continue;
3104  }
3105  ASTOBJ_UNLOCK(iterator);
3106  } while (0) );
3108 
3109  /* Don't touch GK if nothing changed because URQ will drop all existing calls */
3110  gk_changed = 0;
3111  if (gatekeeper_disable != gk_disable)
3112  gk_changed = is_reload;
3113  else if(!gatekeeper_disable && (gatekeeper_discover != gk_discover))
3114  gk_changed = is_reload;
3115  else if(!gatekeeper_disable && (strncmp(_gatekeeper, gatekeeper, sizeof(_gatekeeper)) != 0))
3116  gk_changed = is_reload;
3117  if (gk_changed) {
3118  if(!gk_disable)
3119  h323_gk_urq();
3120  if (!gatekeeper_disable) {
3121  if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
3122  ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
3123  gatekeeper_disable = 1;
3124  }
3125  }
3126  }
3127  return 0;
3128 }
3129 
3130 static int h323_reload(void)
3131 {
3133  if (h323_reloading) {
3134  ast_verbose("Previous H.323 reload not yet done\n");
3135  } else {
3136  h323_reloading = 1;
3137  }
3139  restart_monitor();
3140  return 0;
3141 }
3142 
3143 static char *handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
3144 {
3145  switch (cmd) {
3146  case CLI_INIT:
3147  e->command = "h323 reload";
3148  e->usage =
3149  "Usage: h323 reload\n"
3150  " Reloads H.323 configuration from h323.conf\n";
3151  return NULL;
3152  case CLI_GENERATE:
3153  return NULL;
3154  }
3155 
3156  if (a->argc != 2)
3157  return CLI_SHOWUSAGE;
3158 
3159  h323_reload();
3160 
3161  return CLI_SUCCESS;
3162 }
3163 
3164 static int h323_do_reload(void)
3165 {
3166  reload_config(1);
3167  return 0;
3168 }
3169 
3170 static int reload(void)
3171 {
3172  if (!sched || !io) {
3173  ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
3174  return 0;
3175  }
3176  return h323_reload();
3177 }
3178 
3180  AST_CLI_DEFINE(handle_cli_h323_reload, "Reload H.323 configuration");
3181 
3182 static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
3183 {
3184  struct oh323_pvt *pvt;
3186 
3187  if (!(pvt = (struct oh323_pvt *)chan->tech_pvt))
3189 
3190  ast_mutex_lock(&pvt->lock);
3191  *instance = pvt->rtp ? ao2_ref(pvt->rtp, +1), pvt->rtp : NULL;
3192 #if 0
3193  if (pvt->options.bridge) {
3195  }
3196 #endif
3197  ast_mutex_unlock(&pvt->lock);
3198 
3199  return res;
3200 }
3201 
3202 #if 0
3203 static char *convertcap(format_t cap)
3204 {
3205  switch (cap) {
3206  case AST_FORMAT_G723_1:
3207  return "G.723";
3208  case AST_FORMAT_GSM:
3209  return "GSM";
3210  case AST_FORMAT_ULAW:
3211  return "ULAW";
3212  case AST_FORMAT_ALAW:
3213  return "ALAW";
3214  case AST_FORMAT_G722:
3215  return "G.722";
3216  case AST_FORMAT_ADPCM:
3217  return "G.728";
3218  case AST_FORMAT_G729A:
3219  return "G.729";
3220  case AST_FORMAT_SPEEX:
3221  return "SPEEX";
3222  case AST_FORMAT_ILBC:
3223  return "ILBC";
3224  default:
3225  ast_log(LOG_NOTICE, "Don't know how to deal with mode %" PRId64 "\n", cap);
3226  return NULL;
3227  }
3228 }
3229 #endif
3230 
3231 static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
3232 {
3233  /* XXX Deal with Video */
3234  struct oh323_pvt *pvt;
3235  struct sockaddr_in them = { 0, };
3236  struct sockaddr_in us = { 0, };
3237 #if 0 /* Native bridge still isn't ready */
3238  char *mode;
3239 #endif
3240 
3241  if (!rtp) {
3242  return 0;
3243  }
3244 
3245 #if 0 /* Native bridge still isn't ready */
3246  mode = convertcap(chan->writeformat);
3247 #endif
3248 
3249  pvt = (struct oh323_pvt *) chan->tech_pvt;
3250  if (!pvt) {
3251  ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
3252  return -1;
3253  }
3254  {
3255  struct ast_sockaddr tmp;
3256 
3258  ast_sockaddr_to_sin(&tmp, &them);
3260  ast_sockaddr_to_sin(&tmp, &us);
3261  }
3262 #if 0 /* Native bridge still isn't ready */
3263  h323_native_bridge(pvt->cd.call_token, ast_inet_ntoa(them.sin_addr), mode);
3264 #endif
3265  return 0;
3266 }
3267 
3268 static struct ast_rtp_glue oh323_rtp_glue = {
3269  .type = "H323",
3270  .get_rtp_info = oh323_get_rtp_peer,
3271  .update_peer = oh323_set_rtp_peer,
3272 };
3273 
3275 {
3276  int res;
3277 
3278  h323debug = 0;
3279  sched = sched_context_create();
3280  if (!sched) {
3281  ast_log(LOG_WARNING, "Unable to create schedule context\n");
3282  return AST_MODULE_LOAD_FAILURE;
3283  }
3284  io = io_context_create();
3285  if (!io) {
3286  ast_log(LOG_WARNING, "Unable to create I/O context\n");
3287  return AST_MODULE_LOAD_FAILURE;
3288  }
3289  ast_cli_register(&cli_h323_reload);
3293  res = reload_config(0);
3294  if (res) {
3295  /* No config entry */
3296  ast_log(LOG_NOTICE, "Unload and load chan_h323.so again in order to receive configuration changes.\n");
3297  ast_cli_unregister(&cli_h323_reload);
3298  io_context_destroy(io);
3299  io = NULL;
3300  sched_context_destroy(sched);
3301  sched = NULL;
3305  return AST_MODULE_LOAD_DECLINE;
3306  } else {
3307  /* Make sure we can register our channel type */
3308  if (ast_channel_register(&oh323_tech)) {
3309  ast_log(LOG_ERROR, "Unable to register channel class 'H323'\n");
3310  ast_cli_unregister(&cli_h323_reload);
3311  h323_end_process();
3312  io_context_destroy(io);
3313  sched_context_destroy(sched);
3314 
3321 
3322  return AST_MODULE_LOAD_FAILURE;
3323  }
3324  ast_cli_register_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
3325 
3326  ast_rtp_glue_register(&oh323_rtp_glue);
3327 
3328  /* Register our callback functions */
3329  h323_callback_register(setup_incoming_call,
3334  chan_ringing,
3336  receive_digit,
3337  answer_call,
3338  progress,
3343  remote_hold);
3344  /* start the h.323 listener */
3345  if (h323_start_listener(h323_signalling_port, bindaddr)) {
3346  ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
3347  ast_rtp_glue_unregister(&oh323_rtp_glue);
3348  ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
3349  ast_cli_unregister(&cli_h323_reload);
3350  h323_end_process();
3351  io_context_destroy(io);
3352  sched_context_destroy(sched);
3353 
3360 
3361  return AST_MODULE_LOAD_DECLINE;
3362  }
3363  /* Possibly register with a GK */
3364  if (!gatekeeper_disable) {
3365  if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
3366  ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
3367  gatekeeper_disable = 1;
3369  }
3370  }
3371  /* And start the monitor for the first time */
3372  restart_monitor();
3373  }
3374  return res;
3375 }
3376 
3377 static int unload_module(void)
3378 {
3379  struct oh323_pvt *p, *pl;
3380 
3381  /* unregister commands */
3382  ast_cli_unregister_multiple(cli_h323, sizeof(cli_h323) / sizeof(struct ast_cli_entry));
3383  ast_cli_unregister(&cli_h323_reload);
3384 
3385  ast_channel_unregister(&oh323_tech);
3386  ast_rtp_glue_unregister(&oh323_rtp_glue);
3387 
3388  if (!ast_mutex_lock(&iflock)) {
3389  /* hangup all interfaces if they have an owner */
3390  p = iflist;
3391  while(p) {
3392  if (p->owner) {
3394  }
3395  p = p->next;
3396  }
3397  iflist = NULL;
3399  } else {
3400  ast_log(LOG_WARNING, "Unable to lock the interface list\n");
3401  return -1;
3402  }
3403  if (!ast_mutex_lock(&monlock)) {
3404  if ((monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
3405  if (monitor_thread != pthread_self()) {
3406  pthread_cancel(monitor_thread);
3407  }
3408  pthread_kill(monitor_thread, SIGURG);
3409  pthread_join(monitor_thread, NULL);
3410  }
3411  monitor_thread = AST_PTHREADT_STOP;
3413  } else {
3414  ast_log(LOG_WARNING, "Unable to lock the monitor\n");
3415  return -1;
3416  }
3417  if (!ast_mutex_lock(&iflock)) {
3418  /* destroy all the interfaces and free their memory */
3419  p = iflist;
3420  while(p) {
3421  pl = p;
3422  p = p->next;
3423  /* free associated memory */
3424  ast_mutex_destroy(&pl->lock);
3425  ast_free(pl);
3426  }
3427  iflist = NULL;
3429  } else {
3430  ast_log(LOG_WARNING, "Unable to lock the interface list\n");
3431  return -1;
3432  }
3433  if (!gatekeeper_disable)
3434  h323_gk_urq();
3435  h323_end_process();
3436  if (io)
3437  io_context_destroy(io);
3438  if (sched)
3439  sched_context_destroy(sched);
3440 
3447 
3448  return 0;
3449 }
3450 
3451 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "The NuFone Network's OpenH323 Channel Driver",
3452  .load = load_module,
3453  .unload = unload_module,
3454  .reload = reload,
3455  .load_pri = AST_MODPRI_CHANNEL_DRIVER,
3456 );
static char user[512]
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
Definition: io.c:273
static struct ast_frame * oh323_rtp_read(struct oh323_pvt *pvt)
Retrieve audio/etc from channel. Assumes pvt-&gt;lock is already held.
Definition: chan_h323.c:752
void ast_rtp_codecs_packetization_set(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, struct ast_codec_pref *prefs)
Set codec packetization preferences.
Definition: rtp_engine.c:727
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1569
union ast_frame_subclass subclass
Definition: frame.h:146
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
struct sockaddr_storage ss
Definition: netsock2.h:64
enum sip_cc_notify_state state
Definition: chan_sip.c:842
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
int presentation
Q.931 encoded presentation-indicator encoded field.
Definition: channel.h:227
int newduration
Definition: chan_h323.c:178
#define ast_channel_lock(chan)
Definition: channel.h:2466
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
Definition: dsp.c:1392
ast_module_load_result
Definition: module.h:60
Main Channel structure associated with a channel.
Definition: channel.h:742
Music on hold handling.
static char default_context[AST_MAX_CONTEXT]
Definition: chan_h323.c:132
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
static struct oh323_user * build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
Definition: chan_h323.c:1384
static int dtmfmode
Definition: chan_mgcp.c:160
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
int h323debug
Definition: chan_h323.c:115
const char *const type
Definition: channel.h:508
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
Definition: causes.h:134
Asterisk locking-related definitions:
static char * handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2776
Asterisk main include file. File version handling, generic pbx functions.
int rings
Definition: channel.h:840
static struct oh323_pvt * find_call_locked(int call_reference, const char *token)
Definition: chan_h323.c:1168
static const char config[]
Definition: chan_h323.c:131
receive_digit_cb on_receive_digit
Definition: chan_h323.c:99
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static char * handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2726
static ast_mutex_t monlock
Protect the H.323 monitoring thread, so only one process can kill or start it, and not when it&#39;s doin...
Definition: chan_h323.c:218
int nativeformats
Definition: chan_h323.c:172
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
Definition: channel.c:1601
struct ast_frame ast_null_frame
Definition: frame.c:131
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
setup_incoming_cb on_incoming_call
Definition: chan_h323.c:102
static ast_mutex_t h323_reload_lock
Protect the reload process.
Definition: chan_h323.c:224
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
Definition: callerid.c:1093
start_rtp_cb on_start_rtp_channel
Definition: chan_h323.c:101
static call_options_t * setup_incoming_call(call_details_t *cd)
Call-back function for incoming calls.
Definition: chan_h323.c:2145
int priority
Definition: channel.h:841
int recvonly
Definition: chan_h323.c:187
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
Definition: channel.h:245
onhold_cb on_hold
Definition: chan_h323.c:113
struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload)
Retrieve payload information by payload.
Definition: rtp_engine.c:618
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
static void delete_aliases(void)
Definition: chan_h323.c:2853
#define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container, data, field, hashfunc, hashoffset, comparefunc)
Find and remove an object in a container.
Definition: astobj.h:551
void ast_rtp_instance_change_source(struct ast_rtp_instance *instance)
Indicate a new source of audio has dropped in and the ssrc should change.
Definition: rtp_engine.c:767
#define ast_strdup(a)
Definition: astmm.h:109
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
static int oh323_answer(struct ast_channel *c)
Definition: chan_h323.c:662
Definition: ast_expr2.c:325
format_t writeformat
Definition: channel.h:854
static unsigned int tos
Definition: chan_h323.c:146
struct ast_party_id id
Connected party ID.
Definition: channel.h:403
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
Definition: acl.c:744
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
Definition: causes.h:121
static struct oh323_alias * realtime_alias(const char *alias)
Definition: chan_h323.c:1250
static struct oh323_user * realtime_user(const call_details_t *cd)
Definition: chan_h323.c:1470
struct ast_rtp_instance * rtp
Definition: chan_h323.c:170
char order[sizeof(format_t)*8]
Definition: frame.h:39
static enum ast_module_load_result load_module(void)
Definition: chan_h323.c:3274
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
static struct ast_cli_entry cli_h323_reload
Definition: chan_h323.c:3179
#define AST_FORMAT_G723_1
Definition: frame.h:242
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
int newstate
Definition: chan_h323.c:175
int noInbandDtmf
Definition: chan_h323.c:189
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1650
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
void * tech_pvt
Definition: channel.h:744
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:97
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
Convenient Signal Processing routines.
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ASTOBJ_MARK(object)
Mark an ASTOBJ by adding the ASTOBJ_FLAG_MARKED flag to its objflags mask.
Definition: astobj.h:241
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:483
clear_con_cb on_connection_cleared
Definition: chan_h323.c:106
#define DEADLOCK_AVOIDANCE(lock)
Definition: lock.h:485
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
static int __oh323_rtp_create(struct oh323_pvt *pvt)
Definition: chan_h323.c:964
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
#define LOG_WARNING
Definition: logger.h:144
static struct oh323_peer * find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
Definition: chan_h323.c:1668
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
static struct aji_capabilities * capabilities
Definition: res_jabber.c:393
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:2151
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
Definition: abstract_jb.c:577
static void oh323_destroy_alias(struct oh323_alias *alias)
Definition: chan_h323.c:282
int lineno
Definition: config.h:87
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct ast_dsp * ast_dsp_new(void)
Definition: dsp.c:1607
#define AST_FRAME_DTMF
Definition: frame.h:128
static int update_state(struct oh323_pvt *pvt, int state, int signal)
Definition: chan_h323.c:1194
call_options_t options
Definition: chan_h323.c:156
#define ASTOBJ_UNMARK(object)
Unmark an ASTOBJ by subtracting the ASTOBJ_FLAG_MARKED flag from its objflags mask.
Definition: astobj.h:251
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
int ast_rtp_instance_set_qos(struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
Set QoS parameters on an RTP session.
Definition: rtp_engine.c:774
static int create_addr(struct oh323_pvt *pvt, char *opeer)
Definition: chan_h323.c:1686
#define var
Definition: ast_expr2f.c:606
static struct ast_channel * oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
Definition: chan_h323.c:1758
char accountcode[256]
Definition: chan_h323.c:167
setup_outbound_cb on_outgoing_call
Definition: chan_h323.c:103
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
Definition: rtp_engine.c:374
static int h323_reloading
Definition: chan_h323.c:225
static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
Compares the source address and port of two sockaddr_in.
Definition: network.h:90
format_t rawwriteformat
Definition: channel.h:856
#define ast_rtp_glue_register(glue)
Definition: rtp_engine.h:476
static const char * redirectingreason2str(int redirectingreason)
Definition: chan_h323.c:266
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
Definition: cli.h:146
static int reload_config(int is_reload)
Definition: chan_h323.c:2877
static struct oh323_alias * find_alias(const char *source_aliases, int realtime)
Find a call by alias.
Definition: chan_h323.c:1845
Configuration File Parser.
char * str
Subscriber name (Malloced)
Definition: channel.h:214
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
Definition: config.c:2548
static void delete_users(void)
Definition: chan_h323.c:2827
static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
Definition: chan_h323.c:861
static struct h323_user_list userl
format_t ast_best_codec(format_t fmts)
Pick the best audio codec.
Definition: channel.c:1062
ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user)
on_rtp_cb on_external_rtp_create
Definition: chan_h323.c:100
static void cleanup_call_details(call_details_t *cd)
Definition: chan_h323.c:410
#define ast_mutex_lock(a)
Definition: lock.h:155
static void oh323_destroy_peer(struct oh323_peer *peer)
Definition: chan_h323.c:297
unsigned short transfercapability
Definition: channel.h:863
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
static int oh323_hangup(struct ast_channel *c)
Definition: chan_h323.c:685
format_t nativeformats
Definition: channel.h:852
static int gatekeeper_disable
Definition: chan_h323.c:140
H323 User list.
Definition: chan_h323.c:196
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static void oh323_update_info(struct ast_channel *c)
Only channel structure should be locked.
Definition: chan_h323.c:399
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
Definition: acl.c:667
H323 alias list.
Definition: chan_h323.c:206
static int gatekeeper_discover
Definition: chan_h323.c:141
format_t codec
Definition: frame.h:137
const char * data
Definition: channel.h:755
static void * do_monitor(void *data)
Definition: chan_h323.c:2574
I/O Management (derived from Cheops-NG)
Definition: dsp.c:105
static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
Send (play) the specified digit to the channel.
Definition: chan_h323.c:543
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Definition: causes.h:119
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int oh323_digit_begin(struct ast_channel *c, char digit)
Definition: chan_h323.c:502
void ast_update_use_count(void)
Notify when usecount has been changed.
Definition: loader.c:1222
static void oh323_destroy(struct oh323_pvt *pvt)
Definition: chan_h323.c:491
const ast_string_field linkedid
Definition: channel.h:787
const char * ext
Definition: http.c:112
char exten[AST_MAX_EXTENSION]
Definition: chan_h323.c:165
static struct oh323_user * find_user(const call_details_t *cd, int realtime)
Definition: chan_h323.c:1638
format_t rawreadformat
Definition: channel.h:855
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
static char * handle_cli_h323_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2797
Socket address structure.
Definition: netsock2.h:63
static char cid_num[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:157
#define ast_verb(level,...)
Definition: logger.h:243
ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer)
answer_call_cb on_answer_call
Definition: chan_h323.c:107
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
const char * type
Definition: rtp_engine.h:395
static char gatekeeper[100]
Definition: chan_h323.c:139
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
#define AST_FORMAT_G729A
Definition: frame.h:258
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
String fields in structures.
Utility functions.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1581
int args
This gets set in ast_cli_register()
Definition: cli.h:179
static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
Definition: chan_h323.c:2463
struct ast_codec_pref peer_prefs
Definition: chan_h323.c:182
#define ASTOBJ_CONTAINER_WRLOCK(container)
Lock an ASTOBJ_CONTAINER for writing.
Definition: astobj.h:280
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
Definition: astobj.h:752
static int answer_call(unsigned call_reference, const char *token)
Call-back function to start PBX when OpenH323 ready to serve incoming call.
Definition: chan_h323.c:2265
internal representation of acl entries In principle user applications would have no need for this...
Definition: acl.h:48
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
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
static struct ast_cli_entry cli_h323[]
Definition: chan_h323.c:2818
static int userbyalias
Definition: chan_h323.c:144
struct oh323_pvt * next
Definition: chan_h323.c:192
format_t jointcapability
Definition: chan_h323.c:181
static char * handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2674
int outgoing
Definition: chan_h323.c:164
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
int DTMFsched
Definition: chan_h323.c:185
Private structure of a OpenH323 channel.
Definition: chan_h323.c:154
#define SENTINEL
Definition: compiler.h:75
static void cleanup_connection(unsigned call_reference, const char *call_token)
Call-back function to cleanup communication Returns nothing,.
Definition: chan_h323.c:2382
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
Definition: rtp_engine.c:779
const char * value
Definition: config.h:79
ASTOBJ_CONTAINER_COMPONENTS(struct oh323_alias)
static int receive_digit(unsigned call_reference, char digit, const char *token, int duration)
Callback for sending digits from H.323 up to asterisk.
Definition: chan_h323.c:1861
struct ast_module * self
Definition: module.h:227
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
General Asterisk PBX channel definitions.
struct ast_party_dialed::@155 number
Dialed/Called number.
static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
Definition: chan_h323.c:832
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
void io_context_destroy(struct io_context *ioc)
Destroys a context.
Definition: io.c:102
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
struct sockaddr_in redirip
Definition: chan_h323.c:162
#define ast_mutex_trylock(a)
Definition: lock.h:157
static struct oh323_pvt * iflist
static struct ast_generator gen
const int fd
Definition: cli.h:153
#define AST_FORMAT_ALAW
Definition: frame.h:248
static struct h323_alias_list aliasl
Definition: dsp.c:390
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static void hangup_connection(unsigned int call_reference, const char *token, int cause)
Definition: chan_h323.c:2435
#define AST_FORMAT_SPEEX
Definition: frame.h:260
#define AST_PTHREADT_NULL
Definition: lock.h:65
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
format_t pref_codec
Definition: chan_h323.c:179
Access Control of various sorts.
call_details_t cd
Definition: chan_h323.c:159
struct sockaddr_in sa
Definition: chan_h323.c:161
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:66
#define AST_MAX_EXTENSION
Definition: channel.h:135
int datalen
Definition: frame.h:148
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
Scheduler Routines (derived from cheops)
#define AST_FORMAT_G726_AAL2
Definition: frame.h:250
#define ao2_ref(o, delta)
Definition: astobj2.h:472
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
Channel and private structures should be already locked.
Definition: chan_h323.c:335
static int update_common_options(struct ast_variable *v, struct call_options *options)
Definition: chan_h323.c:1275
static void connection_made(unsigned call_reference, const char *token)
Call-back function to signal asterisk that the channel has been answered Returns nothing.
Definition: chan_h323.c:2090
static int oh323_call(struct ast_channel *c, char *dest, int timeout)
Make a call over the specified channel to the specified destination. Returns -1 on error...
Definition: chan_h323.c:582
static const char tdesc[]
Definition: chan_h323.c:130
int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:391
static unsigned int unique
Definition: chan_h323.c:149
#define ASTOBJ_INIT(object)
Initialize an object.
Definition: astobj.h:264
int needhangup
Definition: chan_h323.c:173
const char * name
Definition: config.h:77
int newdigit
Definition: chan_h323.c:177
#define AST_CAUSE_NO_ANSWER
Definition: causes.h:108
int hangupcause
Definition: chan_h323.c:174
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
static struct ast_frame * oh323_read(struct ast_channel *c)
Definition: chan_h323.c:807
int needdestroy
Definition: chan_h323.c:158
ast_rtp_glue_result
Definition: rtp_engine.h:125
int ast_rtp_codecs_payloads_set_rtpmap_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload, char *mimetype, char *mimesubtype, enum ast_rtp_options options)
Record payload information that was seen in an a=rtpmap: SDP line.
Definition: rtp_engine.c:597
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration - by default, jb is disabled.
Definition: chan_h323.c:119
Structure to describe a channel &quot;technology&quot;, ie a channel driver See for examples: ...
Definition: channel.h:507
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
Definition: causes.h:114
static struct sched_context * sched
Definition: chan_gtalk.c:227
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
Definition: astobj.h:218
static struct ast_channel * __oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
Private structure should be locked on a call.
Definition: chan_h323.c:1018
const char *const * argv
Definition: cli.h:155
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
static char * handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2753
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
Definition: chan_h323.c:1633
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
Definition: astobj.h:765
#define LOG_ERROR
Definition: logger.h:155
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
Definition: astobj.h:453
A set of macros implementing objects and containers. Macros are used for maximum performance, to support multiple inheritance, and to be easily integrated into existing structures without additional malloc calls, etc.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free&#39;s) the given sched_context structure
Definition: sched.c:267
int64_t format_t
Definition: frame_defs.h:32
static int h323_signalling_port
Definition: chan_h323.c:138
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
Definition: astobj.h:776
progress_cb on_progress
Definition: chan_h323.c:108
#define CLI_SHOWUSAGE
Definition: cli.h:44
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
Definition: channel.h:243
static struct ast_codec_pref prefs
Definition: chan_iax2.c:258
#define AST_FORMAT_ULAW
Definition: frame.h:246
static struct ast_channel_tech oh323_tech
Definition: chan_h323.c:248
int ast_cdr_amaflags2int(const char *flag)
Convert a string to a detail record AMA flag.
Definition: cdr.c:1105
enum ast_channel_state _state
Definition: channel.h:839
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
Definition: rtp_engine.c:736
const ast_string_field name
Definition: channel.h:787
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
struct ast_dsp * vad
Definition: chan_h323.c:171
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 _softhangup
Definition: channel.h:832
format_t ast_codec_choose(struct ast_codec_pref *pref, format_t formats, int find_best)
Select the best audio format according to preference list from supplied options. If &quot;find_best&quot; is no...
Definition: frame.c:1249
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
Definition: astobj.h:376
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
Definition: acl.c:700
#define LOG_NOTICE
Definition: logger.h:133
static struct oh323_peer * build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
Definition: chan_h323.c:1508
static struct oh323_peer * realtime_peer(const char *peername, struct sockaddr_in *sin)
Definition: chan_h323.c:1590
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2733
int framing[64]
Definition: frame.h:40
int nonCodecCapability
Definition: chan_h323.c:163
int fdno
Definition: channel.h:834
static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
Definition: chan_h323.c:3231
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
Definition: chan_h323.c:229
#define ast_channel_unlock(chan)
Definition: channel.h:2467
int errno
static void set_local_capabilities(unsigned call_reference, const char *token)
Definition: chan_h323.c:2518
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1642
static const char name[]
#define AST_MAX_CONTEXT
Definition: channel.h:136
int newcontrol
Definition: chan_h323.c:176
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Definition: utils.c:564
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
Definition: astobj.h:109
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
format_t peercapability
Definition: chan_h323.c:180
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
Definition: astobj.h:401
#define ASTOBJ_CONTAINER_UNLOCK(container)
Unlock an ASTOBJ_CONTAINER.
Definition: astobj.h:283
struct ast_channel * owner
Definition: chan_h323.c:160
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
Definition: acl.c:653
static void setup_rtp_connection(unsigned call_reference, const char *remoteIp, int remotePort, const char *token, int pt)
Call-back function passing remote ip/port information from H.323 to asterisk.
Definition: chan_h323.c:1975
int ast_udptl_fd(const struct ast_udptl *udptl)
Definition: udptl.c:643
static struct ast_format f[]
Definition: format_g726.c:181
int txDtmfDigit
Definition: chan_h323.c:188
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
Definition: rtp_engine.c:786
static format_t capability
Definition: chan_mgcp.c:228
static int oh323_simulate_dtmf_end(const void *data)
Definition: chan_h323.c:305
int update_rtp_info
Definition: chan_h323.c:186
struct ast_rtp_instance * ast_rtp_instance_new(const char *engine_name, struct sched_context *sched, const struct ast_sockaddr *sa, void *data)
Create a new RTP instance.
Definition: rtp_engine.c:308
int curDTMF
Definition: chan_h323.c:184
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
Definition: abstract_jb.h:58
int connection_established
Definition: chan_h323.c:190
char rdnis[80]
Definition: chan_h323.c:168
static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
Definition: chan_h323.c:950
static int setup_outgoing_call(call_details_t *cd)
Call-back function to establish an outgoing H.323 call.
Definition: chan_h323.c:2344
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
static const char type[]
Definition: chan_nbs.c:57
structure to hold users read from users.conf
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:430
Structure used to handle boolean flags.
Definition: utils.h:200
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
Definition: rtp_engine.c:301
int amaflags
Definition: chan_h323.c:169
#define ast_clear_flag(p, flag)
Definition: utils.h:77
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
Definition: channel.c:2631
H323 peer list.
Definition: chan_h323.c:201
static char cid_name[AST_MAX_EXTENSION]
Definition: chan_mgcp.c:158
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:616
int ast_sched_runq(struct sched_context *con)
Runs the queue.
Definition: sched.c:600
const char * usage
Definition: cli.h:171
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
static struct sockaddr_in bindaddr
Definition: chan_gtalk.c:225
static void chan_ringing(unsigned call_reference, const char *token)
Call-back function to signal asterisk that the channel is ringing Returns nothing.
Definition: chan_h323.c:2356
static int restart_monitor(void)
Definition: chan_h323.c:2642
static char * handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:3143
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:223
static struct rtp_info * external_rtp_create(unsigned call_reference, const char *token)
Callback function used to inform the H.323 stack of the local rtp ip/port details.
Definition: chan_h323.c:1929
#define CLI_SUCCESS
Definition: cli.h:43
#define LOG_DTMF
Definition: logger.h:177
static struct ast_jb_conf global_jbconf
Definition: chan_h323.c:127
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
Definition: causes.h:124
hangup_cb on_hangup
Definition: chan_h323.c:110
static int unload_module(void)
Definition: chan_h323.c:3377
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
Definition: utils.c:195
static void remote_hold(unsigned call_reference, const char *token, int is_hold)
Definition: chan_h323.c:2548
static char secret[50]
Definition: chan_h323.c:148
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
struct sched_context * sched_context_create(void)
New schedule context.
Definition: sched.c:246
int alreadygone
Definition: chan_h323.c:157
Channels have this property if they can create jitter; i.e. most VoIP channels.
Definition: channel.h:888
Standard Command Line Interface.
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
Definition: astobj.h:100
format_t readformat
Definition: channel.h:853
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
static int h323_do_reload(void)
Definition: chan_h323.c:3164
ast_mutex_t lock
Definition: chan_h323.c:155
static void oh323_destroy_user(struct oh323_user *user)
Definition: chan_h323.c:289
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
#define AST_CAUSE_USER_BUSY
Definition: causes.h:106
int ast_sched_wait(struct sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place Determine the number of s...
Definition: sched.c:334
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
#define AST_PTHREADT_STOP
Definition: lock.h:66
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
Definition: rtp_engine.c:266
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
Definition: channel.c:1041
#define AST_FORMAT_ADPCM
Definition: frame.h:252
static void __oh323_destroy(struct oh323_pvt *pvt)
Definition: chan_h323.c:446
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Definition: frame.c:591
Data structure associated with a single frame of data.
Definition: frame.h:142
int hangupcause
Definition: channel.h:849
#define ASTOBJ_CONTAINER_FIND_FULL(container, data, field, hashfunc, hashoffset, comparefunc)
Find an object in a container.
Definition: astobj.h:428
Internal Asterisk hangup causes.
setpeercapabilities_cb on_setpeercapabilities
Definition: chan_h323.c:112
con_established_cb on_connection_established
Definition: chan_h323.c:105
#define AST_FORMAT_G722
Definition: frame.h:266
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:399
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
Definition: channel.h:883
static int progress(unsigned call_reference, const char *token, int inband)
Definition: chan_h323.c:2117
void ast_rtp_instance_set_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
Set the value of an RTP instance property.
Definition: rtp_engine.c:469
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
char context[AST_MAX_CONTEXT]
Definition: chan_h323.c:166
enum ast_frame_type frametype
Definition: frame.h:144
struct ast_variable * next
Definition: config.h:82
static int gkroute
Definition: chan_h323.c:142
static struct ast_rtp_glue oh323_rtp_glue
Definition: chan_h323.c:3268
static void prune_peers(void)
Definition: chan_h323.c:2871
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static int acceptAnonymous
Definition: chan_h323.c:145
static call_options_t global_options
Definition: chan_h323.c:151
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static char * handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: chan_h323.c:2703
#define ast_mutex_destroy(a)
Definition: lock.h:154
static unsigned int cos
Definition: chan_h323.c:147
static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
Definition: chan_h323.c:3182
static ast_mutex_t iflock
Definition: chan_h323.c:214
static struct h323_peer_list peerl
#define AST_RTP_DTMF
Definition: rtp_engine.h:218
#define GLOBAL_CAPABILITY
Definition: chan_h323.c:135
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
static struct oh323_pvt * oh323_alloc(int callid)
Definition: chan_h323.c:1125
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:110
Pluggable RTP Architecture.
void ast_rtp_instance_update_source(struct ast_rtp_instance *instance)
Indicate that the RTP marker bit should be set on an RTP stream.
Definition: rtp_engine.c:760
setcapabilities_cb on_setcapabilities
Definition: chan_h323.c:111
Asterisk module definitions.
static struct hostent * hp
Definition: chan_skinny.c:1048
int amaflags
Definition: channel.h:843
rfc2833_cb on_set_rfc2833_payload
Definition: chan_h323.c:109
static int h323_reload(void)
Definition: chan_h323.c:3130
static snd_pcm_format_t format
Definition: chan_alsa.c:93
union ast_frame::@172 data
struct ast_channel_tech * tech
Definition: channel.h:743
#define AST_FORMAT_ILBC
Definition: frame.h:262
#define AST_FORMAT_GSM
Definition: frame.h:244
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
long len
Definition: frame.h:170
General jitterbuffer configuration.
Definition: abstract_jb.h:55
static ast_mutex_t caplock
Protect the H.323 capabilities list, to avoid more than one channel to set the capabilities simultane...
Definition: chan_h323.c:221
static int reload(void)
Definition: chan_h323.c:3170
int got_progress
Definition: chan_h323.c:191
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:526
Structure for mutex and tracking information.
Definition: lock.h:121
int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing)
Parse an &quot;allow&quot; or &quot;deny&quot; line in a channel or device configuration and update the capabilities mask...
Definition: frame.c:1272
static struct io_context * io
Definition: chan_h323.c:212
chan_ringing_cb on_chan_ringing
Definition: chan_h323.c:104
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
Definition: rtp_engine.c:379
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
int samples
Definition: frame.h:150
static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
Definition: chan_h323.c:1656
int dtmf_pt[2]
Definition: chan_h323.c:183
#define ASTOBJ_CONTAINER_PRUNE_MARKED(container, destructor)
Prune marked objects from a container.
Definition: astobj.h:651
static struct oh323_alias * build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
Definition: chan_h323.c:1215
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
#define ast_mutex_unlock(a)
Definition: lock.h:156
enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
Bridge two channels that use RTP instances.
Definition: rtp_engine.c:1274
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Stop sending a DTMF digit.
Definition: rtp_engine.c:741
struct io_context * io_context_create(void)
Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up s...
Definition: io.c:76
static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)
Definition: chan_h323.c:2483