41 #include <sys/socket.h>
42 #include <sys/ioctl.h>
46 #include <sys/signal.h>
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/ip.h>
51 #include <arpa/inet.h>
89 #define DEFAULT_EXPIRY 120
90 #define MAX_EXPIRY 3600
94 #define INADDR_NONE (in_addr_t)(-1)
103 .resync_threshold = 1000,
109 static const char tdesc[] =
"Media Gateway Control Protocol (MGCP)";
110 static const char config[] =
"mgcp.conf";
112 #define MGCP_DTMF_RFC2833 (1 << 0)
113 #define MGCP_DTMF_INBAND (1 << 1)
114 #define MGCP_DTMF_HYBRID (1 << 2)
116 #define DEFAULT_MGCP_GW_PORT 2427
117 #define DEFAULT_MGCP_CA_PORT 2727
118 #define MGCP_MAX_PACKET 1500
119 #define DEFAULT_RETRANS 1000
120 #define MAX_RETRANS 5
123 #define MGCP_CX_SENDONLY 0
124 #define MGCP_CX_RECVONLY 1
125 #define MGCP_CX_SENDRECV 2
126 #define MGCP_CX_CONF 3
127 #define MGCP_CX_CONFERENCE 3
128 #define MGCP_CX_MUTE 4
129 #define MGCP_CX_INACTIVE 4
174 }
qos = { 0, 0, 0, 0 };
243 #define MGCP_MAX_HEADERS 64
244 #define MGCP_MAX_LINES 64
274 #define RESPONSE_TIMEOUT 30
295 #define MGCP_SUBCHANNEL_MAGIC "!978!"
319 #define MGCP_ONHOOK 1
320 #define MGCP_OFFHOOK 2
440 int result,
unsigned int ident,
struct mgcp_request *resp);
466 .description =
tdesc,
548 if (gw->
addr.sin_addr.s_addr)
549 res=sendto(mgcpsock, data, len, 0, (
struct sockaddr *)&gw->
addr,
sizeof(
struct sockaddr_in));
551 res=sendto(mgcpsock, data, len, 0, (
struct sockaddr *)&gw->
defaddr,
sizeof(
struct sockaddr_in));
586 for (prev = NULL, cur = gw->
msgs; cur; prev = cur, cur = cur->
next) {
589 prev->next = cur->
next;
664 for (prev = NULL, cur = gw->
msgs; cur; prev = cur, cur = cur->
next) {
667 ast_debug(1,
"Retransmitting #%d transaction %u on [%s]\n",
672 prev->next = cur->
next;
711 char *data,
int len,
unsigned int seqno)
718 if (!(msg =
ast_malloc(
sizeof(*msg) + len))) {
732 memcpy(msg->
buf, data, msg->
len);
735 for (cur = gw->
msgs; cur && cur->
next; cur = cur->
next);
811 memcpy(r, req,
sizeof(*r));
824 for (t = *queue; t && t->
next; t = t->
next);
843 const char *distinctive_ring = NULL;
853 if (strcasecmp(
ast_var_name(current),
"ALERT_INFO") == 0) {
862 snprintf(tone,
sizeof(tone),
"L/wt%s", distinctive_ring);
863 ast_debug(3,
"MGCP distinctive callwait %s\n", tone);
866 ast_debug(3,
"MGCP normal callwait %s\n", tone);
872 snprintf(tone,
sizeof(tone),
"L/r%s", distinctive_ring);
873 ast_debug(3,
"MGCP distinctive ring %s\n", tone);
930 ast_debug(1,
"Asked to hangup channel not connected\n");
934 ast_debug(1,
"Invalid magic. MGCP subchannel freed up already.\n");
1022 ast_verb(3,
"Enabling call waiting on %s\n", ast->
name);
1026 ast_debug(3,
"MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n",
1030 ast_debug(3,
"MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n",
1043 int hasendpoints = 0;
1048 e->
command =
"mgcp show endpoints";
1050 "Usage: mgcp show endpoints\n"
1051 " Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n";
1073 if (!hasendpoints) {
1074 ast_cli(a->
fd,
" << No Endpoints Defined >> ");
1086 char *ename,*gname, *c;
1090 e->
command =
"mgcp audit endpoint";
1092 "Usage: mgcp audit endpoint <endpointid>\n"
1093 " Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n"
1094 " mgcp debug MUST be on to see the results of this command.\n";
1107 for (gname = ename; *gname; gname++) {
1108 if (*gname ==
'@') {
1114 if (gname[0] ==
'[') {
1117 if ((c = strrchr(gname,
']'))) {
1122 if (!strcasecmp(mg->
name, gname)) {
1124 if (!strcasecmp(me->
name, ename)) {
1136 ast_cli(a->
fd,
" << Could not find endpoint >> ");
1146 e->
command =
"mgcp set debug {on|off}";
1148 "Usage: mgcp set debug {on|off}\n"
1149 " Enables/Disables dumping of MGCP packets for debugging purposes\n";
1158 if (!strncasecmp(a->
argv[e->
args - 1],
"on", 2)) {
1160 ast_cli(a->
fd,
"MGCP Debugging Enabled\n");
1161 }
else if (!strncasecmp(a->
argv[3],
"off", 3)) {
1163 ast_cli(a->
fd,
"MGCP Debugging Disabled\n");
1190 ast_verb(3,
"MGCP mgcp_answer(%s) on %s@%s-%d\n",
1258 ast_log(
LOG_WARNING,
"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
1270 ast_debug(1,
"GATE ALLOCATED, sending sdp\n");
1290 if (sub->
owner != oldchan) {
1295 sub->
owner = newchan;
1308 ast_debug(1,
"Sending DTMF using inband/hybrid\n");
1311 ast_debug(1,
"Sending DTMF using RFC2833\n");
1330 ast_debug(1,
"Stopping DTMF using inband/hybrid\n");
1333 ast_debug(1,
"Stopping DTMF using RFC2833\n");
1366 char *tmp, *endpt, *gw;
1370 if ((tmp = strchr(endpt,
'@'))) {
1378 if (strcasecmp(g->
name, gw) == 0) {
1387 for (; e; e = e->
next) {
1388 if (strcasecmp(e->
name, endpt) == 0) {
1411 return "Other end has hungup";
1413 return "Local ring";
1415 return "Remote end is ringing";
1417 return "Remote end has answered";
1419 return "Remote end is busy";
1421 return "Make it go off hook";
1423 return "Line is off hook";
1425 return "Congestion (circuits busy)";
1427 return "Flash hook";
1431 return "Set a low-level option";
1435 return "Un-Key Radio";
1445 ast_debug(3,
"MGCP asked to indicate %d '%s' condition on channel %s\n",
1450 #ifdef DLINK_BUGGY_FIRMWARE
1501 tmp =
ast_channel_alloc(1, state, i->
cid_num, i->
cid_name, linkedid, i->
accountcode, i->
exten, i->
context, i->
amaflags,
"MGCP/%s@%s-%d", i->
name, i->
parent->
name, sub->
id);
1555 char valuebuf[1024];
1569 ast_verb(3,
"MGCP mgcp_new(%s) created in state: %s\n",
1579 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] ==
'=') {
1580 char *r = line + nameLen + 1;
1581 while (*r && (*r < 33)) ++r;
1590 int len = strlen(name);
1593 for (x = 0; x < req->
lines; x++) {
1595 if (r[0] !=
'\0')
return r;
1607 int len = strlen(name);
1609 while (*iterator < req->
lines) {
1611 if (r[0] !=
'\0')
return r;
1619 int len = strlen(name);
1621 for (x = *start; x < req->
headers; x++) {
1622 if (!strncasecmp(req->
header[x], name, len) &&
1623 (req->
header[x][len] ==
':')) {
1624 r = req->
header[x] + len + 1;
1625 while (*r && (*r < 33)) {
1647 *next = NULL, *len = 0;
1648 if (!c)
return NULL;
1650 while (*c && (*c < 33 || *c ==
',')) {
1655 while (*c && (*c >= 33 && *c !=
',')) {
1661 s = NULL, *next = NULL;
1676 ast_debug(1,
"*** find Realtime MGCPGW\n");
1705 for (gwv = mgcpgwconfig; gwv; gwv = gwv->
next) {
1706 if (!strcasecmp(gwv->
name,
"lines")) {
1712 for (gwv = gwv && gwv->
next ? gwv : mgcpgwconfig; gwv->
next; gwv = gwv->
next);
1719 for (i = 0; i <
args.argc; i++) {
1723 for (epname = NULL; gwv->
next; gwv = gwv->
next) {
1724 if (!strcasecmp(gwv->
next->
name,
"line")) {
1733 epname->
next = NULL;
1738 for (gwv = mgcpgwconfig; gwv; gwv = gwv->
next) {
1764 char *at = NULL, *c;
1768 at = strchr(tmp,
'@');
1776 if (at && (at[0] ==
'[')) {
1778 c = strrchr(at,
']');
1784 if ((!name || !strcasecmp(g->
name, at)) &&
1785 (sin || g->
addr.sin_addr.s_addr || g->
defaddr.sin_addr.s_addr)) {
1787 if (sin && g->
dynamic && name) {
1788 if ((g->
addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1789 (g->
addr.sin_port != sin->sin_port)) {
1790 memcpy(&g->
addr, sin,
sizeof(g->
addr));
1793 struct sockaddr_in tmp3 = {0,};
1795 tmp3.sin_addr = g->
ourip;
1802 g->
ourip = tmp3.sin_addr;
1808 if (strcasecmp(g->
name, at)) {
1813 }
else if (!name && sin) {
1814 if ((g->
addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
1815 (g->
addr.sin_port != sin->sin_port)) {
1831 }
else if (name && !strcasecmp(p->
name, tmp)) {
1832 ast_debug(1,
"Coundn't determine subchannel, assuming current master %s@%s-%d\n",
1851 ast_log(
LOG_NOTICE,
"Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp);
1883 }
else if (*c ==
'\r') {
1906 req->
line[
f] = c + 1;
1907 }
else if (*c ==
'\r') {
1919 while (*c && *c < 33) c++;
1922 while (*c && (*c > 32)) c++;
1926 while (*c && (*c < 33)) c++;
1928 while (*c && (*c > 32)) c++;
1932 while (*c && (*c < 33)) c++;
1934 while (*c && (*c > 32)) c++;
1938 while (*c && (*c < 33)) c++;
1940 while (*c && (*c > 32)) c++;
1941 while (*c && (*c < 33)) c++;
1942 while (*c && (*c > 32)) c++;
1948 ast_debug(1,
"Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n",
1965 int peerNonCodecCapability;
1966 struct sockaddr_in sin;
1970 int codec, codec_count=0;
1973 char tmp1[256], tmp2[256], tmp3[256];
1979 ast_log(
LOG_WARNING,
"Insufficient information for SDP (m = '%s', c = '%s')\n", m, c);
1982 if (sscanf(c,
"IN IP4 %256s", host) != 1) {
1992 if (sscanf(m,
"audio %30d RTP/AVP %n", &portno, &len) != 1 || !len) {
1996 sin.sin_family = AF_INET;
1997 memcpy(&sin.sin_addr, hp->h_addr,
sizeof(sin.sin_addr));
1998 sin.sin_port = htons(portno);
2006 if (sscanf(codecs,
"%30d%n", &codec, &len) != 1) {
2023 if (sscanf(a,
"rtpmap: %30d %127[^/]/", &codec, mimeSubtype) != 2)
2032 ast_debug(1,
"Capabilities: us - %s, them - %s, combined - %s\n",
2036 ast_debug(1,
"Non-codec capabilities: us - %d, them - %d, combined - %d\n",
2047 if (req->
len >=
sizeof(req->
data) - 4) {
2069 if (req->
len >=
sizeof(req->
data) - 4) {
2134 memset(resp, 0,
sizeof(*resp));
2145 if (oseq_global > 999999999) {
2164 respprep(&resp, p, msg, req, msgrest);
2173 mgr->
buf[resp.
len] =
'\0';
2186 struct sockaddr_in sin;
2196 struct sockaddr_in dest = { 0, };
2212 if (sub->
tmpdest.sin_addr.s_addr) {
2213 dest.sin_addr = sub->
tmpdest.sin_addr;
2214 dest.sin_port = sub->
tmpdest.sin_port;
2219 dest.sin_port = sin.sin_port;
2224 snprintf(o,
sizeof(o),
"o=root %d %d IN IP4 %s\r\n", (
int)getpid(), (
int)getpid(),
ast_inet_ntoa(dest.sin_addr));
2226 snprintf(c,
sizeof(c),
"c=IN IP4 %s\r\n",
ast_inet_ntoa(dest.sin_addr));
2228 snprintf(m,
sizeof(m),
"m=audio %d RTP/AVP", ntohs(dest.sin_port));
2238 snprintf(costr,
sizeof(costr),
" %d", codec);
2239 strncat(m, costr,
sizeof(m) - strlen(m) - 1);
2241 strncat(a, costr,
sizeof(a) - strlen(a) - 1);
2247 ast_debug(1,
"Answering with non-codec capability %d\n", (
int) x);
2250 snprintf(costr,
sizeof(costr),
" %d", codec);
2251 strncat(m, costr,
sizeof(m) - strlen(m) - 1);
2253 strncat(a, costr,
sizeof(a) - strlen(a) - 1);
2257 snprintf(costr,
sizeof costr,
"a=fmtp:%d 0-16\r\n", codec);
2258 strncat(a, costr,
sizeof(a) - strlen(a) - 1);
2263 strncat(m,
"\r\n",
sizeof(m) - strlen(m) - 1);
2264 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a);
2265 snprintf(costr,
sizeof(costr),
"%d", len);
2301 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2307 snprintf(tmp,
sizeof(tmp),
", dq-gi:%x", sub->
gate->
gateid);
2308 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2312 ast_debug(1,
"Waiting for opened gate...\n");
2319 oseq =
reqprep(&resp, p,
"MDCX");
2343 ast_debug(3,
"Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2355 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2361 snprintf(tmp,
sizeof(tmp),
", dq-gi:%x", sub->
gate->
gateid);
2362 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2366 oseq =
reqprep(&resp, p,
"CRCX");
2444 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2448 ast_debug(3,
"Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
2451 oseq =
reqprep(&resp, p,
"CRCX");
2470 ast_debug(3,
"MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2473 oseq =
reqprep(&resp, p,
"RQNT");
2513 snprintf(tone2,
sizeof(tone2),
"%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
2516 oseq =
reqprep(&resp, p,
"RQNT");
2529 ast_debug(3,
"MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
2552 ast_debug(3,
"Modified %s@%s-%d with new mode: %s on callid: %s\n",
2558 if (p->
ncs && !fc) {
2565 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2572 snprintf(tmp,
sizeof(tmp),
", dq-gi:%x", sub->
gate->
gateid);
2573 strncat(local, tmp,
sizeof(local) - strlen(local) - 1);
2581 oseq =
reqprep(&resp, p,
"MDCX");
2612 char tone_indicate_end = 0;
2617 if (p && (!strcasecmp(tone, (p->
ncs ?
"L/ro" :
"G/cg")))) {
2618 tone_indicate_end = 1;
2626 }
else if (!tone_indicate_end){
2627 add_header(resp,
"R", (p->
ncs ?
"L/hu(N),L/hf(N),L/[0-9#*](N)" :
"L/hu(N),L/hf(N),D/[0-9#*](N)"));
2629 ast_debug(1,
"We don't want more digits if we will end the call\n");
2641 oseq =
reqprep(&resp, p,
"AUEP");
2657 ast_debug(3,
"Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
2659 oseq =
reqprep(&resp, p,
"DLCX");
2679 ast_debug(3,
"Delete connection %s %s@%s on callid: %s\n",
2680 cxident ? cxident :
"", p->
name, p->
parent->
name, callid ? callid :
"");
2681 oseq =
reqprep(&resp, p,
"DLCX");
2683 if (callid && *callid)
2686 if (cxident && *cxident)
2735 for (prev = NULL, req = *queue; req; prev = req, req = req->
next) {
2736 if (req->trid == ident) {
2745 ast_debug(1,
"Posting Queued Request:\n%s to %s:%d\n", (*queue)->data,
2759 int result,
unsigned int ident,
struct mgcp_request *resp)
2778 ast_verb(3,
"No command found on [%s] for transaction %u. Ignoring...\n",
2783 if (p && (result >= 400) && (result <= 599)) {
2841 if (strcasecmp(c, sub->
cxident)) {
2846 if (sub->
tmpdest.sin_addr.s_addr) {
2865 while ((v =
get_csv(c, &len, &n))) {
2870 char cxident[80] =
"";
2872 if (len > (
sizeof(cxident) - 1))
2873 len =
sizeof(cxident) - 1;
2875 ast_verb(3,
"Non existing connection id %s on %s@%s \n",
2887 if (strstr(c,
"hu")) {
2900 }
else if (strstr(c,
"hd")) {
2914 if (resp && resp->
lines) {
2916 if (sub && sub->
owner) {
2971 int loop_pause = 100;
2978 while (strlen(p->
dtmf_buf) == len) {
2980 timeout -= loop_pause;
3004 ast_verb(3,
"Setting call forward to '%s' on channel %s\n",
3049 }
else if (res == 0) {
3050 ast_debug(1,
"not enough digits (and no ambiguous match)...\n");
3058 ast_verb(3,
"Disabling call waiting on %s\n", chan->
name);
3080 ast_verb(3,
"Disabling Caller*ID on %s\n", chan->
name);
3098 }
else if (!strcmp(p->
dtmf_buf,
"*78")) {
3100 ast_verb(3,
"Enabled DND on channel %s\n", chan->
name);
3107 }
else if (!strcmp(p->
dtmf_buf,
"*79")) {
3109 ast_verb(3,
"Disabled DND on channel %s\n", chan->
name);
3123 ast_verb(3,
"Cancelling call forwarding on channel %s\n", chan->
name);
3257 ast_debug(1,
"Neither %s nor %s are in a bridge, nothing to transfer\n",
3301 #ifdef DLINK_BUGGY_FIRMWARE
3333 ast_log(
LOG_WARNING,
"If we're onhook why are we here trying to handle a hd or hf?\n");
3360 if (!strcasecmp(req->
verb,
"RSIP")) {
3362 if (!strcasecmp(
get_header(req,
"RM"),
"X-keepalive")) {
3378 for (tmp_ep = g->
endpoints; tmp_ep; tmp_ep = tmp_ep->
next) {
3384 first_sub = tmp_ep->
sub;
3385 tmp_sub = tmp_ep->
sub;
3388 tmp_sub = tmp_sub->
next;
3389 if (tmp_sub == first_sub)
3394 }
else if (sub->
owner) {
3407 }
else if (!strcasecmp(req->
verb,
"NTFY")) {
3412 s = strchr(ev,
'/');
3416 if (strcasecmp(ev,
"hu") && strcasecmp(ev,
"hd") && strcasecmp(ev,
"ping")) {
3419 if (!strcasecmp(ev,
"hd")) {
3430 }
else if (!strcasecmp(ev,
"hf")) {
3461 ast_verb(3,
"MGCP Conferencing %d and %d on %s@%s\n",
3473 ast_verb(3,
"We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n",
3503 ast_log(
LOG_WARNING,
"Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n",
3506 }
else if (!strcasecmp(ev,
"hu")) {
3538 ast_verb(3,
"MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n",
3560 }
else if ((strlen(ev) == 1) &&
3561 (((ev[0] >=
'0') && (ev[0] <=
'9')) ||
3562 ((ev[0] >=
'A') && (ev[0] <=
'D')) ||
3563 (ev[0] ==
'*') || (ev[0] ==
'#'))) {
3574 if (strstr(p->
curtone, (p->
ncs ?
"wt1" :
"wt")) && (ev[0] ==
'A')) {
3581 }
else if (!strcasecmp(ev,
"T")) {
3583 }
else if (!strcasecmp(ev,
"ping")) {
3601 if (sscanf(req->
identifier,
"%30d", &seqno) != 1) {
3613 if (seqno == cur->seqno)
3628 struct sockaddr_in sin;
3635 memset(&req, 0,
sizeof(req));
3636 res = recvfrom(mgcpsock, req.
data,
sizeof(req.
data) - 1, 0, (
struct sockaddr *)&sin, &len);
3638 if (
errno != ECONNREFUSED)
3642 req.
data[res] =
'\0';
3655 if (sscanf(req.
verb,
"%30d", &result) && sscanf(req.
identifier,
"%30d", &ident)) {
3657 ast_debug(1,
"Ignoring provisional response on transaction %d\n", ident);
3668 for (prev = NULL, cur = gw->
msgs; cur; prev = cur, cur = cur->
next) {
3669 if (cur->
seqno == ident) {
3670 ast_debug(1,
"Got response back on transaction %d\n", ident);
3691 ast_log(
LOG_NOTICE,
"Got response back on [%s] for transaction %d we aren't sending?\n",
3698 ast_log(
LOG_NOTICE,
"Message must have a verb, an idenitifier, version, and endpoint\n");
3735 for (i = 0; (i <
MAX_SUBS) && s; i++) {
3747 for (i = 0; (i <
MAX_SUBS) && sub; i++) {
3769 ast_debug(1,
"***** MGCP REALTIME PRUNE GW: %s\n", g->
name);
3785 if (mgcpsock > -1) {
3801 if (mgcpsock > -1 && !mgcpsock_read_id) {
3817 lastpass = thispass;
3818 thispass = time(NULL);
3821 if (thispass != lastpass) {
3826 if ((e->msgstate != res) && (e->hookstate ==
MGCP_ONHOOK) && (!e->rtp)){
3833 e->onhooktime = thispass;
3843 if(time(NULL) > (lastrun + 60)) {
3868 lastrun = time(NULL);
3874 pthread_testcancel();
3878 if ((res < 0) || (res > 1000)) {
3901 if (monitor_thread == pthread_self()) {
3908 pthread_kill(monitor_thread, SIGURG);
3944 ast_verb(3,
"MGCP mgcp_request(%s)\n", tmp);
3945 ast_verb(3,
"MGCP cw: %d, dnd: %d, so: %d, sno: %d\n",
3987 if (!strcasecmp(cat, gw->
name)) {
3995 if (!gw && !(gw =
ast_calloc(1,
sizeof(*gw)))) {
4009 for (; v; v = v->
next) {
4010 if (!strcasecmp(v->
name,
"host")) {
4011 if (!strcasecmp(v->
value,
"dynamic")) {
4014 memset(&gw->
addr.sin_addr, 0, 4);
4015 if (gw->
addr.sin_port) {
4018 gw->
addr.sin_port = 0;
4038 }
else if (!strcasecmp(v->
name,
"defaultip")) {
4050 }
else if (!strcasecmp(v->
name,
"permit") ||
4051 !strcasecmp(v->
name,
"deny")) {
4053 }
else if (!strcasecmp(v->
name,
"port")) {
4054 gw->
addr.sin_port = htons(atoi(v->
value));
4055 }
else if (!strcasecmp(v->
name,
"context")) {
4057 }
else if (!strcasecmp(v->
name,
"dtmfmode")) {
4058 if (!strcasecmp(v->
value,
"inband"))
4060 else if (!strcasecmp(v->
value,
"rfc2833"))
4062 else if (!strcasecmp(v->
value,
"hybrid"))
4064 else if (!strcasecmp(v->
value,
"none"))
4068 }
else if (!strcasecmp(v->
name,
"nat")) {
4070 }
else if (!strcasecmp(v->
name,
"ncs")) {
4072 }
else if (!strcasecmp(v->
name,
"hangupongateremove")) {
4074 }
else if (!strcasecmp(v->
name,
"pktcgatealloc")) {
4076 }
else if (!strcasecmp(v->
name,
"callerid")) {
4077 if (!strcasecmp(v->
value,
"asreceived")) {
4083 }
else if (!strcasecmp(v->
name,
"language")) {
4085 }
else if (!strcasecmp(v->
name,
"accountcode")) {
4087 }
else if (!strcasecmp(v->
name,
"amaflags")) {
4094 }
else if (!strcasecmp(v->
name,
"setvar")) {
4096 }
else if (!strcasecmp(v->
name,
"clearvars")) {
4101 }
else if (!strcasecmp(v->
name,
"musiconhold")) {
4103 }
else if (!strcasecmp(v->
name,
"parkinglot")) {
4105 }
else if (!strcasecmp(v->
name,
"callgroup")) {
4107 }
else if (!strcasecmp(v->
name,
"pickupgroup")) {
4109 }
else if (!strcasecmp(v->
name,
"immediate")) {
4111 }
else if (!strcasecmp(v->
name,
"cancallforward")) {
4113 }
else if (!strcasecmp(v->
name,
"singlepath")) {
4115 }
else if (!strcasecmp(v->
name,
"directmedia") || !strcasecmp(v->
name,
"canreinvite")) {
4117 }
else if (!strcasecmp(v->
name,
"mailbox")) {
4119 }
else if (!strcasecmp(v->
name,
"hasvoicemail")) {
4123 }
else if (!strcasecmp(v->
name,
"adsi")) {
4125 }
else if (!strcasecmp(v->
name,
"callreturn")) {
4127 }
else if (!strcasecmp(v->
name,
"callwaiting")) {
4129 }
else if (!strcasecmp(v->
name,
"slowsequence")) {
4131 }
else if (!strcasecmp(v->
name,
"transfer")) {
4133 }
else if (!strcasecmp(v->
name,
"threewaycalling")) {
4135 }
else if (!strcasecmp(v->
name,
"wcardep")) {
4191 if (!ep_reload && e->
sub && e->
sub->
rtp) {
4217 ast_verb(3,
"Allocating subchannel '%d' on %s@%s\n", i, e->
name, gw->
name);
4238 for (sub = e->
sub; sub && sub->
next; sub = sub->
next);
4246 }
else if (!strcasecmp(v->
name,
"trunk") ||
4247 !strcasecmp(v->
name,
"line")) {
4282 ast_verb(3,
"Setting mailbox '%s' on %s@%s\n", mailbox, gw->
name, e->
name);
4326 for (i = 0, sub = NULL; i <
MAX_SUBS; i++) {
4339 ast_verb(3,
"Allocating subchannel '%d' on %s@%s\n", i, e->
name, gw->
name);
4360 for (sub = e->
sub; sub && sub->
next; sub = sub->
next);
4368 }
else if (!strcasecmp(v->
name,
"name") || !strcasecmp(v->
name,
"lines")) {
4374 if (!ntohl(gw->
addr.sin_addr.s_addr) && !gw->
dynamic) {
4384 gw->
defaddr.sin_family = AF_INET;
4385 gw->
addr.sin_family = AF_INET;
4386 if (gw->
defaddr.sin_addr.s_addr && !ntohs(gw->
defaddr.sin_port)) {
4389 if (gw->
addr.sin_addr.s_addr && !ntohs(gw->
addr.sin_port)) {
4394 struct sockaddr_in tmp3 = {0,};
4396 tmp3.sin_addr = gw->
ourip;
4403 gw->
ourip = tmp3.sin_addr;
4412 return (gw_reload ? NULL : gw);
4463 if (!chan || chan->
tech != &mgcp_tech) {
4468 if (!strcasecmp(args,
"ncs")) {
4469 snprintf(buf, buflen,
"%s", sub->
parent->
ncs ?
"yes":
"no");
4512 for (i = 0; (i <
MAX_SUBS) && sub; i++) {
4592 if ((varval = strchr(varname,
'='))) {
4595 tmpvar->
next = list;
4609 for (v = src ; v ; v = v->
next) {
4631 if (gethostname(ourhost,
sizeof(ourhost)-1)) {
4644 ast_log(
LOG_ERROR,
"Config file %s is in an invalid format. Aborting.\n", config);
4661 if (!strcasecmp(v->
name,
"bindaddr")) {
4667 }
else if (!strcasecmp(v->
name,
"allow")) {
4674 }
else if (!strcasecmp(v->
name,
"disallow")) {
4679 capability &= ~format;
4681 }
else if (!strcasecmp(v->
name,
"tos")) {
4685 }
else if (!strcasecmp(v->
name,
"tos_audio")) {
4688 }
else if (!strcasecmp(v->
name,
"cos")) {
4691 }
else if (!strcasecmp(v->
name,
"cos_audio")) {
4694 }
else if (!strcasecmp(v->
name,
"port")) {
4695 if (sscanf(v->
value,
"%5d", &ourport) == 1) {
4696 bindaddr.sin_port = htons(ourport);
4700 }
else if (!strcasecmp(v->
name,
"firstdigittimeout")) {
4701 firstdigittimeout = atoi(v->
value);
4702 }
else if (!strcasecmp(v->
name,
"gendigittimeout")) {
4703 gendigittimeout = atoi(v->
value);
4704 }
else if (!strcasecmp(v->
name,
"matchdigittimeout")) {
4705 matchdigittimeout = atoi(v->
value);
4720 if (strcasecmp(cat,
"general")) {
4730 if (monitor_thread == pthread_self()) {
4740 if (ntohl(
bindaddr.sin_addr.s_addr)) {
4758 if (mgcpsock_read_id != NULL)
4760 mgcpsock_read_id = NULL;
4762 mgcpsock = socket(AF_INET, SOCK_DGRAM, 0);
4773 ast_verb(2,
"MGCP Listening on %s:%d\n",
4786 ast_verb(3,
"MGCP Auditing endpoint %s@%s for hookstate\n", e->
name, g->
name);
4829 static int deprecated = 0;
4836 "Usage: mgcp reload\n"
4837 " 'mgcp reload' is deprecated. Please use 'reload chan_mgcp.so' instead.\n";
4844 if (!deprecated && a && a->
argc > 0) {
4845 ast_log(
LOG_WARNING,
"'mgcp reload' is deprecated. Please use 'reload chan_mgcp.so' instead.\n");
4850 if (mgcp_reloading) {
4851 ast_verbose(
"Previous mgcp reload not yet done\n");
4886 pthread_cancel(monitor_thread);
4887 pthread_kill(monitor_thread, SIGURG);
4888 pthread_join(monitor_thread, NULL);
4935 .nonoptreq =
"res_pktccops",
static int __mgcp_xmit(struct mgcp_gateway *gw, char *data, int len)
int ast_io_wait(struct io_context *ioc, int howlong)
Waits for IO.
static const char *const mgcp_cxmodes[]
static char musicclass[MAX_MUSICCLASS]
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
unsigned long long ast_group_t
union ast_frame_subclass subclass
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
static void start_rtp(struct mgcp_subchannel *sub)
int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks to see if adding anything to this extension might match something. (exists ^ canmatch) ...
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...
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
#define AST_CLI_DEFINE(fn, txt,...)
char * str
Subscriber phone number (Malloced)
static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp)
struct ast_party_connected_line connected
Channel Connected Line ID information.
static void mgcp_queue_frame(struct mgcp_subchannel *sub, struct ast_frame *f)
static ast_mutex_t gatelock
gatelock: mutex for gateway/endpoint lists
static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
char cid_num[AST_MAX_EXTENSION]
static ast_group_t cur_pickupgroup
static int firstdigittimeout
char * str
Subscriber phone number (Malloced)
void ast_module_unref(struct ast_module *)
char lastcallerid[AST_MAX_EXTENSION]
static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
static char parkinglot[AST_MAX_CONTEXT]
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
char cid_name[AST_MAX_EXTENSION]
struct ast_party_caller caller
Channel Caller ID information.
char * strsep(char **str, const char *delims)
static char * handle_mgcp_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_callerid_split(const char *src, char *name, int namelen, char *num, int numlen)
static int restart_monitor(void)
struct mgcp_endpoint * owner_ep
struct mgcp_request * cx_queue
ast_mutex_t cmd_queue_lock
static struct mgcp_gateway * build_gateway(char *cat, struct ast_variable *v)
build_gateway: parse mgcp.conf and create gateway/endpoint structures
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.
int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
Weird function made for call transfers.
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
static unsigned int oseq_global
struct mgcp_subchannel * sub
#define ast_pthread_create_detached(a, b, c, d)
static int * mgcpsock_read_id
static int unalloc_sub(struct mgcp_subchannel *sub)
struct ast_party_id id
Connected party ID.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
int(* gate_remove)(struct cops_gate *gate)
struct cops_gate * ast_pktccops_gate_alloc(int cmd, struct cops_gate *gate, uint32_t mta, uint32_t actcount, float bitrate, uint32_t psize, uint32_t ssip, uint16_t ssport, int(*const got_dq_gi)(struct cops_gate *gate), int(*const gate_remove)(struct cops_gate *gate))
static char * mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DEFAULT_MGCP_GW_PORT
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
static struct ast_frame * mgcp_rtp_read(struct mgcp_subchannel *sub)
const char * ast_var_value(const struct ast_var_t *var)
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
void ast_dsp_free(struct ast_dsp *dsp)
#define DSP_FEATURE_DIGIT_DETECT
char musicclass[MAX_MUSICCLASS]
static char * get_csv(char *c, int *len, char **next)
get_csv: (SC:) get comma separated value
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 MGCP_DTMF_RFC2833
const char * ast_var_name(const struct ast_var_t *var)
static char * get_header(struct mgcp_request *req, char *name)
int ast_app_has_voicemail(const char *mailbox, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX". If folder is "INBOX", includes the number of messages in the "Urgent" folder.
char * ast_get_encoded_str(const char *stream, char *result, size_t result_len)
Decode a stream of encoded control or extended ASCII characters.
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
static void destroy_gateway(struct mgcp_gateway *g)
#define DEADLOCK_AVOIDANCE(lock)
descriptor for a cli entry.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
struct mgcp_request * next
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
int ast_jb_read_conf(struct ast_jb_conf *conf, const char *varname, const char *value)
Sets jitterbuffer configuration property.
void ast_verbose(const char *fmt,...)
static int mgcp_call(struct ast_channel *ast, char *dest, int timeout)
char dtmf_buf[AST_MAX_EXTENSION]
struct ast_dsp * ast_dsp_new(void)
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
static const char config[]
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 load_module(void)
load_module: PBX load module - initialization —
#define AST_MAX_ACCOUNT_CODE
int ast_rtp_instance_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
Send a frame out over RTP.
static void mgcp_queue_hangup(struct mgcp_subchannel *sub)
static struct ast_frame * mgcp_read(struct ast_channel *ast)
char call_forward[AST_MAX_EXTENSION]
static int send_response(struct mgcp_subchannel *sub, struct mgcp_request *req)
#define ast_rtp_glue_register(glue)
static int mgcp_senddigit_begin(struct ast_channel *ast, char digit)
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
static int unload_module(void)
static char ourhost[MAXHOSTNAMELEN]
int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang)
says digits of a string
struct ast_event * ast_event_get_cached(enum ast_event_type,...)
Retrieve an event from the cache.
int ast_ignore_pattern(const char *context, const char *pattern)
Checks to see if a number should be ignored.
Configuration File Parser.
int ast_netsock_set_qos(int netsocket, int tos, int cos, const char *desc)
char * str
Subscriber name (Malloced)
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
struct ast_variable * ast_load_realtime(const char *family,...) attribute_sentinel
Retrieve realtime configuration.
static void sdpLineNum_iterator_init(int *iterator)
static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername)
format_t ast_best_codec(format_t fmts)
Pick the best audio codec.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
struct sockaddr_in tmpdest
int(* gate_open)(struct cops_gate *gate)
Number of new messages Used by: AST_EVENT_MWI Payload type: UINT.
#define ast_mutex_lock(a)
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 ...
static struct mgcp_request * find_command(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request **queue, ast_mutex_t *l, int ident)
find_command: (SC:) remove command transaction from queue
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
static int mgcp_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)
const char * ast_state2str(enum ast_channel_state)
Gives the string form of a given channel state.
static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
I/O Management (derived from Cheops-NG)
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
struct mgcp_subchannel * next
const ast_string_field linkedid
static struct ast_channel * mgcp_new(struct mgcp_subchannel *sub, int state, const char *linkedid)
enum ast_channel_adsicpe adsicpe
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Socket address structure.
static char cid_num[AST_MAX_EXTENSION]
#define ast_verb(level,...)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
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,...)
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
static int threewaycalling
static void * do_monitor(void *data)
static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
String fields in structures.
static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
int args
This gets set in ast_cli_register()
static int mgcp_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration)
static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
static const char * mbox(struct ast_vm_user *vmu, int id)
static int cancallforward
#define ast_pthread_create_background(a, b, c, d)
mgcp_message: MGCP message for queuing up
static void prune_gateways(void)
struct mgcp_response * responses
static char * handle_mgcp_show_endpoints(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DEFAULT_MGCP_CA_PORT
internal representation of acl entries In principle user applications would have no need for this...
char language[MAX_LANGUAGE]
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 void * mgcp_ss(void *data)
char parkinglot[AST_MAX_CONTEXT]
static ast_mutex_t netlock
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...
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
#define ast_debug(level,...)
Log a DEBUG message.
Context IE Used by AST_EVENT_MWI Payload type: str.
struct ast_party_id ani
Automatic Number Identification (ANI)
static int mgcp_prune_realtime_gateway(struct mgcp_gateway *g)
General Asterisk PBX channel definitions.
struct ast_party_dialed::@155 number
Dialed/Called number.
#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.
#define ast_mutex_trylock(a)
#define ast_config_load(filename, flags)
Load a config file.
#define AST_PTHREADT_NULL
struct sockaddr_in defaddr
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static int reload_config(int reload)
static void destroy_endpoint(struct mgcp_endpoint *e)
struct ast_variable * chanvars
Access Control of various sorts.
Global IO variables are now in a struct in order to be made threadsafe.
static int mgcp_alloc_pktcgate(struct mgcp_subchannel *sub)
#define AST_MAX_EXTENSION
static int transmit_connect(struct mgcp_subchannel *sub)
Scheduler Routines (derived from cheops)
struct mgcp_gateway * next
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define ao2_ref(o, delta)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
struct ast_channel * owner
long int ast_random(void)
struct mgcp_request * rqnt_queue
static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
static int mgcp_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
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.
struct mgcp_message * msgs
static struct io_context * io
static struct ast_channel_tech mgcp_tech
ast_group_t ast_get_group(const char *s)
static int mgcp_postrequest(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno)
static int transmit_connection_del(struct mgcp_subchannel *sub)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
char context[AST_MAX_EXTENSION]
static int mgcp_devicestate(void *data)
mgcp_devicestate: channel callback for device status monitoring
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.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
char accountcode[AST_MAX_ACCOUNT_CODE]
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.
static int resend_response(struct mgcp_subchannel *sub, struct mgcp_response *resp)
struct ast_event_sub * mwi_event_sub
static struct sched_context * sched
static char language[MAX_LANGUAGE]
struct ast_party_dialed dialed
Dialed/Called information.
static int gendigittimeout
#define ast_strdupa(s)
duplicate a string in memory from the stack
format_t ast_getformatbyname(const char *name)
Gets a format from a name.
static pthread_t monitor_thread
struct mgcp_response * next
char exten[AST_MAX_EXTENSION]
char * ast_getformatname(format_t format)
Get the name of a format.
static ast_mutex_t monlock
static struct ast_variable * add_var(const char *buf, struct ast_variable *list)
static int nonCodecCapability
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 void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request *resp, char *tone)
ast_mutex_t cx_queue_lock
static enum ast_rtp_glue_result mgcp_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
struct mgcp_gateway * parent
static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
static void mwi_event_cb(const struct ast_event *event, void *userdata)
static int mgcp_reloading
static int attempt_transfer(struct mgcp_endpoint *p)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_cdr_amaflags2int(const char *flag)
Convert a string to a detail record AMA flag.
enum ast_channel_state _state
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
int ast_rtp_instance_dtmf_begin(struct ast_rtp_instance *instance, char digit)
Begin sending a DTMF digit.
const ast_string_field name
static char * get_sdp_by_line(char *line, char *name, int nameLen)
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...
int ast_get_ip(struct ast_sockaddr *addr, const char *hostname)
Get the IP address given a hostname.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static struct ast_jb_conf global_jbconf
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
struct ast_var_t::@158 entries
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
#define AST_CAUSE_UNREGISTERED
#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.
ast_mutex_t rqnt_queue_lock
int ast_str2cos(const char *value, unsigned int *cos)
Convert a string to the appropriate COS value.
static char * handle_mgcp_audit_endpoint(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 ast_group_t cur_callergroup
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.
const char * ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
Retrieve mime subtype information on a payload.
struct mgcp_request * cmd_queue
unsigned int flags
Combination of the AST_JB_ENABLED, AST_JB_FORCED and AST_JB_LOG flags.
static struct mgcp_gateway * gateways
static struct mgcp_subchannel * find_subchannel_and_lock(char *name, int msgid, struct sockaddr_in *sin)
static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub)
dump_cmd_queues: (SC:) cleanup pending commands
void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance)
Clear payload information from an RTP instance.
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.
struct ast_rtp_instance * rtp
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
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.
static char accountcode[AST_MAX_ACCOUNT_CODE]
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
uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_type ie_type)
Get the value of an information element that has an integer payload.
static struct ast_channel * mgcp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
struct mgcp_endpoint * parent
static struct ast_variable * copy_vars(struct ast_variable *src)
duplicate a list of channel variables,
int ast_waitfordigit(struct ast_channel *c, int ms)
Waits for a digit.
static char * __get_header(struct mgcp_request *req, char *name, int *start, char *def)
static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
#define AST_CAUSE_REQUESTED_CHAN_UNAVAIL
struct hostent * ast_gethostbyname(const char *host, struct ast_hostent *hp)
Thread-safe gethostbyname function to use in Asterisk.
void ast_event_destroy(struct ast_event *event)
Destroy an event.
static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
struct sched_context * sched_context_create(void)
New schedule context.
Channels have this property if they can create jitter; i.e. most VoIP channels.
static int hangupongateremove
static struct ast_cli_entry cli_mgcp[]
static int has_voicemail(struct mgcp_endpoint *p)
Standard Command Line Interface.
static int mgcp_answer(struct ast_channel *ast)
struct ast_event_sub * ast_event_subscribe(enum ast_event_type event_type, ast_event_cb_t cb, const char *description, void *userdata,...)
Subscribe to events.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
static format_t mgcp_get_codec(struct ast_channel *chan)
static ast_mutex_t mgcp_reload_lock
int(* got_dq_gi)(struct cops_gate *gate)
static int find_and_retrans(struct mgcp_subchannel *sub, struct mgcp_request *req)
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
static struct ast_rtp_glue mgcp_rtp_glue
static int send_request(struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno)
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.
static char context[AST_MAX_EXTENSION]
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
char * ast_getformatname_multiple(char *buf, size_t size, format_t format)
Get the names of a set of formats.
char * line[MGCP_MAX_LINES]
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
static void mgcp_queue_control(struct mgcp_subchannel *sub, int control)
int ast_masq_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout)
Park a call via a masqueraded channel.
static int mgcp_pktcgate_open(struct cops_gate *gate)
char * header[MGCP_MAX_HEADERS]
static struct mgcp_gateway * find_realtime_gw(char *name, char *at, struct sockaddr_in *sin)
struct mgcp_message * next
static char * get_sdp_iterate(int *iterator, struct mgcp_request *req, char *name)
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.
static char * control2str(int ind)
int ast_db_put(const char *family, const char *key, const char *value)
Store value addressed by family/key.
static int mgcp_pktcgate_remove(struct cops_gate *gate)
static ast_mutex_t oseq_lock
Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
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.
static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
static int handle_request(struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin)
int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context)
Determine if parking extension exists in a given context.
struct mgcp_endpoint * endpoints
#define AST_APP_ARG(name)
Define an application argument.
enum ast_frame_type frametype
struct ast_variable * next
static int mgcp_hangup(struct ast_channel *ast)
static int add_line(struct mgcp_request *req, char *line)
#define DSP_DIGITMODE_NOQUELCH
static struct adsi_event events[]
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
unsigned char valid
TRUE if the name information is valid/present.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define CONFIG_STATUS_FILEINVALID
static int matchdigittimeout
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define ast_mutex_destroy(a)
struct mgcp_endpoint * next
#define MGCP_SUBCHANNEL_MAGIC
static char * get_sdp(struct mgcp_request *req, char *name)
static struct in_addr __ourip
static const char tdesc[]
static struct ast_jb_conf default_jbconf
Say numbers and dates (maybe words one day too)
static int transmit_modify_request(struct mgcp_subchannel *sub)
#define ASTERISK_GPL_KEY
The text the key() function should return.
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.
char mailbox[AST_MAX_EXTENSION]
Asterisk module definitions.
static int mgcpsock_read(int *id, int fd, short events, void *ignore)
static struct hostent * hp
static snd_pcm_format_t format
union ast_frame::@172 data
struct ast_channel_tech * tech
char data[MGCP_MAX_PACKET]
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Persistant data storage (akin to *doze registry)
struct ast_event_sub * ast_event_unsubscribe(struct ast_event_sub *event_sub)
Un-subscribe from events.
unsigned char valid
TRUE if the number information is valid/present.
General jitterbuffer configuration.
void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
Record payload information that was seen in an m= SDP line.
static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest)
const ast_string_field language
static void dump_queue(struct mgcp_gateway *gw, struct mgcp_endpoint *p)
static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest)
static int retrans_pkt(const void *data)
char exten[AST_MAX_EXTENSION]
#define AST_MUTEX_DEFINE_STATIC(mutex)
const char * ast_pickup_ext(void)
Determine system call pickup extension.
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Structure for mutex and tracking information.
int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
Set digit mode.
static char mailbox[AST_MAX_EXTENSION]
void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *astformats, int *nonastformats)
Retrieve all formats that were found.
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.
#define CONFIG_STATUS_FILEUNCHANGED
#define ast_mutex_unlock(a)
static int add_header(struct mgcp_request *req, const char *var, const char *value)
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.
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
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 mgcp_subchannel * owner_sub
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...