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>
62 #include <netinet/in.h>
63 #include <netinet/in_systm.h>
64 #include <netinet/ip.h>
97 #include "h323/chan_h323.h"
123 .resync_threshold = 1000,
130 static const char tdesc[] =
"The NuFone Network's Open H.323 Channel Driver";
131 static const char config[] =
"h323.conf";
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)
146 static unsigned int tos = 0;
147 static unsigned int cos = 0;
161 struct sockaddr_in
sa;
250 .description =
tdesc,
268 switch (redirectingreason) {
276 return "UNCONDITIONAL";
285 ast_debug(1,
"Destroying alias '%s'\n", alias->name);
292 ast_debug(1,
"Destroying user '%s'\n", user->name);
300 ast_debug(1,
"Destroying peer '%s'\n", peer->name);
319 .subclass.integer = pvt->
curDTMF,
321 .src =
"SIMULATE_DTMF_END",
339 ast_debug(1,
"Preparing %s for new native format\n", c->
name);
367 .src =
"UPDATE_INFO",
412 if (cd->call_token) {
414 cd->call_token = NULL;
416 if (cd->call_source_aliases) {
418 cd->call_source_aliases = NULL;
420 if (cd->call_dest_alias) {
422 cd->call_dest_alias = NULL;
424 if (cd->call_source_name) {
426 cd->call_source_name = NULL;
428 if (cd->call_source_e164) {
430 cd->call_source_e164 = NULL;
432 if (cd->call_dest_e164) {
434 cd->call_dest_e164 = NULL;
440 if (cd->redirect_number) {
442 cd->redirect_number = NULL;
527 token = pvt->
cd.call_token ?
ast_strdup(pvt->
cd.call_token) : NULL;
529 h323_send_tone(token, digit);
556 ast_log(
LOG_DTMF,
"End sending out-of-band digit %c on %s, duration %d\n", digit, c->
name, duration);
563 ast_log(
LOG_DTMF,
"End sending inband digit %c on %s, duration %d\n", digit, c->
name, duration);
566 token = pvt->
cd.call_token ?
ast_strdup(pvt->
cd.call_token) : NULL;
568 h323_send_tone(token,
' ');
587 char called_addr[1024];
597 if (!gatekeeper_disable) {
601 snprintf(called_addr,
sizeof(called_addr),
"%s@%s", pvt->
exten, dest);
604 res = htons(pvt->
sa.sin_port);
607 snprintf(called_addr,
sizeof(called_addr),
"%s:%d", addr, res);
609 snprintf(called_addr,
sizeof(called_addr),
"%s@%s:%d", pvt->
exten, addr, res);
613 called_addr[
sizeof(called_addr) - 1] =
'\0';
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;
640 pvt->
options.redirect_reason = -1;
642 pvt->
options.redirect_reason = -1;
651 ast_debug(1,
"Placing outgoing call to %s, %d/%d\n", called_addr, pvt->
options.dtmfcodec[0], pvt->
options.dtmfcodec[1]);
653 res = h323_make_call(called_addr, &(pvt->
cd), &pvt->
options);
672 token = pvt->
cd.call_token ?
ast_strdup(pvt->
cd.call_token) : NULL;
674 res = h323_answering_call(token, 0);
693 ast_debug(1,
"Hanging up and scheduling destroy of call %s\n", c->
name);
701 if (pvt->
owner != c) {
715 if (!strcmp(cause,
"CONGESTION")) {
717 }
else if (!strcmp(cause,
"BUSY")) {
719 }
else if (!strcmp(cause,
"CHANISUNVAIL")) {
721 }
else if (!strcmp(cause,
"NOANSWER")) {
723 }
else if (!strcmp(cause,
"CANCEL")) {
731 call_token = pvt->
cd.call_token ?
ast_strdup(pvt->
cd.call_token) : NULL;
735 if (h323_clear_call(call_token, q931cause)) {
767 if (f && pvt->
owner) {
773 ast_log(
LOG_NOTICE,
"Format changed but channel is locked. Ignoring frame...\n");
785 if ((pvt->
options.dtmfmode & H323_DTMF_INBAND) && pvt->
vad) {
846 ast_log(
LOG_WARNING,
"Asked to transmit frame type '%s', while native formats is '%s' (read/write = %s/%s)\n",
865 char *token = (
char *)NULL;
870 token = (pvt->
cd.call_token ?
ast_strdup(pvt->
cd.call_token) : NULL);
879 ast_debug(1,
"OH323: Indicating %d on %s (%s)\n", condition, token, c->
name);
884 h323_send_alerting(token);
885 res = (got_progress ? 0 : -1);
892 h323_send_progress(token);
898 h323_answering_call(token, 1);
909 h323_answering_call(token, 1);
915 h323_hold_call(token, 1);
921 h323_hold_call(token, 0);
937 ast_log(
LOG_WARNING,
"OH323: Don't know how to indicate condition %d on %s\n", condition, token);
942 ast_debug(1,
"OH323: Indicated %d on %s, res=%d\n", condition, token, res);
955 if (pvt->
owner != oldchan) {
959 pvt->
owner = newchan;
981 our_addr.
ss.ss_family = AF_INET;
1025 cid_num = pvt->
options.cid_num;
1027 cid_num = pvt->
cd.call_source_e164;
1030 cid_name = pvt->
options.cid_name;
1032 cid_name = pvt->
cd.call_source_name;
1036 ch =
ast_channel_alloc(1, state, cid_num, cid_name, pvt->
accountcode, pvt->
exten, pvt->
context, linkedid, pvt->
amaflags,
"H323/%s", host);
1043 fmt = global_options.capability;
1057 #ifdef VIDEO_SUPPORT
1072 if (pvt->
options.dtmfmode & H323_DTMF_INBAND) {
1098 if (pvt->
cd.redirect_reason >= 0) {
1110 if (pvt->
cd.transfer_capability >= 0)
1134 pvt->
cd.redirect_reason = -1;
1135 pvt->
cd.transfer_capability = -1;
1138 if ((pvt->
cd).call_token == NULL) {
1141 if (!pvt->
cd.call_token) {
1147 memset((
char *)(pvt->
cd).call_token, 0, 128);
1148 pvt->
cd.call_reference = callid;
1152 if (pvt->
options.dtmfmode & (H323_DTMF_RFC2833 | H323_DTMF_CISCO)) {
1175 if (!pvt->
needdestroy && ((
signed int)pvt->
cd.call_reference == call_reference)) {
1177 if ((token != NULL) && (pvt->
cd.call_token != NULL) && (!strcmp(pvt->
cd.call_token, token))) {
1181 }
else if (token == NULL) {
1217 struct oh323_alias *alias;
1225 if (!(alias =
ast_calloc(1,
sizeof(*alias))))
1231 for (; v || ((v = alt) && !(alt = NULL)); v = v->
next) {
1232 if (!strcasecmp(v->
name,
"e164")) {
1234 }
else if (!strcasecmp(v->
name,
"prefix")) {
1236 }
else if (!strcasecmp(v->
name,
"context")) {
1238 }
else if (!strcasecmp(v->
name,
"secret")) {
1241 if (strcasecmp(v->
value,
"h323")) {
1253 struct oh323_alias *a;
1260 for (tmp = var; tmp; tmp = tmp->
next) {
1261 if (!strcasecmp(tmp->
name,
"type") &&
1262 !(!strcasecmp(tmp->
value,
"alias") || !strcasecmp(tmp->
value,
"h323"))) {
1280 if (!strcasecmp(v->
name,
"allow")) {
1282 }
else if (!strcasecmp(v->
name,
"autoframing")) {
1284 }
else if (!strcasecmp(v->
name,
"disallow")) {
1286 }
else if (!strcasecmp(v->
name,
"dtmfmode")) {
1288 if ((opt = strchr(val,
':')) != (
char *)NULL) {
1292 if (!strcasecmp(v->
value,
"inband")) {
1293 options->dtmfmode |= H323_DTMF_INBAND;
1294 }
else if (!strcasecmp(val,
"rfc2833")) {
1295 options->dtmfmode |= H323_DTMF_RFC2833;
1297 options->dtmfcodec[0] = H323_DTMF_RFC2833_PT;
1298 }
else if ((tmp >= 96) && (tmp < 128)) {
1299 options->dtmfcodec[0] = tmp;
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]);
1304 }
else if (!strcasecmp(val,
"cisco")) {
1305 options->dtmfmode |= H323_DTMF_CISCO;
1307 options->dtmfcodec[1] = H323_DTMF_CISCO_PT;
1308 }
else if ((tmp >= 96) && (tmp < 128)) {
1309 options->dtmfcodec[1] = tmp;
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]);
1314 }
else if (!strcasecmp(v->
value,
"h245-signal")) {
1315 options->dtmfmode |= H323_DTMF_SIGNAL;
1319 }
else if (!strcasecmp(v->
name,
"dtmfcodec")) {
1321 tmp = atoi(v->
value);
1325 options->dtmfcodec[0] = tmp;
1326 }
else if (!strcasecmp(v->
name,
"bridge")) {
1328 }
else if (!strcasecmp(v->
name,
"nat")) {
1330 }
else if (!strcasecmp(v->
name,
"fastStart")) {
1332 }
else if (!strcasecmp(v->
name,
"h245Tunneling")) {
1334 }
else if (!strcasecmp(v->
name,
"silenceSuppression")) {
1336 }
else if (!strcasecmp(v->
name,
"progress_setup")) {
1337 tmp = atoi(v->
value);
1338 if ((tmp != 0) && (tmp != 1) && (tmp != 3) && (tmp != 8)) {
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)) {
1349 options->progress_alert = tmp;
1350 }
else if (!strcasecmp(v->
name,
"progress_audio")) {
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")) {
1356 }
else if (!strcasecmp(v->
name,
"cid_number")) {
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;
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;
1386 struct oh323_user *
user;
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;
1406 ast_copy_string(user->context, default_context,
sizeof(user->context));
1411 if (user->chanvars) {
1413 user->chanvars = NULL;
1417 for (; v || ((v = alt) && !(alt = NULL)); v = v->
next) {
1420 if (!strcasecmp(v->
name,
"context")) {
1422 }
else if (!strcasecmp(v->
name,
"secret")) {
1424 }
else if (!strcasecmp(v->
name,
"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");
1434 tmp.
ss.ss_family = AF_INET;
1443 }
else if (!strcasecmp(v->
name,
"amaflags")) {
1450 }
else if (!strcasecmp(v->
name,
"permit") ||
1451 !strcasecmp(v->
name,
"deny")) {
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;
1473 struct oh323_user *
user;
1474 const char *username;
1479 username = (
char *)NULL;
1486 for (tmp = var; tmp; tmp = tmp->
next) {
1487 if (!strcasecmp(tmp->
name,
"type") &&
1488 !(!strcasecmp(tmp->
value,
"user") || !strcasecmp(tmp->
value,
"friend"))) {
1491 }
else if (!username && !strcasecmp(tmp->
name,
"name"))
1492 username = tmp->
value;
1496 ast_log(
LOG_WARNING,
"Cannot determine user name for IP address %s\n", cd->sourceIp);
1510 struct oh323_peer *peer;
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;
1534 if (peer->chanvars) {
1536 peer->chanvars = NULL;
1540 peer->mailbox[0] =
'\0';
1542 for (; v || ((v = alt) && !(alt = NULL)); v = v->
next) {
1545 if (!strcasecmp(v->
name,
"host")) {
1546 if (!strcasecmp(v->
value,
"dynamic")) {
1554 tmp.
ss.ss_family = AF_INET;
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")) {
1571 }
else if (!strcasecmp(v->
name,
"mailbox")) {
1573 }
else if (!strcasecmp(v->
name,
"hasvoicemail")) {
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;
1590 static struct oh323_peer *
realtime_peer(
const char *peername,
struct sockaddr_in *sin)
1592 struct oh323_peer *peer;
1595 const char *addr = NULL;
1608 for (tmp = var; tmp; tmp = tmp->
next) {
1610 if (!strcasecmp(tmp->
name,
"type") &&
1611 !(!strcasecmp(tmp->
value,
"peer") || !strcasecmp(tmp->
value,
"friend"))) {
1614 }
else if (!peername && !strcasecmp(tmp->
name,
"name")) {
1615 peername = tmp->
value;
1638 static struct oh323_user *
find_user(
const call_details_t *cd,
int realtime)
1640 struct oh323_user *u;
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);
1668 static struct oh323_peer *
find_peer(
const char *peer,
struct sockaddr_in *sin,
int realtime)
1670 struct oh323_peer *p;
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>"));
1690 struct oh323_peer *p;
1695 char peer[256] =
"";
1698 port = strchr(peer,
':');
1703 pvt->
sa.sin_family = AF_INET;
1710 if (pvt->
options.dtmfmode & H323_DTMF_RFC2833) {
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;
1725 portno = atoi(port);
1731 memcpy(&pvt->
sa.sin_addr, hp->h_addr,
sizeof(pvt->
sa.sin_addr));
1732 pvt->
sa.sin_port = htons(portno);
1735 memcpy(&pvt->
options, (p ? &p->options : &global_options),
sizeof(pvt->
options));
1741 if (pvt->
options.dtmfmode & H323_DTMF_RFC2833) {
1752 }
else if (!found) {
1762 char *dest = (
char *)data;
1764 char *h323id = NULL;
1765 char tmp[256], tmp1[256];
1784 host = strchr(tmp,
'@');
1790 ext = strrchr(tmp,
'/');
1795 strtok_r(host,
"/", &(h323id));
1797 h323_set_id(h323id);
1805 if (gatekeeper_disable) {
1817 if (pvt->
options.dtmfmode & H323_DTMF_RFC2833) {
1827 snprintf(tmp1,
sizeof(tmp1)-1,
"%s-%u", host, ++unique);
1828 tmp1[
sizeof(tmp1)-1] =
'\0';
1845 static struct oh323_alias *
find_alias(
const char *source_aliases,
int realtime)
1847 struct oh323_alias *a;
1861 static int receive_digit(
unsigned call_reference,
char digit,
const char *token,
int duration)
1868 ast_log(
LOG_ERROR,
"Received digit '%c' (%u ms) for call %s without private structure\n", digit, duration, token);
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);
1880 .subclass.integer = digit,
1881 .samples = duration * 8,
1883 .src =
"SEND_DIGIT",
1932 struct sockaddr_in us;
1933 struct rtp_info *info;
1937 ast_log(
LOG_ERROR,
"Unable to allocated info structure, this is very bad\n");
1951 ast_log(
LOG_ERROR,
"No RTP stream is available for call %s (%d)", token, call_reference);
1964 info->port = ntohs(us.sin_port);
1966 ast_debug(1,
"Sending RTP 'US' %s:%d\n", info->addr, info->port);
1975 static void setup_rtp_connection(
unsigned call_reference,
const char *remoteIp,
int remotePort,
const char *token,
int pt)
1978 struct sockaddr_in them;
1979 int nativeformats_changed;
1980 enum { NEED_NONE, NEED_HOLD, NEED_UNHOLD } rtp_change = NEED_NONE;
1983 ast_debug(1,
"Setting up RTP connection for %s\n", token);
2003 them.sin_family = AF_INET;
2005 them.sin_addr.s_addr = inet_addr(remoteIp);
2006 them.sin_port = htons(remotePort);
2008 if (them.sin_addr.s_addr) {
2017 rtp_change = NEED_UNHOLD;
2023 rtp_change = NEED_HOLD;
2028 nativeformats_changed = 0;
2029 if (pt != 128 && pvt->
rtp) {
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);
2035 nativeformats_changed = 1;
2037 }
else if (h323debug)
2041 if (nativeformats_changed || pvt->
options.progress_audio || (rtp_change != NEED_NONE)) {
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));
2053 if (pvt->
options.progress_audio)
2055 switch (rtp_change) {
2068 if (pvt->
options.progress_audio)
2070 else if (rtp_change == NEED_HOLD)
2072 else if (rtp_change == NEED_UNHOLD)
2075 ast_debug(1,
"RTP connection preparation for %s is pending...\n", token);
2081 ast_debug(1,
"RTP connection prepared for %s\n", token);
2095 ast_debug(1,
"Call %s answered\n", token);
2117 static int progress(
unsigned call_reference,
const char *token,
int inband)
2122 ast_debug(1,
"Received ALERT/PROGRESS message for %s tones\n", (inband ?
"inband" :
"self-generated"));
2131 ast_log(
LOG_ERROR,
"No Asterisk channel associated with private structure.\n");
2148 struct oh323_user *
user = NULL;
2149 struct oh323_alias *alias = NULL;
2152 ast_debug(1,
"Setting up incoming call for %s\n", cd->call_token);
2158 ast_log(
LOG_ERROR,
"Unable to allocate private structure, this is bad.\n");
2164 memcpy(&pvt->
cd, cd,
sizeof(pvt->
cd));
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);
2181 if ((!strcasecmp(cd->sourceIp, gatekeeper)) && (gkroute == -1) && !gatekeeper_disable) {
2188 ast_log(
LOG_ERROR,
"Call for %s rejected, alias not found\n", cd->call_dest_alias);
2200 if (!acceptAnonymous) {
2201 ast_log(
LOG_NOTICE,
"Anonymous call from '%s@%s' rejected\n", pvt->
cd.call_source_aliases, pvt->
cd.sourceIp);
2206 ast_log(
LOG_ERROR,
"Call from '%s@%s' rejected due to no default context\n", pvt->
cd.call_source_aliases, pvt->
cd.sourceIp);
2217 ast_debug(1,
"Sending %s@%s to context [%s] extension %s\n", cd->call_source_aliases, cd->sourceIp, pvt->
context, pvt->
exten);
2220 if (strcasecmp(cd->sourceIp,
ast_inet_ntoa(user->addr.sin_addr))) {
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);
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);
2251 if (user->amaflags) {
2269 enum {ext_original, ext_s, ext_i, ext_notexists} try_exten;
2270 char tmp_exten[
sizeof(pvt->
exten)];
2273 ast_debug(1,
"Preparing Asterisk to answer for %s\n", token);
2285 if ((tmp_exten[0] !=
'\0') && (tmp_exten[1] ==
'\0')) {
2286 if (tmp_exten[0] ==
's')
2288 else if (tmp_exten[0] ==
'i')
2291 try_exten = ext_original;
2293 try_exten = ext_original;
2297 switch (try_exten) {
2300 tmp_exten[1] =
'\0';
2308 try_exten = ext_notexists;
2313 }
while (try_exten != ext_notexists);
2316 if (try_exten == ext_notexists) {
2321 }
else if ((try_exten != ext_original) && (strcmp(pvt->
exten, tmp_exten) != 0)) {
2387 ast_debug(1,
"Cleaning connection to %s\n", call_token);
2393 ast_debug(1,
"No connection for %s\n", call_token);
2400 #ifdef DEBUG_THREADS
2431 ast_debug(1,
"Connection to %s cleaned\n", call_token);
2440 ast_debug(1,
"Hanging up connection to %s with cause %d\n", token, cause);
2445 ast_debug(1,
"Connection to %s already cleared\n", token);
2458 ast_debug(1,
"Hangup for %s is pending\n", token);
2463 static void set_dtmf_payload(
unsigned call_reference,
const char *token,
int payload,
int is_cisco)
2468 ast_debug(1,
"Setting %s DTMF payload to %d on %s\n", (is_cisco ?
"Cisco" :
"RFC2833"), payload, token);
2477 pvt->
dtmf_pt[is_cisco ? 1 : 0] = payload;
2480 ast_debug(1,
"DTMF payload on %s set to %d\n", token, payload);
2488 ast_debug(1,
"Got remote capabilities from connection %s\n", token);
2499 for (i = 0; i < 32; ++i) {
2500 if (!prefs->
order[i])
2506 if (pvt->
options.autoframing) {
2507 ast_debug(2,
"Autoframing option set, using peer's packetization settings\n");
2510 ast_debug(2,
"Autoframing option not set, ignoring peer's packetization settings\n");
2525 ast_debug(1,
"Setting capabilities for connection %s\n", token);
2531 dtmfmode = pvt->
options.dtmfmode;
2535 h323_set_capabilities(token, capability, dtmfmode, &prefs, pref_codec);
2539 for (i = 0; i < 32; i++) {
2540 if (!prefs.
order[i])
2544 ast_debug(1,
"Capabilities for connection %s is set\n", token);
2548 static void remote_hold(
unsigned call_reference,
const char *token,
int is_hold)
2553 ast_debug(1,
"Setting %shold status for connection %s\n", (is_hold ?
"" :
"un"), token);
2594 for (oh323 =
iflist; oh323; oh323 = oh323->
next) {
2614 oh323 = oh323->
next;
2621 pthread_testcancel();
2624 if ((res < 0) || (res > 1000)) {
2631 pthread_testcancel();
2653 if (monitor_thread == pthread_self()) {
2660 pthread_kill(monitor_thread, SIGURG);
2678 e->
command =
"h323 set trace [on|off]";
2680 "Usage: h323 set trace (on|off|<trace level>)\n"
2681 " Enable/Disable H.323 stack tracing for debugging purposes\n";
2689 if (!strcasecmp(a->
argv[3],
"off")) {
2691 ast_cli(a->
fd,
"H.323 Trace Disabled\n");
2692 }
else if (!strcasecmp(a->
argv[3],
"on")) {
2694 ast_cli(a->
fd,
"H.323 Trace Enabled\n");
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);
2707 e->
command =
"h323 set debug [on|off]";
2709 "Usage: h323 set debug [on|off]\n"
2710 " Enable/Disable H.323 debugging output\n";
2718 if (strcasecmp(a->
argv[3],
"on") && strcasecmp(a->
argv[3],
"off"))
2721 h323debug = (strcasecmp(a->
argv[3],
"on")) ? 0 : 1;
2722 ast_cli(a->
fd,
"H.323 Debugging %s\n", h323debug ?
"Enabled" :
"Disabled");
2732 "Usage: h323 cycle gk\n"
2733 " Manually re-register with the Gatekeper (Currently Disabled)\n";
2745 if (!gatekeeper_disable) {
2746 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
2759 "Usage: h323 hangup <token>\n"
2760 " Manually try to hang up the call identified by <token>\n";
2768 if (h323_soft_hangup(a->
argv[2])) {
2780 e->
command =
"h323 show tokens";
2782 "Usage: h323 show tokens\n"
2783 " Print out all active call tokens\n";
2801 e->
command =
"h323 show version";
2803 "Usage: h323 show version\n"
2804 " Show the version of the H.323 library in use\n";
2813 h323_show_version();
2881 struct oh323_peer *peer = NULL;
2882 struct oh323_user *
user = NULL;
2883 struct oh323_alias *alias = NULL;
2887 int is_user, is_peer, is_alias;
2888 char _gatekeeper[100];
2889 int gk_discover, gk_disable, gk_changed;
2903 ast_log(
LOG_ERROR,
"Config file users.conf is in an invalid format. Aborting.\n");
2908 ast_log(
LOG_ERROR,
"Config file %s is in an invalid format. Aborting.\n", config);
2913 ast_log(
LOG_ERROR,
"Config file %s is in an invalid format. Aborting.\n", config);
2918 ast_log(
LOG_ERROR,
"Config file users.conf is in an invalid format. Aborting.\n");
2931 if (!h323_end_point_exist()) {
2932 h323_end_point_create();
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;
2946 global_options.bridge = 1;
2947 global_options.autoframing = 0;
2948 strcpy(default_context,
"default");
2949 h323_signalling_port = 1720;
2950 gatekeeper_disable = 1;
2951 gatekeeper_discover = 0;
2954 acceptAnonymous = 1;
2964 const char *has_h323;
2969 if (strcasecmp(cat,
"general")) {
2971 if (
ast_true(has_h323) || (!has_h323 && genhas_h323)) {
2993 if (!strcasecmp(v->
name,
"port")) {
2994 h323_signalling_port = (int)strtol(v->
value, NULL, 10);
2995 }
else if (!strcasecmp(v->
name,
"bindaddr")) {
3001 }
else if (!strcasecmp(v->
name,
"tos")) {
3002 ast_log(
LOG_WARNING,
"The \"tos\" setting is deprecated in this version of Asterisk. Please change to \"tos_audio\".\n");
3006 }
else if (!strcasecmp(v->
name,
"tos_audio")) {
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");
3015 }
else if (!strcasecmp(v->
name,
"cos_audio")) {
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;
3026 gatekeeper_disable = 0;
3029 }
else if (!strcasecmp(v->
name,
"secret")) {
3031 }
else if (!strcasecmp(v->
name,
"AllowGKRouted")) {
3033 }
else if (!strcasecmp(v->
name,
"context")) {
3035 ast_verb(2,
"Setting default context to %s\n", default_context);
3036 }
else if (!strcasecmp(v->
name,
"UserByAlias")) {
3038 }
else if (!strcasecmp(v->
name,
"AcceptAnonymous")) {
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;
3052 if (strcasecmp(cat,
"general")) {
3055 is_user = is_peer = is_alias = 0;
3056 if (!strcasecmp(utype,
"user"))
3058 else if (!strcasecmp(utype,
"peer"))
3060 else if (!strcasecmp(utype,
"friend"))
3061 is_user = is_peer = 1;
3062 else if (!strcasecmp(utype,
"h323") || !strcasecmp(utype,
"alias"))
3100 if (h323_set_alias(iterator)) {
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;
3120 if (!gatekeeper_disable) {
3121 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
3123 gatekeeper_disable = 1;
3133 if (h323_reloading) {
3134 ast_verbose(
"Previous H.323 reload not yet done\n");
3149 "Usage: h323 reload\n"
3150 " Reloads H.323 configuration from h323.conf\n";
3172 if (!sched || !io) {
3173 ast_log(
LOG_NOTICE,
"Unload and load chan_h323.so again in order to receive configuration changes.\n");
3203 static char *convertcap(
format_t cap)
3235 struct sockaddr_in them = { 0, };
3236 struct sockaddr_in us = { 0, };
3263 h323_native_bridge(pvt->
cd.call_token,
ast_inet_ntoa(them.sin_addr), mode);
3296 ast_log(
LOG_NOTICE,
"Unload and load chan_h323.so again in order to receive configuration changes.\n");
3345 if (h323_start_listener(h323_signalling_port,
bindaddr)) {
3364 if (!gatekeeper_disable) {
3365 if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
3367 gatekeeper_disable = 1;
3405 if (monitor_thread != pthread_self()) {
3406 pthread_cancel(monitor_thread);
3408 pthread_kill(monitor_thread, SIGURG);
3409 pthread_join(monitor_thread, NULL);
3433 if (!gatekeeper_disable)
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
static struct ast_frame * oh323_rtp_read(struct oh323_pvt *pvt)
Retrieve audio/etc from channel. Assumes pvt->lock is already held.
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.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
union ast_frame_subclass subclass
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
struct sockaddr_storage ss
enum sip_cc_notify_state state
static char accountcode[AST_MAX_ACCOUNT_CODE]
int presentation
Q.931 encoded presentation-indicator encoded field.
#define ast_channel_lock(chan)
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...
Main Channel structure associated with a channel.
static char default_context[AST_MAX_CONTEXT]
#define AST_CLI_DEFINE(fn, txt,...)
char * str
Subscriber phone number (Malloced)
static struct oh323_user * build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
struct ast_party_connected_line connected
Channel Connected Line ID information.
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
Asterisk locking-related definitions:
static char * handle_cli_h323_show_tokens(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Asterisk main include file. File version handling, generic pbx functions.
static struct oh323_pvt * find_call_locked(int call_reference, const char *token)
static const char config[]
receive_digit_cb on_receive_digit
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
static char * handle_cli_h323_cycle_gk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static ast_mutex_t monlock
Protect the H.323 monitoring thread, so only one process can kill or start it, and not when it's doin...
char * str
Subscriber phone number (Malloced)
void ast_module_unref(struct ast_module *)
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame with payload.
struct ast_frame ast_null_frame
struct ast_party_caller caller
Channel Caller ID information.
setup_incoming_cb on_incoming_call
static ast_mutex_t h323_reload_lock
Protect the reload process.
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
start_rtp_cb on_start_rtp_channel
static call_options_t * setup_incoming_call(call_details_t *cd)
Call-back function for incoming calls.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload)
Retrieve payload information by payload.
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
static void delete_aliases(void)
#define ASTOBJ_CONTAINER_FIND_UNLINK_FULL(container, data, field, hashfunc, hashoffset, comparefunc)
Find and remove an object in a container.
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.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
static int oh323_answer(struct ast_channel *c)
struct ast_party_id id
Connected party ID.
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
static struct oh323_alias * realtime_alias(const char *alias)
static struct oh323_user * realtime_user(const call_details_t *cd)
struct ast_rtp_instance * rtp
char order[sizeof(format_t)*8]
static enum ast_module_load_result load_module(void)
struct ast_party_name name
Subscriber name.
static struct ast_cli_entry cli_h323_reload
#define AST_FORMAT_G723_1
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
void ast_dsp_free(struct ast_dsp *dsp)
#define DSP_FEATURE_DIGIT_DETECT
#define AST_CAUSE_UNALLOCATED
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.
Convenient Signal Processing routines.
char context[AST_MAX_CONTEXT]
#define ASTOBJ_MARK(object)
Mark an ASTOBJ by adding the ASTOBJ_FLAG_MARKED flag to its objflags mask.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
clear_con_cb on_connection_cleared
#define DEADLOCK_AVOIDANCE(lock)
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
static int __oh323_rtp_create(struct oh323_pvt *pvt)
descriptor for a cli entry.
static struct oh323_peer * find_peer(const char *peer, struct sockaddr_in *sin, int realtime)
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
static struct aji_capabilities * capabilities
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
static void oh323_destroy_alias(struct oh323_alias *alias)
void ast_verbose(const char *fmt,...)
struct ast_dsp * ast_dsp_new(void)
static int update_state(struct oh323_pvt *pvt, int state, int signal)
#define ASTOBJ_UNMARK(object)
Unmark an ASTOBJ by subtracting the ASTOBJ_FLAG_MARKED flag from its objflags mask.
Structure for variables, used for configurations and for channel variables.
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.
static int create_addr(struct oh323_pvt *pvt, char *opeer)
static struct ast_channel * oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
setup_outbound_cb on_outgoing_call
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
static int h323_reloading
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.
#define ast_rtp_glue_register(glue)
static const char * redirectingreason2str(int redirectingreason)
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
static int reload_config(int is_reload)
static struct oh323_alias * find_alias(const char *source_aliases, int realtime)
Find a call by alias.
Configuration File Parser.
char * str
Subscriber name (Malloced)
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
static void delete_users(void)
static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
static struct h323_user_list userl
format_t ast_best_codec(format_t fmts)
Pick the best audio codec.
ASTOBJ_CONTAINER_COMPONENTS(struct oh323_user)
on_rtp_cb on_external_rtp_create
static void cleanup_call_details(call_details_t *cd)
#define ast_mutex_lock(a)
static void oh323_destroy_peer(struct oh323_peer *peer)
unsigned short transfercapability
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 ...
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
static int oh323_hangup(struct ast_channel *c)
static int gatekeeper_disable
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
static void oh323_update_info(struct ast_channel *c)
Only channel structure should be locked.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
static int gatekeeper_discover
static void * do_monitor(void *data)
I/O Management (derived from Cheops-NG)
static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration)
Send (play) the specified digit to the channel.
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
static int oh323_digit_begin(struct ast_channel *c, char digit)
void ast_update_use_count(void)
Notify when usecount has been changed.
static void oh323_destroy(struct oh323_pvt *pvt)
const ast_string_field linkedid
char exten[AST_MAX_EXTENSION]
static struct oh323_user * find_user(const call_details_t *cd, int realtime)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
static char * handle_cli_h323_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Socket address structure.
static char cid_num[AST_MAX_EXTENSION]
#define ast_verb(level,...)
ASTOBJ_CONTAINER_COMPONENTS(struct oh323_peer)
answer_call_cb on_answer_call
void ast_config_destroy(struct ast_config *config)
Destroys a config.
static char gatekeeper[100]
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,...)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
String fields in structures.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
int args
This gets set in ast_cli_register()
static void set_dtmf_payload(unsigned call_reference, const char *token, int payload, int is_cisco)
struct ast_codec_pref peer_prefs
#define ASTOBJ_CONTAINER_WRLOCK(container)
Lock an ASTOBJ_CONTAINER for writing.
#define ast_pthread_create_background(a, b, c, d)
#define ASTOBJ_CONTAINER_INIT(container)
Initialize a container.
static int answer_call(unsigned call_reference, const char *token)
Call-back function to start PBX when OpenH323 ready to serve incoming call.
internal representation of acl entries In principle user applications would have no need for this...
struct ast_party_id id
Caller party ID.
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 "format" is ...
static struct ast_cli_entry cli_h323[]
static char * handle_cli_h323_set_trace(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 "format" is be...
#define ast_debug(level,...)
Log a DEBUG message.
Private structure of a OpenH323 channel.
static void cleanup_connection(unsigned call_reference, const char *call_token)
Call-back function to cleanup communication Returns nothing,.
void ast_rtp_instance_stop(struct ast_rtp_instance *instance)
Stop an RTP instance.
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.
struct ast_party_id ani
Automatic Number Identification (ANI)
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)
#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...
void io_context_destroy(struct io_context *ioc)
Destroys a context.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
struct sockaddr_in redirip
#define ast_mutex_trylock(a)
static struct oh323_pvt * iflist
static struct ast_generator gen
static struct h323_alias_list aliasl
#define ast_config_load(filename, flags)
Load a config file.
static void hangup_connection(unsigned int call_reference, const char *token, int cause)
#define AST_PTHREADT_NULL
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Access Control of various sorts.
Global IO variables are now in a struct in order to be made threadsafe.
#define AST_MAX_EXTENSION
#define AST_CAUSE_NORMAL_CLEARING
Scheduler Routines (derived from cheops)
#define AST_FORMAT_G726_AAL2
#define ao2_ref(o, delta)
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
Channel and private structures should be already locked.
static int update_common_options(struct ast_variable *v, struct call_options *options)
static void connection_made(unsigned call_reference, const char *token)
Call-back function to signal asterisk that the channel has been answered Returns nothing.
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...
static const char tdesc[]
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.
static unsigned int unique
#define ASTOBJ_INIT(object)
Initialize an object.
#define AST_CAUSE_NO_ANSWER
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
static struct ast_frame * oh323_read(struct ast_channel *c)
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.
static struct ast_jb_conf default_jbconf
Global jitterbuffer configuration - by default, jb is disabled.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
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's frame queue.
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
static struct sched_context * sched
#define ASTOBJ_UNREF(object, destructor)
Decrement the reference count on an object.
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.
struct ast_party_dialed dialed
Dialed/Called information.
static char * handle_cli_h323_hangup(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int oh323_addrcmp_str(struct in_addr inaddr, char *addr)
char * ast_getformatname(format_t format)
Get the name of a format.
#define ASTOBJ_CONTAINER_DESTROY(container)
Destroy a container.
#define ASTOBJ_CONTAINER_DESTROYALL(container, destructor)
Empty a container.
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 "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
void sched_context_destroy(struct sched_context *c)
destroys a schedule context Destroys (free's) the given sched_context structure
static int h323_signalling_port
#define ASTOBJ_CONTAINER_LINK(container, newobj)
Add an object to a container.
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
static struct ast_codec_pref prefs
static struct ast_channel_tech oh323_tech
int ast_cdr_amaflags2int(const char *flag)
Convert a string to a detail record AMA flag.
enum ast_channel_state _state
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
const ast_string_field name
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
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...
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 "find_best" is no...
#define ASTOBJ_CONTAINER_TRAVERSE(container, continue, eval)
Iterate through the objects in a container.
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
static struct oh323_peer * build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
static struct oh323_peer * realtime_peer(const char *peername, struct sockaddr_in *sin)
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
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)
static pthread_t monitor_thread
This is the thread for the monitor which checks for input on the channels which are not currently in ...
#define ast_channel_unlock(chan)
static void set_local_capabilities(unsigned call_reference, const char *token)
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
#define ASTOBJ_UNLOCK(object)
Unlock a locked object.
#define ASTOBJ_CONTAINER_FIND(container, namestr)
Find an object in a container.
#define ASTOBJ_CONTAINER_UNLOCK(container)
Unlock an ASTOBJ_CONTAINER.
struct ast_channel * owner
#define AST_FORMAT_AUDIO_MASK
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.
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
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.
int ast_udptl_fd(const struct ast_udptl *udptl)
int ast_rtp_instance_fd(struct ast_rtp_instance *instance, int rtcp)
Get the file descriptor for an RTP session (or RTCP)
static format_t capability
static int oh323_simulate_dtmf_end(const void *data)
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.
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
int connection_established
static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
static int setup_outgoing_call(call_details_t *cd)
Call-back function to establish an outgoing H.323 call.
if(yyss+yystacksize-1<=yyssp)
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.
Structure used to handle boolean flags.
int ast_rtp_instance_destroy(struct ast_rtp_instance *instance)
Destroy an RTP instance.
#define ast_clear_flag(p, flag)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
static char cid_name[AST_MAX_EXTENSION]
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
int ast_sched_runq(struct sched_context *con)
Runs the queue.
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...
static struct sockaddr_in bindaddr
static void chan_ringing(unsigned call_reference, const char *token)
Call-back function to signal asterisk that the channel is ringing Returns nothing.
static int restart_monitor(void)
static char * handle_cli_h323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
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.
static struct ast_jb_conf global_jbconf
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
static int unload_module(void)
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
static void remote_hold(unsigned call_reference, const char *token, int is_hold)
#define AST_FORMAT_SLINEAR
struct sched_context * sched_context_create(void)
New schedule context.
Channels have this property if they can create jitter; i.e. most VoIP channels.
Standard Command Line Interface.
#define ASTOBJ_RDLOCK(object)
Lock an ASTOBJ for reading.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static int h323_do_reload(void)
static void oh323_destroy_user(struct oh323_user *user)
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
#define AST_CAUSE_USER_BUSY
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...
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
#define AST_PTHREADT_STOP
int ast_rtp_glue_unregister(struct ast_rtp_glue *glue)
Unregister RTP glue.
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
static void __oh323_destroy(struct oh323_pvt *pvt)
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
Data structure associated with a single frame of data.
#define ASTOBJ_CONTAINER_FIND_FULL(container, data, field, hashfunc, hashoffset, comparefunc)
Find an object in a container.
Internal Asterisk hangup causes.
setpeercapabilities_cb on_setpeercapabilities
con_established_cb on_connection_established
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.
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
static int progress(unsigned call_reference, const char *token, int inband)
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.
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
char context[AST_MAX_CONTEXT]
enum ast_frame_type frametype
struct ast_variable * next
static struct ast_rtp_glue oh323_rtp_glue
static void prune_peers(void)
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
static int acceptAnonymous
static call_options_t global_options
unsigned char valid
TRUE if the name information is valid/present.
#define CONFIG_STATUS_FILEINVALID
static char * handle_cli_h323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define ast_mutex_destroy(a)
static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
static ast_mutex_t iflock
static struct h323_peer_list peerl
#define GLOBAL_CAPABILITY
#define ASTERISK_GPL_KEY
The text the key() function should return.
static struct oh323_pvt * oh323_alloc(int callid)
#define AST_CAUSE_CALL_REJECTED
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.
setcapabilities_cb on_setcapabilities
Asterisk module definitions.
static struct hostent * hp
rfc2833_cb on_set_rfc2833_payload
static int h323_reload(void)
static snd_pcm_format_t format
union ast_frame::@172 data
struct ast_channel_tech * tech
unsigned char valid
TRUE if the number information is valid/present.
General jitterbuffer configuration.
static ast_mutex_t caplock
Protect the H.323 capabilities list, to avoid more than one channel to set the capabilities simultane...
char exten[AST_MAX_EXTENSION]
#define AST_MUTEX_DEFINE_STATIC(mutex)
Structure for mutex and tracking information.
int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing)
Parse an "allow" or "deny" line in a channel or device configuration and update the capabilities mask...
static struct io_context * io
chan_ringing_cb on_chan_ringing
struct ast_frame * ast_rtp_instance_read(struct ast_rtp_instance *instance, int rtcp)
Receive a frame over RTP.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static int oh323_addrcmp(struct sockaddr_in addr, struct sockaddr_in *sin)
#define ASTOBJ_CONTAINER_PRUNE_MARKED(container, destructor)
Prune marked objects from a container.
static struct oh323_alias * build_alias(const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime)
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
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.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
struct ast_module * ast_module_ref(struct ast_module *)
struct ast_party_number number
Subscriber phone number.
int ast_rtp_instance_dtmf_end(struct ast_rtp_instance *instance, char digit)
Stop sending a DTMF digit.
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...
static void set_peer_capabilities(unsigned call_reference, const char *token, int capabilities, struct ast_codec_pref *prefs)