#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/signal.h>
#include <signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/cdr.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/dsp.h"
Go to the source code of this file.
Data Structures | |
struct | mgcp_endpoint |
struct | mgcp_gateway |
struct | mgcp_message |
struct | mgcp_request |
struct | mgcp_response |
struct | mgcp_subchannel |
Defines | |
#define | CANREINVITE 1 |
#define | DEFAULT_EXPIRY 120 |
#define | DEFAULT_MGCP_CA_PORT 2727 |
#define | DEFAULT_MGCP_GW_PORT 2427 |
#define | DEFAULT_RETRANS 1000 |
#define | INADDR_NONE (in_addr_t)(-1) |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_EXPIRY 3600 |
#define | MAX_RETRANS 5 |
#define | MAX_SUBS 2 |
#define | MGCP_CMD_AUCX 7 |
#define | MGCP_CMD_AUEP 6 |
#define | MGCP_CMD_CRCX 1 |
#define | MGCP_CMD_DLCX 3 |
#define | MGCP_CMD_EPCF 0 |
#define | MGCP_CMD_MDCX 2 |
#define | MGCP_CMD_NTFY 5 |
#define | MGCP_CMD_RQNT 4 |
#define | MGCP_CMD_RSIP 8 |
#define | MGCP_CX_CONF 3 |
#define | MGCP_CX_CONFERENCE 3 |
#define | MGCP_CX_INACTIVE 4 |
#define | MGCP_CX_MUTE 4 |
#define | MGCP_CX_RECVONLY 1 |
#define | MGCP_CX_SENDONLY 0 |
#define | MGCP_CX_SENDRECV 2 |
#define | MGCP_DTMF_HYBRID (1 << 2) |
#define | MGCP_DTMF_INBAND (1 << 1) |
#define | MGCP_DTMF_RFC2833 (1 << 0) |
#define | MGCP_MAX_HEADERS 64 |
#define | MGCP_MAX_LINES 64 |
#define | MGCP_MAX_PACKET 1500 |
#define | MGCP_OFFHOOK 2 |
#define | MGCP_ONHOOK 1 |
#define | MGCP_SUBCHANNEL_MAGIC "!978!" |
#define | MGCPDUMPER |
#define | RESPONSE_TIMEOUT 30 |
#define | SUB_ALT 1 |
#define | SUB_REAL 0 |
#define | TYPE_LINE 2 |
#define | TYPE_TRUNK 1 |
Functions | |
static char * | __get_header (struct mgcp_request *req, char *name, int *start) |
static int | __mgcp_xmit (struct mgcp_gateway *gw, char *data, int len) |
static int | add_header (struct mgcp_request *req, char *var, char *value) |
static int | add_line (struct mgcp_request *req, char *line) |
static int | add_sdp (struct mgcp_request *resp, struct mgcp_subchannel *sub, struct ast_rtp *rtp) |
AST_MUTEX_DEFINE_STATIC (gatelock) | |
AST_MUTEX_DEFINE_STATIC (mgcp_reload_lock) | |
AST_MUTEX_DEFINE_STATIC (monlock) | |
AST_MUTEX_DEFINE_STATIC (netlock) | |
AST_MUTEX_DEFINE_STATIC (usecnt_lock) | |
static int | attempt_transfer (struct mgcp_endpoint *p) |
static struct mgcp_gateway * | build_gateway (char *cat, struct ast_variable *v) |
static char * | control2str (int ind) |
char * | description () |
Provides a description of the module. | |
static void | destroy_endpoint (struct mgcp_endpoint *e) |
static void | destroy_gateway (struct mgcp_gateway *g) |
static void * | do_monitor (void *data) |
static void | dump_cmd_queues (struct mgcp_endpoint *p, struct mgcp_subchannel *sub) |
static void | dump_queue (struct mgcp_gateway *gw, struct mgcp_endpoint *p) |
static int | find_and_retrans (struct mgcp_subchannel *sub, struct mgcp_request *req) |
static struct mgcp_request * | find_command (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request **queue, ast_mutex_t *l, int ident) |
static struct mgcp_subchannel * | find_subchannel_and_lock (char *name, int msgid, struct sockaddr_in *sin) |
static char * | get_csv (char *c, int *len, char **next) |
static char * | get_header (struct mgcp_request *req, char *name) |
static char * | get_sdp (struct mgcp_request *req, char *name) |
static char * | get_sdp_by_line (char *line, char *name, int nameLen) |
static char * | get_sdp_iterate (int *iterator, struct mgcp_request *req, char *name) |
static void | handle_hd_hf (struct mgcp_subchannel *sub, char *ev) |
static int | handle_request (struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin) |
static void | handle_response (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp) |
static int | has_voicemail (struct mgcp_endpoint *p) |
static int | init_req (struct mgcp_endpoint *p, struct mgcp_request *req, char *verb) |
static int | init_resp (struct mgcp_request *req, char *resp, struct mgcp_request *orig, char *resprest) |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module () |
Initialize the module. | |
static int | mgcp_answer (struct ast_channel *ast) |
static int | mgcp_audit_endpoint (int fd, int argc, char *argv[]) |
static int | mgcp_call (struct ast_channel *ast, char *dest, int timeout) |
static int | mgcp_do_debug (int fd, int argc, char *argv[]) |
static int | mgcp_do_reload (void) |
static int | mgcp_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
static struct ast_rtp * | mgcp_get_rtp_peer (struct ast_channel *chan) |
static int | mgcp_hangup (struct ast_channel *ast) |
static int | mgcp_indicate (struct ast_channel *ast, int ind) |
static struct ast_channel * | mgcp_new (struct mgcp_subchannel *sub, int state) |
static int | mgcp_no_debug (int fd, int argc, char *argv[]) |
static int | mgcp_postrequest (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno) |
static void | mgcp_queue_control (struct mgcp_subchannel *sub, int control) |
static void | mgcp_queue_frame (struct mgcp_subchannel *sub, struct ast_frame *f) |
static void | mgcp_queue_hangup (struct mgcp_subchannel *sub) |
static struct ast_frame * | mgcp_read (struct ast_channel *ast) |
static int | mgcp_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | mgcp_request (const char *type, int format, void *data, int *cause) |
static struct ast_frame * | mgcp_rtp_read (struct mgcp_subchannel *sub) |
static int | mgcp_senddigit (struct ast_channel *ast, char digit) |
static int | mgcp_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
static int | mgcp_show_endpoints (int fd, int argc, char *argv[]) |
static void * | mgcp_ss (void *data) |
static int | mgcp_write (struct ast_channel *ast, struct ast_frame *frame) |
static int | mgcpsock_read (int *id, int fd, short events, void *ignore) |
static void | parse (struct mgcp_request *req) |
static int | process_sdp (struct mgcp_subchannel *sub, struct mgcp_request *req) |
static void | prune_gateways (void) |
int | reload (void) |
Reload stuff. | |
static int | reload_config (void) |
static int | reqprep (struct mgcp_request *req, struct mgcp_endpoint *p, char *verb) |
static int | resend_response (struct mgcp_subchannel *sub, struct mgcp_response *resp) |
static int | respprep (struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest) |
static int | restart_monitor (void) |
static int | retrans_pkt (void *data) |
static void | sdpLineNum_iterator_init (int *iterator) |
static int | send_request (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno) |
static int | send_response (struct mgcp_subchannel *sub, struct mgcp_request *req) |
static void | start_rtp (struct mgcp_subchannel *sub) |
static int | transmit_audit_endpoint (struct mgcp_endpoint *p) |
static int | transmit_connect_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp *rtp) |
static int | transmit_connection_del (struct mgcp_subchannel *sub) |
static int | transmit_connection_del_w_params (struct mgcp_endpoint *p, char *callid, char *cxident) |
static int | transmit_modify_request (struct mgcp_subchannel *sub) |
static int | transmit_modify_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs) |
static int | transmit_notify_request (struct mgcp_subchannel *sub, char *tone) |
static int | transmit_notify_request_with_callerid (struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername) |
static int | transmit_response (struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest) |
static int | unalloc_sub (struct mgcp_subchannel *sub) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
Variables | |
static struct in_addr | __ourip |
static char | accountcode [AST_MAX_ACCOUNT_CODE] = "" |
static int | adsi = 0 |
static int | amaflags = 0 |
static char | audit_endpoint_usage [] |
static struct sockaddr_in | bindaddr |
static int | callreturn = 0 |
static int | callwaiting = 0 |
static int | cancallforward = 0 |
static int | canreinvite = CANREINVITE |
static int | capability = AST_FORMAT_ULAW |
static char | cid_name [AST_MAX_EXTENSION] = "" |
static char | cid_num [AST_MAX_EXTENSION] = "" |
static struct ast_cli_entry | cli_audit_endpoint |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_mgcp_reload |
static struct ast_cli_entry | cli_no_debug |
static struct ast_cli_entry | cli_show_endpoints |
static const char | config [] = "mgcp.conf" |
static char | context [AST_MAX_EXTENSION] = "default" |
static ast_group_t | cur_callergroup = 0 |
static ast_group_t | cur_pickupgroup = 0 |
static char | debug_usage [] |
static const char | desc [] = "Media Gateway Control Protocol (MGCP)" |
static int | dtmfmode = 0 |
static int | firstdigittimeout = 16000 |
static struct mgcp_gateway * | gateways |
static int | gendigittimeout = 8000 |
static int | immediate = 0 |
static struct io_context * | io |
static char | language [MAX_LANGUAGE] = "" |
static char | mailbox [AST_MAX_EXTENSION] |
static int | matchdigittimeout = 3000 |
static char * | mgcp_cxmodes [] |
static char | mgcp_reload_usage [] |
static int | mgcp_reloading = 0 |
static struct ast_rtp_protocol | mgcp_rtp |
static const struct ast_channel_tech | mgcp_tech |
static int | mgcpdebug = 0 |
static int | mgcpsock = -1 |
static int * | mgcpsock_read_id = NULL |
static pthread_t | monitor_thread = AST_PTHREADT_NULL |
static char | musicclass [MAX_MUSICCLASS] = "" |
static int | nat = 0 |
static char | no_debug_usage [] |
static int | nonCodecCapability = AST_RTP_DTMF |
static unsigned int | oseq |
static char | ourhost [MAXHOSTNAMELEN] |
static int | ourport |
static struct sched_context * | sched |
static char | show_endpoints_usage [] |
static int | singlepath = 0 |
static int | slowsequence = 0 |
static const char | tdesc [] = "Media Gateway Control Protocol (MGCP)" |
static int | threewaycalling = 0 |
static int | tos = 0 |
static int | transfer = 0 |
static const char | type [] = "MGCP" |
static int | usecnt = 0 |
Definition in file chan_mgcp.c.
|
Definition at line 130 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 128 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 146 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 145 of file chan_mgcp.c. |
|
Definition at line 148 of file chan_mgcp.c. Referenced by __sip_reliable_xmit(), mgcp_postrequest(), and retrans_pkt(). |
|
Definition at line 133 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 118 of file chan_mgcp.c. |
|
Definition at line 129 of file chan_mgcp.c. |
|
Definition at line 149 of file chan_mgcp.c. Referenced by retrans_pkt(). |
|
Definition at line 333 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), and destroy_endpoint(). |
|
Definition at line 176 of file chan_mgcp.c. |
|
Definition at line 175 of file chan_mgcp.c. Referenced by handle_response(), and transmit_audit_endpoint(). |
|
Definition at line 170 of file chan_mgcp.c. Referenced by handle_response(), and send_request(). |
|
Definition at line 172 of file chan_mgcp.c. Referenced by send_request(), transmit_connection_del(), and transmit_connection_del_w_params(). |
|
Definition at line 169 of file chan_mgcp.c. |
|
Definition at line 171 of file chan_mgcp.c. Referenced by send_request(), and transmit_modify_request(). |
|
Definition at line 174 of file chan_mgcp.c. |
|
Definition at line 173 of file chan_mgcp.c. Referenced by send_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 177 of file chan_mgcp.c. |
|
Definition at line 155 of file chan_mgcp.c. Referenced by handle_request(). |
|
Definition at line 156 of file chan_mgcp.c. |
|
Definition at line 158 of file chan_mgcp.c. Referenced by build_gateway(), mgcp_hangup(), and unalloc_sub(). |
|
Definition at line 157 of file chan_mgcp.c. Referenced by handle_request(). |
|
Definition at line 153 of file chan_mgcp.c. Referenced by handle_request(), mgcp_call(), and mgcp_hangup(). |
|
Definition at line 152 of file chan_mgcp.c. |
|
Definition at line 154 of file chan_mgcp.c. Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), and mgcp_call(). |
|
Definition at line 143 of file chan_mgcp.c. Referenced by build_gateway(), mgcp_hangup(), mgcp_new(), and mgcp_ss(). |
|
Definition at line 142 of file chan_mgcp.c. Referenced by build_gateway(), mgcp_hangup(), mgcp_new(), mgcp_rtp_read(), mgcp_ss(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 141 of file chan_mgcp.c. Referenced by build_gateway(), and mgcp_rtp_read(). |
|
Definition at line 282 of file chan_mgcp.c. Referenced by add_header(), init_req(), init_resp(), and parse(). |
|
Definition at line 283 of file chan_mgcp.c. Referenced by add_line(), and parse(). |
|
Definition at line 147 of file chan_mgcp.c. |
|
Definition at line 375 of file chan_mgcp.c. Referenced by handle_hd_hf(), handle_request(), handle_response(), mgcp_call(), mgcp_hangup(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 374 of file chan_mgcp.c. Referenced by build_gateway(), do_monitor(), handle_request(), handle_response(), mgcp_call(), mgcp_hangup(), mgcp_request(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 344 of file chan_mgcp.c. Referenced by build_gateway(), and mgcp_hangup(). |
|
Definition at line 127 of file chan_mgcp.c. |
|
Definition at line 323 of file chan_mgcp.c. Referenced by find_and_retrans(). |
|
Definition at line 336 of file chan_mgcp.c. |
|
Definition at line 335 of file chan_mgcp.c. |
|
Definition at line 378 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), do_monitor(), mgcp_call(), and skinny_hangup(). |
|
Definition at line 377 of file chan_mgcp.c. Referenced by build_device(), and build_gateway(). |
|
Definition at line 1497 of file chan_mgcp.c. References mgcp_request::header, and mgcp_request::headers. Referenced by build_route(), copy_all_header(), copy_via_headers(), get_header(), and handle_response_register(). 01498 { 01499 int x; 01500 int len = strlen(name); 01501 char *r; 01502 for (x=*start;x<req->headers;x++) { 01503 if (!strncasecmp(req->header[x], name, len) && 01504 (req->header[x][len] == ':')) { 01505 r = req->header[x] + len + 1; 01506 while(*r && (*r < 33)) 01507 r++; 01508 *start = x+1; 01509 return r; 01510 } 01511 } 01512 /* Don't return NULL, so get_header is always a valid pointer */ 01513 return ""; 01514 }
|
|
Definition at line 550 of file chan_mgcp.c. References mgcp_gateway::addr, ast_log(), mgcp_gateway::defaddr, and LOG_WARNING. Referenced by mgcp_postrequest(), resend_response(), retrans_pkt(), and send_response(). 00551 { 00552 int res; 00553 if (gw->addr.sin_addr.s_addr) 00554 res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->addr, sizeof(struct sockaddr_in)); 00555 else 00556 res=sendto(mgcpsock, data, len, 0, (struct sockaddr *)&gw->defaddr, sizeof(struct sockaddr_in)); 00557 if (res != len) { 00558 ast_log(LOG_WARNING, "mgcp_xmit returned %d: %s\n", res, strerror(errno)); 00559 } 00560 return res; 00561 }
|
|
|
Definition at line 1871 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::len, mgcp_request::line, mgcp_request::lines, LOG_WARNING, and MGCP_MAX_LINES. Referenced by add_digit(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify(). 01872 { 01873 if (req->len >= sizeof(req->data) - 4) { 01874 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 01875 return -1; 01876 } 01877 if (!req->lines) { 01878 /* Add extra empty return */ 01879 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 01880 req->len += strlen(req->data + req->len); 01881 } 01882 req->line[req->lines] = req->data + req->len; 01883 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 01884 req->len += strlen(req->line[req->lines]); 01885 if (req->lines < MGCP_MAX_LINES) 01886 req->lines++; 01887 else { 01888 ast_log(LOG_WARNING, "Out of line space\n"); 01889 return -1; 01890 } 01891 return 0; 01892 }
|
|
Definition at line 1973 of file chan_mgcp.c. References AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), ast_verbose(), mgcp_endpoint::capability, mgcp_response::len, LOG_WARNING, mgcpdebug, mgcp_gateway::ourip, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, s, mgcp_endpoint::sub, t, and mgcp_subchannel::tmpdest. Referenced by transmit_invite(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp(). 01974 { 01975 int len; 01976 int codec; 01977 char costr[80]; 01978 struct sockaddr_in sin; 01979 char v[256]; 01980 char s[256]; 01981 char o[256]; 01982 char c[256]; 01983 char t[256]; 01984 char m[256] = ""; 01985 char a[1024] = ""; 01986 char iabuf[INET_ADDRSTRLEN]; 01987 int x; 01988 struct sockaddr_in dest; 01989 struct mgcp_endpoint *p = sub->parent; 01990 /* XXX We break with the "recommendation" and send our IP, in order that our 01991 peer doesn't have to ast_gethostbyname() us XXX */ 01992 len = 0; 01993 if (!sub->rtp) { 01994 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 01995 return -1; 01996 } 01997 ast_rtp_get_us(sub->rtp, &sin); 01998 if (rtp) { 01999 ast_rtp_get_peer(rtp, &dest); 02000 } else { 02001 if (sub->tmpdest.sin_addr.s_addr) { 02002 dest.sin_addr = sub->tmpdest.sin_addr; 02003 dest.sin_port = sub->tmpdest.sin_port; 02004 /* Reset temporary destination */ 02005 memset(&sub->tmpdest, 0, sizeof(sub->tmpdest)); 02006 } else { 02007 dest.sin_addr = p->parent->ourip; 02008 dest.sin_port = sin.sin_port; 02009 } 02010 } 02011 if (mgcpdebug) { 02012 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->ourip), ntohs(sin.sin_port)); 02013 } 02014 snprintf(v, sizeof(v), "v=0\r\n"); 02015 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02016 snprintf(s, sizeof(s), "s=session\r\n"); 02017 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02018 snprintf(t, sizeof(t), "t=0 0\r\n"); 02019 snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 02020 for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02021 if (p->capability & x) { 02022 if (mgcpdebug) { 02023 ast_verbose("Answering with capability %d\n", x); 02024 } 02025 codec = ast_rtp_lookup_code(sub->rtp, 1, x); 02026 if (codec > -1) { 02027 snprintf(costr, sizeof(costr), " %d", codec); 02028 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02029 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x)); 02030 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02031 } 02032 } 02033 } 02034 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 02035 if (p->nonCodecCapability & x) { 02036 if (mgcpdebug) { 02037 ast_verbose("Answering with non-codec capability %d\n", x); 02038 } 02039 codec = ast_rtp_lookup_code(sub->rtp, 0, x); 02040 if (codec > -1) { 02041 snprintf(costr, sizeof(costr), " %d", codec); 02042 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02043 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x)); 02044 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02045 if (x == AST_RTP_DTMF) { 02046 /* Indicate we support DTMF... Not sure about 16, 02047 but MSN supports it so dang it, we will too... */ 02048 snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec); 02049 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02050 } 02051 } 02052 } 02053 } 02054 strncat(m, "\r\n", sizeof(m) - strlen(m) - 1); 02055 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a); 02056 snprintf(costr, sizeof(costr), "%d", len); 02057 add_line(resp, v); 02058 add_line(resp, o); 02059 add_line(resp, s); 02060 add_line(resp, c); 02061 add_line(resp, t); 02062 add_line(resp, m); 02063 add_line(resp, a); 02064 return 0; 02065 }
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 2825 of file chan_mgcp.c. References ast_channel::_softhangup, ast_channel::_state, mgcp_subchannel::alreadygone, ast_bridged_channel(), ast_channel_masquerade(), AST_CONTROL_RINGING, ast_indicate(), ast_log(), ast_moh_stop(), AST_SOFTHANGUP_DEV, AST_STATE_RINGING, ast_verbose(), mgcp_subchannel::id, LOG_DEBUG, LOG_WARNING, mgcp_queue_hangup(), mgcp_gateway::name, mgcp_endpoint::name, ast_channel::name, mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_endpoint::sub, unalloc_sub(), and VERBOSE_PREFIX_3. Referenced by handle_request(), handle_request_refer(), and zt_handle_event(). 02826 { 02827 /* ************************* 02828 * I hope this works. 02829 * Copied out of chan_zap 02830 * Cross your fingers 02831 * *************************/ 02832 02833 /* In order to transfer, we need at least one of the channels to 02834 actually be in a call bridge. We can't conference two applications 02835 together (but then, why would we want to?) */ 02836 if (ast_bridged_channel(p->sub->owner)) { 02837 /* The three-way person we're about to transfer to could still be in MOH, so 02838 stop if now if appropriate */ 02839 if (ast_bridged_channel(p->sub->next->owner)) 02840 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02841 if (p->sub->owner->_state == AST_STATE_RINGING) { 02842 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02843 } 02844 if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { 02845 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02846 ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); 02847 return -1; 02848 } 02849 /* Orphan the channel */ 02850 unalloc_sub(p->sub->next); 02851 } else if (ast_bridged_channel(p->sub->next->owner)) { 02852 if (p->sub->owner->_state == AST_STATE_RINGING) { 02853 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02854 } 02855 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02856 if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { 02857 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02858 ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); 02859 return -1; 02860 } 02861 /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ 02862 if (option_verbose > 2) { 02863 ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name); 02864 } 02865 p->sub = p->sub->next; 02866 unalloc_sub(p->sub->next); 02867 /* Tell the caller not to hangup */ 02868 return 1; 02869 } else { 02870 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 02871 p->sub->owner->name, p->sub->next->owner->name); 02872 p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02873 if (p->sub->next->owner) { 02874 p->sub->next->alreadygone = 1; 02875 mgcp_queue_hangup(p->sub->next); 02876 } 02877 } 02878 return 0; 02879 }
|
|
Definition at line 3535 of file chan_mgcp.c. References mgcp_endpoint::accountcode, accountcode, mgcp_gateway::addr, mgcp_endpoint::adsi, adsi, mgcp_endpoint::amaflags, amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_get_group(), ast_get_ip(), ast_log(), ast_mutex_destroy(), ast_mutex_init(), ast_sched_del(), ast_strlen_zero(), ast_true(), ast_verbose(), mgcp_endpoint::callgroup, mgcp_endpoint::callreturn, callreturn, mgcp_endpoint::callwaiting, callwaiting, mgcp_endpoint::cancallforward, cancallforward, mgcp_endpoint::canreinvite, CANREINVITE, canreinvite, capability, mgcp_endpoint::capability, mgcp_endpoint::cid_name, cid_name, mgcp_endpoint::cid_num, cid_num, mgcp_endpoint::context, context, cur_callergroup, cur_pickupgroup, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxmode, mgcp_gateway::defaddr, mgcp_endpoint::delme, mgcp_gateway::delme, mgcp_endpoint::dtmfmode, dtmfmode, mgcp_gateway::dynamic, mgcp_gateway::endpoints, mgcp_gateway::expire, free, gateways, mgcp_gateway::ha, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_endpoint::immediate, immediate, INADDR_NONE, mgcp_endpoint::language, language, ast_variable::lineno, mgcp_subchannel::lock, LOG_WARNING, mgcp_subchannel::magic, mgcp_endpoint::mailbox, mailbox, malloc, MAX_SUBS, MGCP_CX_INACTIVE, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, MGCP_ONHOOK, MGCP_SUBCHANNEL_MAGIC, mgcp_gateway::msgs_lock, mgcp_endpoint::msgstate, mgcp_endpoint::musicclass, musicclass, mgcp_endpoint::name, ast_variable::name, mgcp_gateway::name, mgcp_subchannel::nat, nat, mgcp_subchannel::next, mgcp_endpoint::next, mgcp_gateway::next, mgcp_endpoint::onhooktime, mgcp_subchannel::parent, mgcp_endpoint::parent, mgcp_endpoint::pickupgroup, mgcp_endpoint::rqnt_ident, mgcp_subchannel::rtp, mgcp_endpoint::singlepath, singlepath, mgcp_endpoint::slowsequence, slowsequence, mgcp_endpoint::sub, mgcp_endpoint::threewaycalling, threewaycalling, mgcp_endpoint::transfer, transfer, mgcp_subchannel::txident, mgcp_endpoint::type, TYPE_LINE, TYPE_TRUNK, ast_variable::value, VERBOSE_PREFIX_3, and mgcp_gateway::wcardep. Referenced by reload_config(). 03536 { 03537 struct mgcp_gateway *gw; 03538 struct mgcp_endpoint *e; 03539 struct mgcp_subchannel *sub; 03540 /*char txident[80];*/ 03541 int i=0, y=0; 03542 int gw_reload = 0; 03543 int ep_reload = 0; 03544 canreinvite = CANREINVITE; 03545 03546 /* SC: locate existing gateway */ 03547 gw = gateways; 03548 while (gw) { 03549 if (!strcasecmp(cat, gw->name)) { 03550 /* gateway already exists */ 03551 gw->delme = 0; 03552 gw_reload = 1; 03553 break; 03554 } 03555 gw = gw->next; 03556 } 03557 03558 if (!gw) 03559 gw = malloc(sizeof(struct mgcp_gateway)); 03560 03561 if (gw) { 03562 if (!gw_reload) { 03563 memset(gw, 0, sizeof(struct mgcp_gateway)); 03564 gw->expire = -1; 03565 gw->retransid = -1; /* SC */ 03566 ast_mutex_init(&gw->msgs_lock); 03567 strncpy(gw->name, cat, sizeof(gw->name) - 1); 03568 /* SC: check if the name is numeric ip */ 03569 if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE) 03570 gw->isnamedottedip = 1; 03571 } 03572 while(v) { 03573 if (!strcasecmp(v->name, "host")) { 03574 if (!strcasecmp(v->value, "dynamic")) { 03575 /* They'll register with us */ 03576 gw->dynamic = 1; 03577 memset(&gw->addr.sin_addr, 0, 4); 03578 if (gw->addr.sin_port) { 03579 /* If we've already got a port, make it the default rather than absolute */ 03580 gw->defaddr.sin_port = gw->addr.sin_port; 03581 gw->addr.sin_port = 0; 03582 } 03583 } else { 03584 /* Non-dynamic. Make sure we become that way if we're not */ 03585 if (gw->expire > -1) 03586 ast_sched_del(sched, gw->expire); 03587 gw->expire = -1; 03588 gw->dynamic = 0; 03589 if (ast_get_ip(&gw->addr, v->value)) { 03590 if (!gw_reload) { 03591 ast_mutex_destroy(&gw->msgs_lock); 03592 free(gw); 03593 } 03594 return NULL; 03595 } 03596 } 03597 } else if (!strcasecmp(v->name, "defaultip")) { 03598 if (ast_get_ip(&gw->defaddr, v->value)) { 03599 if (!gw_reload) { 03600 ast_mutex_destroy(&gw->msgs_lock); 03601 free(gw); 03602 } 03603 return NULL; 03604 } 03605 } else if (!strcasecmp(v->name, "permit") || 03606 !strcasecmp(v->name, "deny")) { 03607 gw->ha = ast_append_ha(v->name, v->value, gw->ha); 03608 } else if (!strcasecmp(v->name, "port")) { 03609 gw->addr.sin_port = htons(atoi(v->value)); 03610 } else if (!strcasecmp(v->name, "context")) { 03611 strncpy(context, v->value, sizeof(context) - 1); 03612 } else if (!strcasecmp(v->name, "dtmfmode")) { 03613 if (!strcasecmp(v->value, "inband")) 03614 dtmfmode = MGCP_DTMF_INBAND; 03615 else if (!strcasecmp(v->value, "rfc2833")) 03616 dtmfmode = MGCP_DTMF_RFC2833; 03617 else if (!strcasecmp(v->value, "hybrid")) 03618 dtmfmode = MGCP_DTMF_HYBRID; 03619 else if (!strcasecmp(v->value, "none")) 03620 dtmfmode = 0; 03621 else 03622 ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno); 03623 } else if (!strcasecmp(v->name, "nat")) { 03624 nat = ast_true(v->value); 03625 } else if (!strcasecmp(v->name, "callerid")) { 03626 if (!strcasecmp(v->value, "asreceived")) { 03627 cid_num[0] = '\0'; 03628 cid_name[0] = '\0'; 03629 } else { 03630 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 03631 } 03632 } else if (!strcasecmp(v->name, "language")) { 03633 strncpy(language, v->value, sizeof(language)-1); 03634 } else if (!strcasecmp(v->name, "accountcode")) { 03635 strncpy(accountcode, v->value, sizeof(accountcode)-1); 03636 } else if (!strcasecmp(v->name, "amaflags")) { 03637 y = ast_cdr_amaflags2int(v->value); 03638 if (y < 0) { 03639 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 03640 } else { 03641 amaflags = y; 03642 } 03643 } else if (!strcasecmp(v->name, "musiconhold")) { 03644 strncpy(musicclass, v->value, sizeof(musicclass)-1); 03645 } else if (!strcasecmp(v->name, "callgroup")) { 03646 cur_callergroup = ast_get_group(v->value); 03647 } else if (!strcasecmp(v->name, "pickupgroup")) { 03648 cur_pickupgroup = ast_get_group(v->value); 03649 } else if (!strcasecmp(v->name, "immediate")) { 03650 immediate = ast_true(v->value); 03651 } else if (!strcasecmp(v->name, "cancallforward")) { 03652 cancallforward = ast_true(v->value); 03653 } else if (!strcasecmp(v->name, "singlepath")) { 03654 singlepath = ast_true(v->value); 03655 } else if (!strcasecmp(v->name, "canreinvite")) { 03656 canreinvite = ast_true(v->value); 03657 } else if (!strcasecmp(v->name, "mailbox")) { 03658 strncpy(mailbox, v->value, sizeof(mailbox) -1); 03659 } else if (!strcasecmp(v->name, "adsi")) { 03660 adsi = ast_true(v->value); 03661 } else if (!strcasecmp(v->name, "callreturn")) { 03662 callreturn = ast_true(v->value); 03663 } else if (!strcasecmp(v->name, "callwaiting")) { 03664 callwaiting = ast_true(v->value); 03665 } else if (!strcasecmp(v->name, "slowsequence")) { 03666 slowsequence = ast_true(v->value); 03667 } else if (!strcasecmp(v->name, "transfer")) { 03668 transfer = ast_true(v->value); 03669 } else if (!strcasecmp(v->name, "threewaycalling")) { 03670 threewaycalling = ast_true(v->value); 03671 } else if (!strcasecmp(v->name, "wcardep")) { 03672 /* SC: locate existing endpoint */ 03673 e = gw->endpoints; 03674 while (e) { 03675 if (!strcasecmp(v->value, e->name)) { 03676 /* endpoint already exists */ 03677 e->delme = 0; 03678 ep_reload = 1; 03679 break; 03680 } 03681 e = e->next; 03682 } 03683 03684 if (!e) { 03685 /* Allocate wildcard endpoint */ 03686 e = malloc(sizeof(struct mgcp_endpoint)); 03687 ep_reload = 0; 03688 } 03689 03690 if (e) { 03691 if (!ep_reload) { 03692 memset(e, 0, sizeof(struct mgcp_endpoint)); 03693 ast_mutex_init(&e->lock); 03694 ast_mutex_init(&e->rqnt_queue_lock); 03695 ast_mutex_init(&e->cmd_queue_lock); 03696 strncpy(e->name, v->value, sizeof(e->name) - 1); 03697 e->needaudit = 1; 03698 } 03699 strncpy(gw->wcardep, v->value, sizeof(gw->wcardep) - 1); 03700 /*strncpy(e->name, "aaln/" "*", sizeof(e->name) - 1);*/ 03701 /* XXX Should we really check for uniqueness?? XXX */ 03702 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03703 strncpy(e->context, context, sizeof(e->context) - 1); 03704 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03705 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03706 strncpy(e->language, language, sizeof(e->language) - 1); 03707 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03708 strncpy(e->mailbox, mailbox, sizeof(e->mailbox) - 1); 03709 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03710 e->msgstate = -1; 03711 e->amaflags = amaflags; 03712 e->capability = capability; 03713 e->parent = gw; 03714 e->dtmfmode = dtmfmode; 03715 if (!ep_reload && e->sub && e->sub->rtp) 03716 e->dtmfmode |= MGCP_DTMF_INBAND; 03717 e->adsi = adsi; 03718 e->type = TYPE_LINE; 03719 e->immediate = immediate; 03720 e->callgroup=cur_callergroup; 03721 e->pickupgroup=cur_pickupgroup; 03722 e->callreturn = callreturn; 03723 e->cancallforward = cancallforward; 03724 e->singlepath = singlepath; 03725 e->canreinvite = canreinvite; 03726 e->callwaiting = callwaiting; 03727 e->hascallwaiting = callwaiting; 03728 e->slowsequence = slowsequence; 03729 e->transfer = transfer; 03730 e->threewaycalling = threewaycalling; 03731 e->onhooktime = time(NULL); 03732 /* ASSUME we're onhook */ 03733 e->hookstate = MGCP_ONHOOK; 03734 if (!ep_reload) { 03735 /*snprintf(txident, sizeof(txident), "%08x", rand());*/ 03736 for (i = 0; i < MAX_SUBS; i++) { 03737 sub = malloc(sizeof(struct mgcp_subchannel)); 03738 if (sub) { 03739 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03740 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03741 ast_mutex_init(&sub->lock); 03742 ast_mutex_init(&sub->cx_queue_lock); 03743 sub->parent = e; 03744 sub->id = i; 03745 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03746 /*stnrcpy(sub->txident, txident, sizeof(sub->txident) - 1);*/ 03747 sub->cxmode = MGCP_CX_INACTIVE; 03748 sub->nat = nat; 03749 sub->next = e->sub; 03750 e->sub = sub; 03751 } else { 03752 /* XXX Should find a way to clean up our memory */ 03753 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03754 return NULL; 03755 } 03756 } 03757 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03758 sub = e->sub; 03759 /* find the end of the list */ 03760 while(sub->next){ 03761 sub = sub->next; 03762 } 03763 /* set the last sub->next to the first sub */ 03764 sub->next = e->sub; 03765 03766 e->next = gw->endpoints; 03767 gw->endpoints = e; 03768 } 03769 } 03770 } else if (!strcasecmp(v->name, "trunk") || 03771 !strcasecmp(v->name, "line")) { 03772 03773 /* SC: locate existing endpoint */ 03774 e = gw->endpoints; 03775 while (e) { 03776 if (!strcasecmp(v->value, e->name)) { 03777 /* endpoint already exists */ 03778 e->delme = 0; 03779 ep_reload = 1; 03780 break; 03781 } 03782 e = e->next; 03783 } 03784 03785 if (!e) { 03786 e = malloc(sizeof(struct mgcp_endpoint)); 03787 ep_reload = 0; 03788 } 03789 03790 if (e) { 03791 if (!ep_reload) { 03792 memset(e, 0, sizeof(struct mgcp_endpoint)); 03793 ast_mutex_init(&e->lock); 03794 ast_mutex_init(&e->rqnt_queue_lock); 03795 ast_mutex_init(&e->cmd_queue_lock); 03796 strncpy(e->name, v->value, sizeof(e->name) - 1); 03797 e->needaudit = 1; 03798 } 03799 /* XXX Should we really check for uniqueness?? XXX */ 03800 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03801 strncpy(e->context, context, sizeof(e->context) - 1); 03802 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03803 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03804 strncpy(e->language, language, sizeof(e->language) - 1); 03805 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03806 strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1); 03807 if (!ast_strlen_zero(mailbox)) { 03808 ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name); 03809 } 03810 if (!ep_reload) { 03811 /* XXX SC: potential issue due to reload */ 03812 e->msgstate = -1; 03813 e->parent = gw; 03814 } 03815 e->amaflags = amaflags; 03816 e->capability = capability; 03817 e->dtmfmode = dtmfmode; 03818 e->adsi = adsi; 03819 if (!strcasecmp(v->name, "trunk")) 03820 e->type = TYPE_TRUNK; 03821 else 03822 e->type = TYPE_LINE; 03823 03824 e->immediate = immediate; 03825 e->callgroup=cur_callergroup; 03826 e->pickupgroup=cur_pickupgroup; 03827 e->callreturn = callreturn; 03828 e->cancallforward = cancallforward; 03829 e->canreinvite = canreinvite; 03830 e->singlepath = singlepath; 03831 e->callwaiting = callwaiting; 03832 e->hascallwaiting = callwaiting; 03833 e->slowsequence = slowsequence; 03834 e->transfer = transfer; 03835 e->threewaycalling = threewaycalling; 03836 if (!ep_reload) { 03837 e->onhooktime = time(NULL); 03838 /* ASSUME we're onhook */ 03839 e->hookstate = MGCP_ONHOOK; 03840 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03841 } 03842 03843 for (i = 0, sub = NULL; i < MAX_SUBS; i++) { 03844 if (!ep_reload) { 03845 sub = malloc(sizeof(struct mgcp_subchannel)); 03846 } else { 03847 if (!sub) 03848 sub = e->sub; 03849 else 03850 sub = sub->next; 03851 } 03852 03853 if (sub) { 03854 if (!ep_reload) { 03855 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03856 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03857 ast_mutex_init(&sub->lock); 03858 ast_mutex_init(&sub->cx_queue_lock); 03859 strncpy(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic) - 1); 03860 sub->parent = e; 03861 sub->id = i; 03862 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03863 sub->cxmode = MGCP_CX_INACTIVE; 03864 sub->next = e->sub; 03865 e->sub = sub; 03866 } 03867 sub->nat = nat; 03868 } else { 03869 /* XXX Should find a way to clean up our memory */ 03870 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03871 return NULL; 03872 } 03873 } 03874 if (!ep_reload) { 03875 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03876 sub = e->sub; 03877 /* find the end of the list */ 03878 while (sub->next) { 03879 sub = sub->next; 03880 } 03881 /* set the last sub->next to the first sub */ 03882 sub->next = e->sub; 03883 03884 e->next = gw->endpoints; 03885 gw->endpoints = e; 03886 } 03887 } 03888 } else 03889 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 03890 v = v->next; 03891 } 03892 } 03893 if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) { 03894 ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name); 03895 if (!gw_reload) { 03896 ast_mutex_destroy(&gw->msgs_lock); 03897 free(gw); 03898 } 03899 return NULL; 03900 } 03901 gw->defaddr.sin_family = AF_INET; 03902 gw->addr.sin_family = AF_INET; 03903 if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port)) 03904 gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03905 if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) 03906 gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03907 if (gw->addr.sin_addr.s_addr) 03908 if (ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip)) 03909 memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip)); 03910 03911 return (gw_reload ? NULL : gw); 03912 }
|
|
Definition at line 1315 of file chan_mgcp.c. References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_TAKEOFFHOOK, and AST_CONTROL_WINK. Referenced by mgcp_indicate(), and skinny_indicate(). 01315 { 01316 switch (ind) { 01317 case AST_CONTROL_HANGUP: 01318 return "Other end has hungup"; 01319 case AST_CONTROL_RING: 01320 return "Local ring"; 01321 case AST_CONTROL_RINGING: 01322 return "Remote end is ringing"; 01323 case AST_CONTROL_ANSWER: 01324 return "Remote end has answered"; 01325 case AST_CONTROL_BUSY: 01326 return "Remote end is busy"; 01327 case AST_CONTROL_TAKEOFFHOOK: 01328 return "Make it go off hook"; 01329 case AST_CONTROL_OFFHOOK: 01330 return "Line is off hook"; 01331 case AST_CONTROL_CONGESTION: 01332 return "Congestion (circuits busy)"; 01333 case AST_CONTROL_FLASH: 01334 return "Flash hook"; 01335 case AST_CONTROL_WINK: 01336 return "Wink"; 01337 case AST_CONTROL_OPTION: 01338 return "Set a low-level option"; 01339 case AST_CONTROL_RADIO_KEY: 01340 return "Key Radio"; 01341 case AST_CONTROL_RADIO_UNKEY: 01342 return "Un-Key Radio"; 01343 } 01344 return "UNKNOWN"; 01345 }
|
|
Provides a description of the module.
Definition at line 4387 of file chan_mgcp.c. References desc. 04388 { 04389 return (char *) desc; 04390 }
|
|
Definition at line 3979 of file chan_mgcp.c. References ast_mutex_lock(), ast_strlen_zero(), mgcp_subchannel::cxident, mgcp_subchannel::lock, MAX_SUBS, mgcp_subchannel::next, s, mgcp_endpoint::sub, and transmit_connection_del(). Referenced by prune_gateways(). 03980 { 03981 struct mgcp_subchannel *sub = e->sub->next, *s; 03982 int i; 03983 03984 for (i = 0; i < MAX_SUBS; i++) { 03985 ast_mutex_lock(&sub->lock); 03986 if (!ast_strlen_zero(sub->cxident)) { 03987 transmit_connection_del(sub); 03988 } 03989 if (sub->rtp) { 03990 ast_rtp_destroy(sub->rtp); 03991 sub->rtp = NULL; 03992 } 03993 memset(sub->magic, 0, sizeof(sub->magic)); 03994 mgcp_queue_hangup(sub); 03995 dump_cmd_queues(NULL, sub); 03996 ast_mutex_unlock(&sub->lock); 03997 sub = sub->next; 03998 } 03999 04000 if (e->dsp) { 04001 ast_dsp_free(e->dsp); 04002 } 04003 04004 dump_queue(e->parent, e); 04005 dump_cmd_queues(e, NULL); 04006 04007 sub = e->sub; 04008 for (i = 0; (i < MAX_SUBS) && sub; i++) { 04009 s = sub; 04010 sub = sub->next; 04011 ast_mutex_destroy(&s->lock); 04012 ast_mutex_destroy(&s->cx_queue_lock); 04013 free(s); 04014 } 04015 ast_mutex_destroy(&e->lock); 04016 ast_mutex_destroy(&e->rqnt_queue_lock); 04017 ast_mutex_destroy(&e->cmd_queue_lock); 04018 free(e); 04019 }
|
|
Definition at line 4021 of file chan_mgcp.c. References ast_free_ha(), dump_queue(), free, and mgcp_gateway::ha. 04022 { 04023 if (g->ha) 04024 ast_free_ha(g->ha); 04025 04026 dump_queue(g, NULL); 04027 04028 free (g); 04029 }
|
|
Definition at line 3365 of file chan_mgcp.c. References ast_io_add(), AST_IO_IN, ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_verbose(), mgcp_gateway::endpoints, gateways, has_voicemail(), io, mgcp_do_reload(), MGCP_ONHOOK, mgcp_reloading, mgcpsock, mgcpsock_read(), option_verbose, transmit_notify_request(), TYPE_LINE, and VERBOSE_PREFIX_1. 03366 { 03367 int res; 03368 int reloading; 03369 /*struct mgcp_gateway *g;*/ 03370 /*struct mgcp_endpoint *e;*/ 03371 /*time_t thispass = 0, lastpass = 0;*/ 03372 03373 /* Add an I/O event to our UDP socket */ 03374 if (mgcpsock > -1) 03375 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03376 03377 /* This thread monitors all the frame relay interfaces which are not yet in use 03378 (and thus do not have a separate thread) indefinitely */ 03379 /* From here on out, we die whenever asked */ 03380 for(;;) { 03381 /* Check for a reload request */ 03382 ast_mutex_lock(&mgcp_reload_lock); 03383 reloading = mgcp_reloading; 03384 mgcp_reloading = 0; 03385 ast_mutex_unlock(&mgcp_reload_lock); 03386 if (reloading) { 03387 if (option_verbose > 0) 03388 ast_verbose(VERBOSE_PREFIX_1 "Reloading MGCP\n"); 03389 mgcp_do_reload(); 03390 /* Add an I/O event to our UDP socket */ 03391 if (mgcpsock > -1) 03392 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03393 } 03394 03395 /* Check for interfaces needing to be killed */ 03396 /* Don't let anybody kill us right away. Nobody should lock the interface list 03397 and wait for the monitor list, but the other way around is okay. */ 03398 ast_mutex_lock(&monlock); 03399 /* Lock the network interface */ 03400 ast_mutex_lock(&netlock); 03401 03402 #if 0 03403 /* XXX THIS IS COMPLETELY HOSED */ 03404 /* The gateway goes into a state of panic */ 03405 /* If the vmwi indicator is sent while it is reseting interfaces */ 03406 lastpass = thispass; 03407 thispass = time(NULL); 03408 g = gateways; 03409 while(g) { 03410 if (thispass != lastpass) { 03411 e = g->endpoints; 03412 while(e) { 03413 if (e->type == TYPE_LINE) { 03414 res = has_voicemail(e); 03415 if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){ 03416 if (res) { 03417 transmit_notify_request(e, "L/vmwi(+)"); 03418 } else { 03419 transmit_notify_request(e, "L/vmwi(-)"); 03420 } 03421 e->msgstate = res; 03422 e->onhooktime = thispass; 03423 } 03424 } 03425 e = e->next; 03426 } 03427 } 03428 g = g->next; 03429 } 03430 #endif 03431 /* Okay, now that we know what to do, release the network lock */ 03432 ast_mutex_unlock(&netlock); 03433 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 03434 ast_mutex_unlock(&monlock); 03435 pthread_testcancel(); 03436 /* Wait for sched or io */ 03437 res = ast_sched_wait(sched); 03438 /* SC: copied from chan_sip.c */ 03439 if ((res < 0) || (res > 1000)) 03440 res = 1000; 03441 res = ast_io_wait(io, res); 03442 ast_mutex_lock(&monlock); 03443 if (res >= 0) 03444 ast_sched_runq(sched); 03445 ast_mutex_unlock(&monlock); 03446 } 03447 /* Never reached */ 03448 return NULL; 03449 }
|
|
|
Definition at line 592 of file chan_mgcp.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), free, LOG_NOTICE, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, and mgcp_message::next. Referenced by destroy_gateway(), and handle_request(). 00593 { 00594 struct mgcp_message *cur, *q = NULL, *w, *prev; 00595 00596 ast_mutex_lock(&gw->msgs_lock); 00597 prev = NULL, cur = gw->msgs; 00598 while (cur) { 00599 if (!p || cur->owner_ep == p) { 00600 if (prev) 00601 prev->next = cur->next; 00602 else 00603 gw->msgs = cur->next; 00604 00605 ast_log(LOG_NOTICE, "Removing message from %s transaction %u\n", 00606 gw->name, cur->seqno); 00607 00608 w = cur; 00609 cur = cur->next; 00610 if (q) { 00611 w->next = q; 00612 } else { 00613 w->next = NULL; 00614 } 00615 q = w; 00616 } else { 00617 prev = cur, cur=cur->next; 00618 } 00619 } 00620 ast_mutex_unlock(&gw->msgs_lock); 00621 00622 while (q) { 00623 cur = q; 00624 q = q->next; 00625 free(cur); 00626 } 00627 }
|
|
Definition at line 3242 of file chan_mgcp.c. References answer, free, mgcp_request::identifier, mgcp_response::next, mgcp_endpoint::parent, mgcp_subchannel::parent, resend_response(), RESPONSE_TIMEOUT, and mgcp_gateway::responses. Referenced by mgcpsock_read(). 03243 { 03244 int seqno=0; 03245 time_t now; 03246 struct mgcp_response *prev = NULL, *cur, *next, *answer=NULL; 03247 time(&now); 03248 if (sscanf(req->identifier, "%d", &seqno) != 1) 03249 seqno = 0; 03250 cur = sub->parent->parent->responses; 03251 while(cur) { 03252 next = cur->next; 03253 if (now - cur->whensent > RESPONSE_TIMEOUT) { 03254 /* Delete this entry */ 03255 if (prev) 03256 prev->next = next; 03257 else 03258 sub->parent->parent->responses = next; 03259 free(cur); 03260 } else { 03261 if (seqno == cur->seqno) 03262 answer = cur; 03263 prev = cur; 03264 } 03265 cur = next; 03266 } 03267 if (answer) { 03268 resend_response(sub, answer); 03269 return 1; 03270 } 03271 return 0; 03272 }
|
|
Definition at line 2346 of file chan_mgcp.c. References mgcp_gateway::addr, ast_inet_ntoa(), ast_mutex_lock(), ast_verbose(), mgcp_request::next, and mgcp_endpoint::parent. Referenced by agi_handle_command(), handle_response(), and handle_showagi(). 02348 { 02349 struct mgcp_request *prev, *req; 02350 char iabuf[INET_ADDRSTRLEN]; 02351 02352 ast_mutex_lock(l); 02353 for (prev = NULL, req = *queue; req; prev = req, req = req->next) { 02354 if (req->trid == ident) { 02355 /* remove from queue */ 02356 if (!prev) 02357 *queue = req->next; 02358 else 02359 prev->next = req->next; 02360 02361 /* send next pending command */ 02362 if (*queue) { 02363 if (mgcpdebug) { 02364 ast_verbose("Posting Queued Request:\n%s to %s:%d\n", (*queue)->data, 02365 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 02366 } 02367 02368 mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid); 02369 } 02370 break; 02371 } 02372 } 02373 ast_mutex_unlock(l); 02374 return req; 02375 }
|
|
Definition at line 1544 of file chan_mgcp.c. References __ourip, mgcp_gateway::addr, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_ouraddrfor(), ast_verbose(), mgcp_gateway::defaddr, mgcp_gateway::dynamic, mgcp_gateway::endpoints, gateways, mgcp_subchannel::id, mgcp_subchannel::lock, LOG_DEBUG, LOG_NOTICE, mgcp_endpoint::name, mgcp_gateway::name, mgcp_endpoint::next, mgcp_subchannel::next, mgcp_gateway::next, option_debug, option_verbose, mgcp_gateway::ourip, mgcp_endpoint::sub, and VERBOSE_PREFIX_3. Referenced by mgcp_request(), and mgcpsock_read(). 01545 { 01546 struct mgcp_endpoint *p = NULL; 01547 struct mgcp_subchannel *sub = NULL; 01548 struct mgcp_gateway *g; 01549 char iabuf[INET_ADDRSTRLEN]; 01550 char tmp[256] = ""; 01551 char *at = NULL, *c; 01552 int found = 0; 01553 if (name) { 01554 strncpy(tmp, name, sizeof(tmp) - 1); 01555 at = strchr(tmp, '@'); 01556 if (!at) { 01557 ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name); 01558 return NULL; 01559 } 01560 *at = '\0'; 01561 at++; 01562 } 01563 ast_mutex_lock(&gatelock); 01564 if (at && (at[0] == '[')) { 01565 at++; 01566 c = strrchr(at, ']'); 01567 if (c) 01568 *c = '\0'; 01569 } 01570 g = gateways; 01571 while(g) { 01572 if ((!name || !strcasecmp(g->name, at)) && 01573 (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) { 01574 /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */ 01575 if (sin && g->dynamic && name) { 01576 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01577 (g->addr.sin_port != sin->sin_port)) { 01578 memcpy(&g->addr, sin, sizeof(g->addr)); 01579 if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip)) 01580 memcpy(&g->ourip, &__ourip, sizeof(g->ourip)); 01581 if (option_verbose > 2) 01582 ast_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, ast_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr), ntohs(g->addr.sin_port)); 01583 } 01584 } 01585 /* SC: not dynamic, check if the name matches */ 01586 else if (name) { 01587 if (strcasecmp(g->name, at)) { 01588 g = g->next; 01589 continue; 01590 } 01591 } 01592 /* SC: not dynamic, no name, check if the addr matches */ 01593 else if (!name && sin) { 01594 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01595 (g->addr.sin_port != sin->sin_port)) { 01596 g = g->next; 01597 continue; 01598 } 01599 } else { 01600 g = g->next; 01601 continue; 01602 } 01603 /* SC */ 01604 p = g->endpoints; 01605 while(p) { 01606 if (option_debug) 01607 ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n", 01608 p->name, g->name); 01609 if (msgid) { 01610 #if 0 /* SC: new transport mech */ 01611 sub = p->sub; 01612 do { 01613 if (option_debug) 01614 ast_log(LOG_DEBUG, "Searching on %s@%s-%d for subchannel with lastout: %d\n", 01615 p->name, g->name, sub->id, msgid); 01616 if (sub->lastout == msgid) { 01617 if (option_debug) 01618 ast_log(LOG_DEBUG, "Found subchannel sub%d to handle request %d sub->lastout: %d\n", 01619 sub->id, msgid, sub->lastout); 01620 found = 1; 01621 break; 01622 } 01623 sub = sub->next; 01624 } while (sub != p->sub); 01625 if (found) { 01626 break; 01627 } 01628 #endif 01629 /* SC */ 01630 sub = p->sub; 01631 found = 1; 01632 /* SC */ 01633 break; 01634 } else if (name && !strcasecmp(p->name, tmp)) { 01635 ast_log(LOG_DEBUG, "Coundn't determine subchannel, assuming current master %s@%s-%d\n", 01636 p->name, g->name, p->sub->id); 01637 sub = p->sub; 01638 found = 1; 01639 break; 01640 } 01641 p = p->next; 01642 } 01643 if (sub && found) { 01644 ast_mutex_lock(&sub->lock); 01645 break; 01646 } 01647 } 01648 g = g->next; 01649 } 01650 ast_mutex_unlock(&gatelock); 01651 if (!sub) { 01652 if (name) { 01653 if (g) 01654 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at); 01655 else 01656 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp); 01657 } 01658 } 01659 return sub; 01660 }
|
|
Definition at line 1523 of file chan_mgcp.c. References s. Referenced by handle_response(). 01524 { 01525 char *s; 01526 01527 *next = NULL, *len = 0; 01528 if (!c) return NULL; 01529 01530 while (*c && (*c < 33 || *c == ',')) 01531 c++; 01532 01533 s = c; 01534 while (*c && (*c >= 33 && *c != ',')) 01535 c++, (*len)++; 01536 *next = c; 01537 01538 if (*len == 0) 01539 s = NULL, *next = NULL; 01540 01541 return s; 01542 }
|
|
Definition at line 1516 of file chan_mgcp.c. References __get_header(). Referenced by __transmit_response(), check_auth(), check_user_full(), check_via(), copy_header(), extract_uri(), find_call(), find_sdp(), func_header_read(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), gettag(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), handle_response_register(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), receive_message(), register_verify(), reply_digest(), reqprep(), respprep(), send_request(), send_response(), sip_getheader(), sip_sipredirect(), sipsock_read(), transmit_refer(), transmit_response_with_auth(), transmit_response_with_sdp(), and transmit_state_notify(). 01517 { 01518 int start = 0; 01519 return __get_header(req, name, &start); 01520 }
|
|
Definition at line 1468 of file chan_mgcp.c. References get_sdp_by_line(), mgcp_request::line, and mgcp_request::lines. Referenced by process_sdp(). 01469 { 01470 int x; 01471 int len = strlen(name); 01472 char *r; 01473 01474 for (x=0; x<req->lines; x++) { 01475 r = get_sdp_by_line(req->line[x], name, len); 01476 if (r[0] != '\0') return r; 01477 } 01478 return ""; 01479 }
|
|
Definition at line 1458 of file chan_mgcp.c. Referenced by get_sdp(), and get_sdp_iterate(). 01459 { 01460 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 01461 char* r = line + nameLen + 1; 01462 while (*r && (*r < 33)) ++r; 01463 return r; 01464 } 01465 return ""; 01466 }
|
|
Definition at line 1486 of file chan_mgcp.c. References get_sdp_by_line(), and mgcp_request::line. Referenced by process_sdp(). 01487 { 01488 int len = strlen(name); 01489 char *r; 01490 while (*iterator < req->lines) { 01491 r = get_sdp_by_line(req->line[(*iterator)++], name, len); 01492 if (r[0] != '\0') return r; 01493 } 01494 return ""; 01495 }
|
|
Definition at line 2881 of file chan_mgcp.c. References ast_bridged_channel(), AST_CONTROL_ANSWER, ast_hangup(), ast_log(), ast_moh_stop(), ast_pthread_create, AST_STATE_DOWN, AST_STATE_RING, mgcp_subchannel::cxmode, has_voicemail(), mgcp_endpoint::hookstate, mgcp_endpoint::immediate, LOG_WARNING, MGCP_CX_SENDRECV, mgcp_new(), MGCP_OFFHOOK, mgcp_queue_control(), mgcp_ss(), mgcp_gateway::name, mgcp_endpoint::name, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, start_rtp(), mgcp_endpoint::sub, t, transmit_modify_request(), and transmit_notify_request(). Referenced by handle_request(). 02882 { 02883 struct mgcp_endpoint *p = sub->parent; 02884 struct ast_channel *c; 02885 pthread_t t; 02886 pthread_attr_t attr; 02887 pthread_attr_init(&attr); 02888 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02889 02890 /* Off hook / answer */ 02891 if (sub->outgoing) { 02892 /* Answered */ 02893 if (sub->owner) { 02894 if (ast_bridged_channel(sub->owner)) { 02895 ast_moh_stop(ast_bridged_channel(sub->owner)); 02896 } 02897 sub->cxmode = MGCP_CX_SENDRECV; 02898 if (!sub->rtp) { 02899 start_rtp(sub); 02900 } else { 02901 transmit_modify_request(sub); 02902 } 02903 /*transmit_notify_request(sub, "aw");*/ 02904 transmit_notify_request(sub, ""); 02905 mgcp_queue_control(sub, AST_CONTROL_ANSWER); 02906 } 02907 } else { 02908 /* Start switch */ 02909 /*sub->cxmode = MGCP_CX_SENDRECV;*/ 02910 if (!sub->owner) { 02911 if (!sub->rtp) { 02912 start_rtp(sub); 02913 } else { 02914 transmit_modify_request(sub); 02915 } 02916 if (p->immediate) { 02917 /* The channel is immediately up. Start right away */ 02918 #ifdef DLINK_BUGGY_FIRMWARE 02919 transmit_notify_request(sub, "rt"); 02920 #else 02921 transmit_notify_request(sub, "G/rt"); 02922 #endif 02923 c = mgcp_new(sub, AST_STATE_RING); 02924 if (!c) { 02925 ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name); 02926 transmit_notify_request(sub, "G/cg"); 02927 ast_hangup(c); 02928 } 02929 } else { 02930 if (has_voicemail(p)) { 02931 transmit_notify_request(sub, "L/sl"); 02932 } else { 02933 transmit_notify_request(sub, "L/dl"); 02934 } 02935 c = mgcp_new(sub, AST_STATE_DOWN); 02936 if (c) { 02937 if (ast_pthread_create(&t, &attr, mgcp_ss, c)) { 02938 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 02939 ast_hangup(c); 02940 } 02941 } else { 02942 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name); 02943 } 02944 } 02945 } else { 02946 if (p->hookstate == MGCP_OFFHOOK) { 02947 ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02948 } else { 02949 ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02950 ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?"); 02951 } 02952 if (ast_bridged_channel(sub->owner)) { 02953 ast_moh_stop(ast_bridged_channel(sub->owner)); 02954 } 02955 sub->cxmode = MGCP_CX_SENDRECV; 02956 if (!sub->rtp) { 02957 start_rtp(sub); 02958 } else { 02959 transmit_modify_request(sub); 02960 } 02961 /*transmit_notify_request(sub, "aw");*/ 02962 transmit_notify_request(sub, ""); 02963 /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/ 02964 } 02965 } 02966 }
|
|
Definition at line 2968 of file chan_mgcp.c. References ast_channel::_state, mgcp_subchannel::alreadygone, ast_bridged_channel(), AST_FRAME_DTMF, ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, AST_STATE_UP, ast_verbose(), attempt_transfer(), mgcp_endpoint::callwaiting, mgcp_endpoint::curtone, mgcp_subchannel::cxmode, dump_cmd_queues(), dump_queue(), mgcp_gateway::endpoints, ast_frame::frametype, get_header(), handle_hd_hf(), has_voicemail(), mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_subchannel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, MGCP_CX_CONF, MGCP_CX_MUTE, MGCP_CX_RECVONLY, MGCP_CX_SENDRECV, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_queue_frame(), mgcp_queue_hangup(), mgcp_gateway::name, mgcp_endpoint::name, mgcp_subchannel::next, mgcp_endpoint::next, option_verbose, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, s, ast_frame::src, mgcp_endpoint::sub, ast_frame::subclass, mgcp_endpoint::threewaycalling, mgcp_endpoint::transfer, transmit_audit_endpoint(), transmit_connection_del(), transmit_modify_request(), transmit_notify_request(), transmit_response(), mgcp_request::verb, VERBOSE_PREFIX_3, and mgcp_gateway::wcardep. Referenced by mgcpsock_read(), and sipsock_read(). 02969 { 02970 char *ev, *s; 02971 struct ast_frame f = { 0, }; 02972 struct mgcp_endpoint *p = sub->parent; 02973 struct mgcp_gateway *g = NULL; 02974 char iabuf[INET_ADDRSTRLEN]; 02975 int res; 02976 02977 if (mgcpdebug) { 02978 ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name); 02979 } 02980 /* Clear out potential response */ 02981 if (!strcasecmp(req->verb, "RSIP")) { 02982 /* Test if this RSIP request is just a keepalive */ 02983 if(!strcasecmp( get_header(req, "RM"), "X-keepalive")) { 02984 if (option_verbose > 2) 02985 ast_verbose(VERBOSE_PREFIX_3 "Received keepalive request from %s@%s\n", p->name, p->parent->name); 02986 transmit_response(sub, "200", req, "OK"); 02987 } else { 02988 dump_queue(p->parent, p); 02989 dump_cmd_queues(p, NULL); 02990 02991 if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) { 02992 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); 02993 } 02994 /* JS: For RSIP on wildcard we reset all endpoints */ 02995 if (!strcmp(p->name, p->parent->wcardep)) { 02996 /* Reset all endpoints */ 02997 struct mgcp_endpoint *tmp_ep; 02998 02999 g = p->parent; 03000 tmp_ep = g->endpoints; 03001 while (tmp_ep) { 03002 /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/ 03003 if (strcmp(tmp_ep->name, g->wcardep) != 0) { 03004 struct mgcp_subchannel *tmp_sub, *first_sub; 03005 if (option_verbose > 2) { 03006 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name); 03007 } 03008 03009 first_sub = tmp_ep->sub; 03010 tmp_sub = tmp_ep->sub; 03011 while (tmp_sub) { 03012 mgcp_queue_hangup(tmp_sub); 03013 tmp_sub = tmp_sub->next; 03014 if (tmp_sub == first_sub) 03015 break; 03016 } 03017 } 03018 tmp_ep = tmp_ep->next; 03019 } 03020 } else if (sub->owner) { 03021 mgcp_queue_hangup(sub); 03022 } 03023 transmit_response(sub, "200", req, "OK"); 03024 /* JS: We dont send NTFY or AUEP to wildcard ep */ 03025 if (strcmp(p->name, p->parent->wcardep) != 0) { 03026 transmit_notify_request(sub, ""); 03027 /* SC: Audit endpoint. 03028 Idea is to prevent lost lines due to race conditions 03029 */ 03030 transmit_audit_endpoint(p); 03031 } 03032 } 03033 } else if (!strcasecmp(req->verb, "NTFY")) { 03034 /* Acknowledge and be sure we keep looking for the same things */ 03035 transmit_response(sub, "200", req, "OK"); 03036 /* Notified of an event */ 03037 ev = get_header(req, "O"); 03038 s = strchr(ev, '/'); 03039 if (s) ev = s + 1; 03040 ast_log(LOG_DEBUG, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev); 03041 /* Keep looking for events unless this was a hangup */ 03042 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) { 03043 transmit_notify_request(sub, p->curtone); 03044 } 03045 if (!strcasecmp(ev, "hd")) { 03046 p->hookstate = MGCP_OFFHOOK; 03047 sub->cxmode = MGCP_CX_SENDRECV; 03048 handle_hd_hf(sub, ev); 03049 } else if (!strcasecmp(ev, "hf")) { 03050 /* We can assume we are offhook if we received a hookflash */ 03051 /* First let's just do call wait and ignore threeway */ 03052 /* We're currently in charge */ 03053 if (p->hookstate != MGCP_OFFHOOK) { 03054 /* Cisco c7940 sends hf even if the phone is onhook */ 03055 /* Thanks to point on IRC for pointing this out */ 03056 return -1; 03057 } 03058 /* do not let * conference two down channels */ 03059 if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) 03060 return -1; 03061 03062 if (p->callwaiting || p->transfer || p->threewaycalling) { 03063 if (option_verbose > 2) { 03064 ast_verbose(VERBOSE_PREFIX_3 "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name); 03065 } 03066 p->sub = p->sub->next; 03067 03068 /* transfer control to our next subchannel */ 03069 if (!sub->next->owner) { 03070 /* plave the first call on hold and start up a new call */ 03071 sub->cxmode = MGCP_CX_MUTE; 03072 if (option_verbose > 2) { 03073 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03074 } 03075 transmit_modify_request(sub); 03076 if (sub->owner && ast_bridged_channel(sub->owner)) { 03077 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03078 } 03079 sub->next->cxmode = MGCP_CX_RECVONLY; 03080 handle_hd_hf(sub->next, ev); 03081 } else if (sub->owner && sub->next->owner) { 03082 /* We've got two active calls lets decide whether or not to conference or just flip flop */ 03083 if ((!sub->outgoing) && (!sub->next->outgoing)) { 03084 /* We made both calls lets conferenct */ 03085 if (option_verbose > 2) { 03086 ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", 03087 sub->id, sub->next->id, p->name, p->parent->name); 03088 } 03089 sub->cxmode = MGCP_CX_CONF; 03090 sub->next->cxmode = MGCP_CX_CONF; 03091 if (ast_bridged_channel(sub->next->owner)) 03092 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03093 transmit_modify_request(sub); 03094 transmit_modify_request(sub->next); 03095 } else { 03096 /* Let's flipflop between calls */ 03097 /* XXX Need to check for state up ??? */ 03098 /* XXX Need a way to indicate the current call, or maybe the call that's waiting */ 03099 if (option_verbose > 2) { 03100 ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", 03101 sub->id, sub->next->id, p->name, p->parent->name); 03102 } 03103 sub->cxmode = MGCP_CX_MUTE; 03104 if (option_verbose > 2) { 03105 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03106 } 03107 transmit_modify_request(sub); 03108 if (ast_bridged_channel(sub->owner)) 03109 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03110 03111 if (ast_bridged_channel(sub->next->owner)) 03112 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03113 03114 handle_hd_hf(sub->next, ev); 03115 #if 0 03116 if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { 03117 handle_hd_hf(sub->next, ev); 03118 } else { 03119 ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); 03120 sub->next->cxmode = MGCP_CX_SENDRECV; 03121 transmit_modify_request(sub->next); 03122 } 03123 #endif 03124 } 03125 } else { 03126 /* We've most likely lost one of our calls find an active call and bring it up */ 03127 if (sub->owner) { 03128 p->sub = sub; 03129 } else if (sub->next->owner) { 03130 p->sub = sub->next; 03131 } else { 03132 /* We seem to have lost both our calls */ 03133 /* XXX - What do we do now? */ 03134 return -1; 03135 } 03136 if (ast_bridged_channel(p->sub->owner)) { 03137 ast_moh_stop(ast_bridged_channel(p->sub->owner)); 03138 } 03139 p->sub->cxmode = MGCP_CX_SENDRECV; 03140 transmit_modify_request(p->sub); 03141 } 03142 } else { 03143 ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", 03144 p->name, p->parent->name); 03145 } 03146 /*ast_moh_stop(sub->owner->bridge);*/ 03147 } else if (!strcasecmp(ev, "hu")) { 03148 p->hookstate = MGCP_ONHOOK; 03149 sub->cxmode = MGCP_CX_RECVONLY; 03150 ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); 03151 /* JS: Do we need to send MDCX before a DLCX ? 03152 if (sub->rtp) { 03153 transmit_modify_request(sub); 03154 } 03155 */ 03156 if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { 03157 /* We're allowed to transfer, we have two avtive calls and */ 03158 /* we made at least one of the calls. Let's try and transfer */ 03159 ast_mutex_lock(&p->sub->next->lock); 03160 res = attempt_transfer(p); 03161 if (res < 0) { 03162 if (p->sub->next->owner) { 03163 sub->next->alreadygone = 1; 03164 mgcp_queue_hangup(sub->next); 03165 } 03166 } else if (res) { 03167 ast_log(LOG_WARNING, "Transfer attempt failed\n"); 03168 ast_mutex_unlock(&p->sub->next->lock); 03169 return -1; 03170 } 03171 ast_mutex_unlock(&p->sub->next->lock); 03172 } else { 03173 /* Hangup the current call */ 03174 /* If there is another active call, mgcp_hangup will ring the phone with the other call */ 03175 if (sub->owner) { 03176 sub->alreadygone = 1; 03177 mgcp_queue_hangup(sub); 03178 } else { 03179 /* SC: verbose level check */ 03180 if (option_verbose > 2) { 03181 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n", 03182 p->name, p->parent->name, sub->id); 03183 } 03184 /* Instruct the other side to remove the connection since it apparently * 03185 * still thinks the channel is active. * 03186 * For Cisco IAD2421 /BAK/ */ 03187 transmit_connection_del(sub); 03188 } 03189 } 03190 if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) { 03191 p->hidecallerid = 0; 03192 if (p->hascallwaiting && !p->callwaiting) { 03193 if (option_verbose > 2) 03194 ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id); 03195 p->callwaiting = -1; 03196 } 03197 if (has_voicemail(p)) { 03198 if (option_verbose > 2) { 03199 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name); 03200 } 03201 transmit_notify_request(sub, "L/vmwi(+)"); 03202 } else { 03203 if (option_verbose > 2) { 03204 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name); 03205 } 03206 transmit_notify_request(sub, "L/vmwi(-)"); 03207 } 03208 } 03209 } else if ((strlen(ev) == 1) && 03210 (((ev[0] >= '0') && (ev[0] <= '9')) || 03211 ((ev[0] >= 'A') && (ev[0] <= 'D')) || 03212 (ev[0] == '*') || (ev[0] == '#'))) { 03213 f.frametype = AST_FRAME_DTMF; 03214 f.subclass = ev[0]; 03215 f.src = "mgcp"; 03216 if (sub->owner) { 03217 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ 03218 mgcp_queue_frame(sub, &f); 03219 ast_mutex_lock(&sub->next->lock); 03220 if (sub->next->owner) { 03221 mgcp_queue_frame(sub->next, &f); 03222 } 03223 ast_mutex_unlock(&sub->next->lock); 03224 } 03225 if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { 03226 memset(p->curtone, 0, sizeof(p->curtone)); 03227 } 03228 } else if (!strcasecmp(ev, "T")) { 03229 /* Digit timeout -- unimportant */ 03230 } else if (!strcasecmp(ev, "ping")) { 03231 /* ping -- unimportant */ 03232 } else { 03233 ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name); 03234 } 03235 } else { 03236 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 03237 transmit_response(sub, "510", req, "Unknown verb"); 03238 } 03239 return 0; 03240 }
|
|
Definition at line 2378 of file chan_mgcp.c. References ast_log(), ast_strlen_zero(), ast_verbose(), mgcp_request::cmd, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxident, dump_cmd_queues(), find_command(), free, get_csv(), get_header(), mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_request::lines, LOG_NOTICE, LOG_WARNING, MGCP_CMD_AUEP, MGCP_CMD_CRCX, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_queue_hangup(), n, mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_endpoint::parent, process_sdp(), mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, mgcp_endpoint::slowsequence, start_rtp(), mgcp_endpoint::sub, mgcp_subchannel::tmpdest, transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_with_sdp(), transmit_notify_request(), and VERBOSE_PREFIX_3. Referenced by handle_request(), mgcpsock_read(), and retrans_pkt(). 02380 { 02381 char *c; 02382 struct mgcp_request *req; 02383 struct mgcp_gateway *gw = p->parent; 02384 02385 if (result < 200) { 02386 /* provisional response */ 02387 return; 02388 } 02389 02390 if (p->slowsequence) 02391 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02392 else if (sub) 02393 req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident); 02394 else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident))) 02395 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02396 02397 if (!req) { 02398 if (option_verbose > 2) { 02399 ast_verbose(VERBOSE_PREFIX_3 "No command found on [%s] for transaction %d. Ignoring...\n", 02400 gw->name, ident); 02401 } 02402 return; 02403 } 02404 02405 if (p && (result >= 400) && (result <= 599)) { 02406 switch (result) { 02407 case 401: 02408 p->hookstate = MGCP_OFFHOOK; 02409 break; 02410 case 402: 02411 p->hookstate = MGCP_ONHOOK; 02412 break; 02413 case 406: 02414 ast_log(LOG_NOTICE, "Transaction %d timed out\n", ident); 02415 break; 02416 case 407: 02417 ast_log(LOG_NOTICE, "Transaction %d aborted\n", ident); 02418 break; 02419 } 02420 if (sub) { 02421 if (sub->owner) { 02422 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02423 result, p->name, p->parent->name, sub ? sub->id:-1); 02424 mgcp_queue_hangup(sub); 02425 } 02426 } else { 02427 if (p->sub->next->owner) { 02428 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02429 result, p->name, p->parent->name, sub ? sub->id:-1); 02430 mgcp_queue_hangup(p->sub); 02431 } 02432 02433 if (p->sub->owner) { 02434 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02435 result, p->name, p->parent->name, sub ? sub->id:-1); 02436 mgcp_queue_hangup(p->sub); 02437 } 02438 02439 dump_cmd_queues(p, NULL); 02440 } 02441 } 02442 02443 if (resp) { 02444 if (req->cmd == MGCP_CMD_CRCX) { 02445 if ((c = get_header(resp, "I"))) { 02446 if (!ast_strlen_zero(c) && sub) { 02447 /* SC: if we are hanging up do not process this conn. */ 02448 if (sub->owner) { 02449 if (!ast_strlen_zero(sub->cxident)) { 02450 if (strcasecmp(c, sub->cxident)) { 02451 ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c); 02452 } 02453 } 02454 strncpy(sub->cxident, c, sizeof(sub->cxident) - 1); 02455 if (sub->tmpdest.sin_addr.s_addr) { 02456 transmit_modify_with_sdp(sub, NULL, 0); 02457 } 02458 } else { 02459 /* XXX SC: delete this one 02460 callid and conn id may already be lost. 02461 so the following del conn may have a side effect of 02462 cleaning up the next subchannel */ 02463 transmit_connection_del(sub); 02464 } 02465 } 02466 } 02467 } 02468 02469 if (req->cmd == MGCP_CMD_AUEP) { 02470 /* SC: check stale connection ids */ 02471 if ((c = get_header(resp, "I"))) { 02472 char *v, *n; 02473 int len; 02474 while ((v = get_csv(c, &len, &n))) { 02475 if (len) { 02476 if (strncasecmp(v, p->sub->cxident, len) && 02477 strncasecmp(v, p->sub->next->cxident, len)) { 02478 /* connection id not found. delete it */ 02479 char cxident[80] = ""; 02480 02481 if (len > (sizeof(cxident) - 1)) 02482 len = sizeof(cxident) - 1; 02483 ast_copy_string(cxident, v, len); 02484 if (option_verbose > 2) { 02485 ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n", 02486 cxident, p->name, gw->name); 02487 } 02488 transmit_connection_del_w_params(p, NULL, cxident); 02489 } 02490 } 02491 c = n; 02492 } 02493 } 02494 02495 /* Try to determine the hookstate returned from an audit endpoint command */ 02496 if ((c = get_header(resp, "ES"))) { 02497 if (!ast_strlen_zero(c)) { 02498 if (strstr(c, "hu")) { 02499 if (p->hookstate != MGCP_ONHOOK) { 02500 /* SC: XXX cleanup if we think we are offhook XXX */ 02501 if ((p->sub->owner || p->sub->next->owner ) && 02502 p->hookstate == MGCP_OFFHOOK) 02503 mgcp_queue_hangup(sub); 02504 p->hookstate = MGCP_ONHOOK; 02505 02506 /* SC: update the requested events according to the new hookstate */ 02507 transmit_notify_request(p->sub, ""); 02508 02509 /* SC: verbose level check */ 02510 if (option_verbose > 2) { 02511 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name); 02512 } 02513 } 02514 } else if (strstr(c, "hd")) { 02515 if (p->hookstate != MGCP_OFFHOOK) { 02516 p->hookstate = MGCP_OFFHOOK; 02517 02518 /* SC: update the requested events according to the new hookstate */ 02519 transmit_notify_request(p->sub, ""); 02520 02521 /* SC: verbose level check */ 02522 if (option_verbose > 2) { 02523 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name); 02524 } 02525 } 02526 } 02527 } 02528 } 02529 } 02530 02531 if (resp && resp->lines) { 02532 /* SC: do not process sdp if we are hanging up. this may be a late response */ 02533 if (sub && sub->owner) { 02534 if (!sub->rtp) 02535 start_rtp(sub); 02536 if (sub->rtp) 02537 process_sdp(sub, resp); 02538 } 02539 } 02540 } 02541 02542 free(req); 02543 }
|
|
Definition at line 517 of file chan_mgcp.c. References ast_app_has_voicemail(), and mgcp_endpoint::mailbox. Referenced by do_housekeeping(), do_monitor(), handle_hd_hf(), handle_init_event(), handle_request(), has_voicemail(), load_module(), mgcp_hangup(), mgcp_request(), vm_execmain(), and zt_handle_event(). 00518 { 00519 return ast_app_has_voicemail(p->mailbox, NULL); 00520 }
|
|
Definition at line 1911 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_gateway::isnamedottedip, mgcp_request::len, LOG_WARNING, MGCP_MAX_HEADERS, mgcp_gateway::name, mgcp_endpoint::name, oseq, and mgcp_endpoint::parent. Referenced by reqprep(), and transmit_register(). 01912 { 01913 /* Initialize a response */ 01914 if (req->headers || req->len) { 01915 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01916 return -1; 01917 } 01918 req->header[req->headers] = req->data + req->len; 01919 /* SC: check if we need brackets around the gw name */ 01920 if (p->parent->isnamedottedip) 01921 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@[%s] MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name); 01922 else 01923 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@%s MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name); 01924 req->len += strlen(req->header[req->headers]); 01925 if (req->headers < MGCP_MAX_HEADERS) 01926 req->headers++; 01927 else 01928 ast_log(LOG_WARNING, "Out of header space\n"); 01929 return 0; 01930 }
|
|
Definition at line 1894 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_request::identifier, mgcp_request::len, LOG_WARNING, and MGCP_MAX_HEADERS. Referenced by respprep(). 01895 { 01896 /* Initialize a response */ 01897 if (req->headers || req->len) { 01898 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01899 return -1; 01900 } 01901 req->header[req->headers] = req->data + req->len; 01902 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest); 01903 req->len += strlen(req->header[req->headers]); 01904 if (req->headers < MGCP_MAX_HEADERS) 01905 req->headers++; 01906 else 01907 ast_log(LOG_WARNING, "Out of header space\n"); 01908 return 0; 01909 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 4382 of file chan_mgcp.c. References ASTERISK_GPL_KEY. 04383 { 04384 return ASTERISK_GPL_KEY; 04385 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 4246 of file chan_mgcp.c. References ast_channel_register(), ast_cli_register(), ast_log(), ast_rtp_proto_register(), cli_audit_endpoint, cli_debug, cli_mgcp_reload, cli_no_debug, cli_show_endpoints, io, io_context_create(), LOG_ERROR, LOG_WARNING, mgcp_rtp, mgcp_tech, reload_config(), restart_monitor(), sched_context_create(), and type. 04247 { 04248 int res; 04249 04250 sched = sched_context_create(); 04251 if (!sched) { 04252 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 04253 return -1; 04254 } 04255 io = io_context_create(); 04256 if (!io) { 04257 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 04258 return -1; 04259 } 04260 04261 if (!(res = reload_config())) { 04262 /* Make sure we can register our mgcp channel type */ 04263 if (ast_channel_register(&mgcp_tech)) { 04264 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 04265 return -1; 04266 } 04267 ast_rtp_proto_register(&mgcp_rtp); 04268 ast_cli_register(&cli_show_endpoints); 04269 ast_cli_register(&cli_audit_endpoint); 04270 ast_cli_register(&cli_debug); 04271 ast_cli_register(&cli_no_debug); 04272 ast_cli_register(&cli_mgcp_reload); 04273 04274 /* And start the monitor for the first time */ 04275 restart_monitor(); 04276 } 04277 04278 return res; 04279 }
|
|
|
Definition at line 1122 of file chan_mgcp.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), mgcp_gateway::endpoints, gateways, mgcpdebug, mgcp_endpoint::name, mgcp_gateway::name, mgcp_gateway::next, mgcp_endpoint::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, and transmit_audit_endpoint(). 01123 { 01124 struct mgcp_gateway *g; 01125 struct mgcp_endpoint *e; 01126 int found = 0; 01127 char *ename,*gname, *c; 01128 01129 if (!mgcpdebug) { 01130 return RESULT_SHOWUSAGE; 01131 } 01132 if (argc != 4) 01133 return RESULT_SHOWUSAGE; 01134 /* split the name into parts by null */ 01135 ename = argv[3]; 01136 gname = ename; 01137 while (*gname) { 01138 if (*gname == '@') { 01139 *gname = 0; 01140 gname++; 01141 break; 01142 } 01143 gname++; 01144 } 01145 if (gname[0] == '[') 01146 gname++; 01147 if ((c = strrchr(gname, ']'))) 01148 *c = '\0'; 01149 ast_mutex_lock(&gatelock); 01150 g = gateways; 01151 while(g) { 01152 if (!strcasecmp(g->name, gname)) { 01153 e = g->endpoints; 01154 while(e) { 01155 if (!strcasecmp(e->name, ename)) { 01156 found = 1; 01157 transmit_audit_endpoint(e); 01158 break; 01159 } 01160 e = e->next; 01161 } 01162 if (found) { 01163 break; 01164 } 01165 } 01166 g = g->next; 01167 } 01168 if (!found) { 01169 ast_cli(fd, " << Could not find endpoint >> "); 01170 } 01171 ast_mutex_unlock(&gatelock); 01172 return RESULT_SUCCESS; 01173 }
|
|
Definition at line 886 of file chan_mgcp.c. References ast_channel::_state, AST_CONTROL_RINGING, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_control(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strlen_zero(), ast_var_name(), ast_var_value(), ast_verbose(), mgcp_subchannel::callid, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_endpoint::hookstate, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, MGCP_CX_RECVONLY, MGCP_CX_SENDRECV, MGCP_OFFHOOK, MGCP_ONHOOK, mgcpdebug, ast_channel::name, mgcp_subchannel::next, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_subchannel::rtp, start_rtp(), ast_channel::tech_pvt, transmit_modify_request(), transmit_notify_request_with_callerid(), mgcp_endpoint::type, TYPE_LINE, ast_channel::varshead, and VERBOSE_PREFIX_3. 00887 { 00888 int res; 00889 struct mgcp_endpoint *p; 00890 struct mgcp_subchannel *sub; 00891 char tone[50] = ""; 00892 char *distinctive_ring = NULL; 00893 struct varshead *headp; 00894 struct ast_var_t *current; 00895 00896 if (mgcpdebug) { 00897 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_call(%s)\n", ast->name); 00898 } 00899 sub = ast->tech_pvt; 00900 p = sub->parent; 00901 headp = &ast->varshead; 00902 AST_LIST_TRAVERSE(headp,current,entries) { 00903 /* Check whether there is an ALERT_INFO variable */ 00904 if (strcasecmp(ast_var_name(current),"ALERT_INFO") == 0) { 00905 distinctive_ring = ast_var_value(current); 00906 } 00907 } 00908 00909 ast_mutex_lock(&sub->lock); 00910 switch (p->hookstate) { 00911 case MGCP_OFFHOOK: 00912 if (!ast_strlen_zero(distinctive_ring)) { 00913 snprintf(tone, sizeof(tone), "L/wt%s", distinctive_ring); 00914 if (mgcpdebug) { 00915 ast_verbose(VERBOSE_PREFIX_3 "MGCP distinctive callwait %s\n", tone); 00916 } 00917 } else { 00918 snprintf(tone, sizeof(tone), "L/wt"); 00919 if (mgcpdebug) { 00920 ast_verbose(VERBOSE_PREFIX_3 "MGCP normal callwait %s\n", tone); 00921 } 00922 } 00923 break; 00924 case MGCP_ONHOOK: 00925 default: 00926 if (!ast_strlen_zero(distinctive_ring)) { 00927 snprintf(tone, sizeof(tone), "L/r%s", distinctive_ring); 00928 if (mgcpdebug) { 00929 ast_verbose(VERBOSE_PREFIX_3 "MGCP distinctive ring %s\n", tone); 00930 } 00931 } else { 00932 snprintf(tone, sizeof(tone), "L/rg"); 00933 if (mgcpdebug) { 00934 ast_verbose(VERBOSE_PREFIX_3 "MGCP default ring\n"); 00935 } 00936 } 00937 break; 00938 } 00939 00940 if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { 00941 ast_log(LOG_WARNING, "mgcp_call called on %s, neither down nor reserved\n", ast->name); 00942 ast_mutex_unlock(&sub->lock); 00943 return -1; 00944 } 00945 00946 res = 0; 00947 sub->outgoing = 1; 00948 sub->cxmode = MGCP_CX_RECVONLY; 00949 if (p->type == TYPE_LINE) { 00950 if (!sub->rtp) { 00951 start_rtp(sub); 00952 } else { 00953 transmit_modify_request(sub); 00954 } 00955 00956 if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) { 00957 /* try to prevent a callwait from disturbing the other connection */ 00958 sub->next->cxmode = MGCP_CX_RECVONLY; 00959 transmit_modify_request(sub->next); 00960 } 00961 00962 transmit_notify_request_with_callerid(sub, tone, ast->cid.cid_num, ast->cid.cid_name); 00963 ast_setstate(ast, AST_STATE_RINGING); 00964 00965 if (sub->next->owner && !ast_strlen_zero(sub->next->cxident) && !ast_strlen_zero(sub->next->callid)) { 00966 /* Put the connection back in sendrecv */ 00967 sub->next->cxmode = MGCP_CX_SENDRECV; 00968 transmit_modify_request(sub->next); 00969 } 00970 } else { 00971 ast_log(LOG_NOTICE, "Don't know how to dial on trunks yet\n"); 00972 res = -1; 00973 } 00974 ast_mutex_unlock(&sub->lock); 00975 ast_queue_control(ast, AST_CONTROL_RINGING); 00976 return res; 00977 }
|
|
Definition at line 3941 of file chan_mgcp.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 03942 { 03943 if (argc != 2) 03944 return RESULT_SHOWUSAGE; 03945 mgcpdebug = 1; 03946 ast_cli(fd, "MGCP Debugging Enabled\n"); 03947 return RESULT_SUCCESS; 03948 }
|
|
Definition at line 4281 of file chan_mgcp.c. References reload_config(). Referenced by do_monitor(). 04282 { 04283 reload_config(); 04284 return 0; 04285 }
|
|
Definition at line 1284 of file chan_mgcp.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, ast_channel::name, mgcp_subchannel::owner, and ast_channel::tech_pvt. 01285 { 01286 struct mgcp_subchannel *sub = newchan->tech_pvt; 01287 01288 ast_mutex_lock(&sub->lock); 01289 ast_log(LOG_NOTICE, "mgcp_fixup(%s, %s)\n", oldchan->name, newchan->name); 01290 if (sub->owner != oldchan) { 01291 ast_mutex_unlock(&sub->lock); 01292 ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, sub->owner); 01293 return -1; 01294 } 01295 sub->owner = newchan; 01296 ast_mutex_unlock(&sub->lock); 01297 return 0; 01298 }
|
|
Definition at line 3914 of file chan_mgcp.c. References mgcp_endpoint::canreinvite, mgcp_subchannel::parent, mgcp_subchannel::rtp, and ast_channel::tech_pvt. 03915 { 03916 struct mgcp_subchannel *sub; 03917 sub = chan->tech_pvt; 03918 if (sub && sub->rtp && sub->parent->canreinvite) 03919 return sub->rtp; 03920 return NULL; 03921 }
|
|
|
Definition at line 1347 of file chan_mgcp.c. References AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), control2str(), mgcp_subchannel::lock, LOG_WARNING, mgcpdebug, ast_channel::name, ast_channel::tech_pvt, transmit_notify_request(), and VERBOSE_PREFIX_3. 01348 { 01349 struct mgcp_subchannel *sub = ast->tech_pvt; 01350 int res = 0; 01351 01352 if (mgcpdebug) { 01353 ast_verbose(VERBOSE_PREFIX_3 "MGCP asked to indicate %d '%s' condition on channel %s\n", 01354 ind, control2str(ind), ast->name); 01355 } 01356 ast_mutex_lock(&sub->lock); 01357 switch(ind) { 01358 case AST_CONTROL_RINGING: 01359 #ifdef DLINK_BUGGY_FIRMWARE 01360 transmit_notify_request(sub, "rt"); 01361 #else 01362 transmit_notify_request(sub, "G/rt"); 01363 #endif 01364 break; 01365 case AST_CONTROL_BUSY: 01366 transmit_notify_request(sub, "L/bz"); 01367 break; 01368 case AST_CONTROL_CONGESTION: 01369 transmit_notify_request(sub, "G/cg"); 01370 break; 01371 case -1: 01372 transmit_notify_request(sub, ""); 01373 break; 01374 default: 01375 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 01376 res = -1; 01377 } 01378 ast_mutex_unlock(&sub->lock); 01379 return res; 01380 }
|
|
|
Definition at line 3950 of file chan_mgcp.c. References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS. 03951 { 03952 if (argc != 3) 03953 return RESULT_SHOWUSAGE; 03954 mgcpdebug = 0; 03955 ast_cli(fd, "MGCP Debugging Disabled\n"); 03956 return RESULT_SUCCESS; 03957 }
|
|
Definition at line 734 of file chan_mgcp.c. References __mgcp_xmit(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), mgcp_message::buf, DEFAULT_RETRANS, mgcp_message::expire, mgcp_message::len, LOG_NOTICE, malloc, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_message::next, mgcp_message::owner_ep, mgcp_message::owner_sub, mgcp_endpoint::parent, mgcp_message::retrans, retrans_pkt(), mgcp_gateway::retransid, and mgcp_message::seqno. Referenced by send_request(). 00736 { 00737 struct mgcp_message *msg = malloc(sizeof(struct mgcp_message) + len); 00738 struct mgcp_message *cur; 00739 struct mgcp_gateway *gw = ((p && p->parent) ? p->parent : NULL); 00740 struct timeval tv; 00741 00742 if (!msg) { 00743 return -1; 00744 } 00745 if (!gw) { 00746 return -1; 00747 } 00748 /* SC 00749 time(&t); 00750 if (gw->messagepending && (gw->lastouttime + 20 < t)) { 00751 ast_log(LOG_NOTICE, "Timeout waiting for response to message:%d, lastouttime: %ld, now: %ld. Dumping pending queue\n", 00752 gw->msgs ? gw->msgs->seqno : -1, (long) gw->lastouttime, (long) t); 00753 dump_queue(sub->parent); 00754 } 00755 */ 00756 msg->owner_sub = sub; 00757 msg->owner_ep = p; 00758 msg->seqno = seqno; 00759 msg->next = NULL; 00760 msg->len = len; 00761 msg->retrans = 0; 00762 memcpy(msg->buf, data, msg->len); 00763 00764 ast_mutex_lock(&gw->msgs_lock); 00765 cur = gw->msgs; 00766 if (cur) { 00767 while(cur->next) 00768 cur = cur->next; 00769 cur->next = msg; 00770 } else { 00771 gw->msgs = msg; 00772 } 00773 00774 if (gettimeofday(&tv, NULL) < 0) { 00775 /* This shouldn't ever happen, but let's be sure */ 00776 ast_log(LOG_NOTICE, "gettimeofday() failed!\n"); 00777 } else { 00778 msg->expire = tv.tv_sec * 1000 + tv.tv_usec / 1000 + DEFAULT_RETRANS; 00779 00780 if (gw->retransid == -1) 00781 gw->retransid = ast_sched_add(sched, DEFAULT_RETRANS, retrans_pkt, (void *)gw); 00782 } 00783 ast_mutex_unlock(&gw->msgs_lock); 00784 /* SC 00785 if (!gw->messagepending) { 00786 gw->messagepending = 1; 00787 gw->lastout = seqno; 00788 gw->lastouttime = t; 00789 */ 00790 __mgcp_xmit(gw, msg->buf, msg->len); 00791 /* XXX Should schedule retransmission XXX */ 00792 /* SC 00793 } else 00794 ast_log(LOG_DEBUG, "Deferring transmission of transaction %d\n", seqno); 00795 */ 00796 return 0; 00797 }
|
|
Definition at line 665 of file chan_mgcp.c. References AST_FRAME_CONTROL, mgcp_queue_frame(), and ast_frame::subclass. Referenced by handle_hd_hf(). 00666 { 00667 struct ast_frame f = { AST_FRAME_CONTROL, }; 00668 f.subclass = control; 00669 return mgcp_queue_frame(sub, &f); 00670 }
|
|
Definition at line 629 of file chan_mgcp.c. References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), ast_channel::lock, and mgcp_subchannel::owner. Referenced by handle_request(), and mgcp_queue_control(). 00630 { 00631 for(;;) { 00632 if (sub->owner) { 00633 if (!ast_mutex_trylock(&sub->owner->lock)) { 00634 ast_queue_frame(sub->owner, f); 00635 ast_mutex_unlock(&sub->owner->lock); 00636 break; 00637 } else { 00638 ast_mutex_unlock(&sub->lock); 00639 usleep(1); 00640 ast_mutex_lock(&sub->lock); 00641 } 00642 } else 00643 break; 00644 } 00645 }
|
|
Definition at line 647 of file chan_mgcp.c. References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_channel::lock, and mgcp_subchannel::owner. Referenced by attempt_transfer(), handle_request(), and handle_response(). 00648 { 00649 for(;;) { 00650 if (sub->owner) { 00651 if (!ast_mutex_trylock(&sub->owner->lock)) { 00652 ast_queue_hangup(sub->owner); 00653 ast_mutex_unlock(&sub->owner->lock); 00654 break; 00655 } else { 00656 ast_mutex_unlock(&sub->lock); 00657 usleep(1); 00658 ast_mutex_lock(&sub->lock); 00659 } 00660 } else 00661 break; 00662 } 00663 }
|
|
Definition at line 1244 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), mgcp_subchannel::lock, mgcp_rtp_read(), and ast_channel::tech_pvt. 01245 { 01246 struct ast_frame *f; 01247 struct mgcp_subchannel *sub = ast->tech_pvt; 01248 ast_mutex_lock(&sub->lock); 01249 f = mgcp_rtp_read(sub); 01250 ast_mutex_unlock(&sub->lock); 01251 return f; 01252 }
|
|
Definition at line 4287 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), mgcp_reloading, and restart_monitor(). Referenced by reload(), and unload_module(). 04288 { 04289 ast_mutex_lock(&mgcp_reload_lock); 04290 if (mgcp_reloading) { 04291 ast_verbose("Previous mgcp reload not yet done\n"); 04292 } else 04293 mgcp_reloading = 1; 04294 ast_mutex_unlock(&mgcp_reload_lock); 04295 restart_monitor(); 04296 return 0; 04297 }
|
|
Definition at line 3480 of file chan_mgcp.c. References AST_CAUSE_BUSY, AST_CAUSE_UNREGISTERED, ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strlen_zero(), ast_verbose(), mgcp_endpoint::call_forward, mgcp_endpoint::callwaiting, capability, mgcp_endpoint::dnd, find_subchannel_and_lock(), has_voicemail(), mgcp_endpoint::hookstate, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, mgcp_new(), MGCP_ONHOOK, mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_subchannel::parent, restart_monitor(), transmit_notify_request(), and VERBOSE_PREFIX_3. 03481 { 03482 int oldformat; 03483 struct mgcp_subchannel *sub; 03484 struct ast_channel *tmpc = NULL; 03485 char tmp[256]; 03486 char *dest = data; 03487 03488 oldformat = format; 03489 format &= capability; 03490 if (!format) { 03491 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 03492 return NULL; 03493 } 03494 strncpy(tmp, dest, sizeof(tmp) - 1); 03495 if (ast_strlen_zero(tmp)) { 03496 ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n"); 03497 return NULL; 03498 } 03499 sub = find_subchannel_and_lock(tmp, 0, NULL); 03500 if (!sub) { 03501 ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp); 03502 *cause = AST_CAUSE_UNREGISTERED; 03503 return NULL; 03504 } 03505 03506 if (option_verbose > 2) { 03507 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp); 03508 ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n", 03509 sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); 03510 } 03511 /* Must be busy */ 03512 if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) || 03513 ((!sub->parent->callwaiting) && (sub->owner)) || 03514 (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) { 03515 if (sub->parent->hookstate == MGCP_ONHOOK) { 03516 if (has_voicemail(sub->parent)) { 03517 transmit_notify_request(sub,"L/vmwi(+)"); 03518 } else { 03519 transmit_notify_request(sub,"L/vmwi(-)"); 03520 } 03521 } 03522 *cause = AST_CAUSE_BUSY; 03523 ast_mutex_unlock(&sub->lock); 03524 return NULL; 03525 } 03526 tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); 03527 ast_mutex_unlock(&sub->lock); 03528 if (!tmpc) 03529 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 03530 restart_monitor(); 03531 return tmpc; 03532 }
|
|
Definition at line 1212 of file chan_mgcp.c. References ast_dsp_process(), AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), mgcp_endpoint::dsp, mgcp_endpoint::dtmfmode, ast_frame::frametype, LOG_DEBUG, LOG_NOTICE, MGCP_DTMF_INBAND, MGCP_DTMF_RFC2833, ast_channel::nativeformats, mgcp_subchannel::owner, mgcp_subchannel::parent, ast_channel::readformat, mgcp_subchannel::rtp, ast_frame::subclass, and ast_channel::writeformat. Referenced by mgcp_read(). 01213 { 01214 /* Retrieve audio/etc from channel. Assumes sub->lock is already held. */ 01215 struct ast_frame *f; 01216 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 01217 01218 f = ast_rtp_read(sub->rtp); 01219 /* Don't send RFC2833 if we're not supposed to */ 01220 if (f && (f->frametype == AST_FRAME_DTMF) && !(sub->parent->dtmfmode & MGCP_DTMF_RFC2833)) 01221 return &null_frame; 01222 if (sub->owner) { 01223 /* We already hold the channel lock */ 01224 if (f->frametype == AST_FRAME_VOICE) { 01225 if (f->subclass != sub->owner->nativeformats) { 01226 ast_log(LOG_DEBUG, "Oooh, format changed to %d\n", f->subclass); 01227 sub->owner->nativeformats = f->subclass; 01228 ast_set_read_format(sub->owner, sub->owner->readformat); 01229 ast_set_write_format(sub->owner, sub->owner->writeformat); 01230 } 01231 /* Courtesy fearnor aka alex@pilosoft.com */ 01232 if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) { 01233 #if 0 01234 ast_log(LOG_NOTICE, "MGCP ast_dsp_process\n"); 01235 #endif 01236 f = ast_dsp_process(sub->owner, sub->parent->dsp, f); 01237 } 01238 } 01239 } 01240 return f; 01241 }
|
|
Definition at line 1300 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), mgcp_subchannel::lock, ast_channel::tech_pvt, and transmit_notify_request(). 01301 { 01302 struct mgcp_subchannel *sub = ast->tech_pvt; 01303 char tmp[4]; 01304 01305 tmp[0] = 'D'; 01306 tmp[1] = '/'; 01307 tmp[2] = digit; 01308 tmp[3] = '\0'; 01309 ast_mutex_lock(&sub->lock); 01310 transmit_notify_request(sub, tmp); 01311 ast_mutex_unlock(&sub->lock); 01312 return -1; 01313 }
|
|
Definition at line 3923 of file chan_mgcp.c. References mgcp_subchannel::rtp, ast_channel::tech_pvt, and transmit_modify_with_sdp(). 03924 { 03925 /* XXX Is there such thing as video support with MGCP? XXX */ 03926 struct mgcp_subchannel *sub; 03927 sub = chan->tech_pvt; 03928 if (sub) { 03929 transmit_modify_with_sdp(sub, rtp, codecs); 03930 return 0; 03931 } 03932 return -1; 03933 }
|
|
Definition at line 1085 of file chan_mgcp.c. References mgcp_gateway::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), mgcp_endpoint::context, mgcp_gateway::defaddr, mgcp_gateway::dynamic, mgcp_gateway::endpoints, gateways, mgcp_endpoint::name, mgcp_gateway::name, mgcp_gateway::next, mgcp_endpoint::next, mgcp_subchannel::owner, RESULT_SHOWUSAGE, RESULT_SUCCESS, mgcp_endpoint::sub, and mgcp_gateway::wcardep. 01086 { 01087 struct mgcp_gateway *g; 01088 struct mgcp_endpoint *e; 01089 int hasendpoints = 0; 01090 char iabuf[INET_ADDRSTRLEN]; 01091 01092 if (argc != 3) 01093 return RESULT_SHOWUSAGE; 01094 ast_mutex_lock(&gatelock); 01095 g = gateways; 01096 while(g) { 01097 e = g->endpoints; 01098 ast_cli(fd, "Gateway '%s' at %s (%s)\n", g->name, g->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr) : ast_inet_ntoa(iabuf, sizeof(iabuf), g->defaddr.sin_addr), g->dynamic ? "Dynamic" : "Static"); 01099 while(e) { 01100 /* JS: Don't show wilcard endpoint */ 01101 if (strcmp(e->name, g->wcardep) !=0) 01102 ast_cli(fd, " -- '%s@%s in '%s' is %s\n", e->name, g->name, e->context, e->sub->owner ? "active" : "idle"); 01103 hasendpoints = 1; 01104 e = e->next; 01105 } 01106 if (!hasendpoints) { 01107 ast_cli(fd, " << No Endpoints Defined >> "); 01108 } 01109 g = g->next; 01110 } 01111 ast_mutex_unlock(&gatelock); 01112 return RESULT_SUCCESS; 01113 }
|
|
Definition at line 2570 of file chan_mgcp.c. References ast_bridged_channel(), ast_canmatch_extension(), ast_db_put(), ast_exists_extension(), ast_hangup(), ast_ignore_pattern(), ast_indicate(), ast_log(), ast_masq_park_call(), ast_matchmore_extension(), AST_MAX_EXTENSION, ast_parking_ext(), ast_pbx_run(), ast_pickup_call(), ast_pickup_ext(), ast_say_digit_str(), ast_set_callerid(), ast_setstate(), AST_STATE_RING, ast_strlen_zero(), ast_verbose(), ast_waitfordigit(), mgcp_endpoint::call_forward, mgcp_endpoint::callreturn, mgcp_endpoint::callwaiting, mgcp_endpoint::cancallforward, ast_channel::cid, mgcp_endpoint::cid_name, ast_callerid::cid_num, mgcp_endpoint::cid_num, ast_channel::context, mgcp_endpoint::dnd, mgcp_endpoint::dtmfmode, ast_channel::exten, exten, firstdigittimeout, gendigittimeout, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, ast_channel::language, mgcp_endpoint::lastcallerid, LOG_DEBUG, LOG_WARNING, matchdigittimeout, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, ast_channel::name, mgcp_subchannel::next, option_debug, option_verbose, mgcp_subchannel::owner, mgcp_subchannel::parent, mgcp_endpoint::sub, ast_channel::tech_pvt, transmit_notify_request(), and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(). 02571 { 02572 struct ast_channel *chan = data; 02573 struct mgcp_subchannel *sub = chan->tech_pvt; 02574 struct mgcp_endpoint *p = sub->parent; 02575 char exten[AST_MAX_EXTENSION] = ""; 02576 int len = 0; 02577 int timeout = firstdigittimeout; 02578 int res; 02579 int getforward = 0; 02580 02581 while(len < AST_MAX_EXTENSION-1) { 02582 res = ast_waitfordigit(chan, timeout); 02583 timeout = 0; 02584 if (res < 0) { 02585 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 02586 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02587 ast_indicate(chan, -1); 02588 ast_hangup(chan); 02589 return NULL; 02590 } else if (res) { 02591 exten[len++]=res; 02592 exten[len] = '\0'; 02593 } 02594 if (!ast_ignore_pattern(chan->context, exten)) { 02595 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02596 ast_indicate(chan, -1); 02597 } else { 02598 /* XXX Redundant? We should already be playing dialtone */ 02599 /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02600 transmit_notify_request(sub, "L/dl"); 02601 } 02602 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 02603 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 02604 if (getforward) { 02605 /* Record this as the forwarding extension */ 02606 strncpy(p->call_forward, exten, sizeof(p->call_forward) - 1); 02607 if (option_verbose > 2) { 02608 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n", 02609 p->call_forward, chan->name); 02610 } 02611 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02612 transmit_notify_request(sub, "L/sl"); 02613 if (res) 02614 break; 02615 usleep(500000); 02616 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02617 ast_indicate(chan, -1); 02618 sleep(1); 02619 memset(exten, 0, sizeof(exten)); 02620 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02621 transmit_notify_request(sub, "L/dl"); 02622 len = 0; 02623 getforward = 0; 02624 } else { 02625 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02626 ast_indicate(chan, -1); 02627 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 02628 ast_set_callerid(chan, 02629 p->hidecallerid ? "" : p->cid_num, 02630 p->hidecallerid ? "" : p->cid_name, 02631 p->cid_num); 02632 ast_setstate(chan, AST_STATE_RING); 02633 /*zt_enable_ec(p);*/ 02634 if (p->dtmfmode & MGCP_DTMF_HYBRID) { 02635 p->dtmfmode |= MGCP_DTMF_INBAND; 02636 ast_indicate(chan, -1); 02637 } 02638 res = ast_pbx_run(chan); 02639 if (res) { 02640 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 02641 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02642 /*transmit_notify_request(p, "nbz", 1);*/ 02643 transmit_notify_request(sub, "G/cg"); 02644 } 02645 return NULL; 02646 } 02647 } else { 02648 /* It's a match, but they just typed a digit, and there is an ambiguous match, 02649 so just set the timeout to matchdigittimeout and wait some more */ 02650 timeout = matchdigittimeout; 02651 } 02652 } else if (res == 0) { 02653 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 02654 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02655 transmit_notify_request(sub, "G/cg"); 02656 /*zt_wait_event(p->subs[index].zfd);*/ 02657 ast_hangup(chan); 02658 return NULL; 02659 } else if (p->hascallwaiting && p->callwaiting && !strcmp(exten, "*70")) { 02660 if (option_verbose > 2) { 02661 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 02662 } 02663 /* Disable call waiting if enabled */ 02664 p->callwaiting = 0; 02665 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02666 transmit_notify_request(sub, "L/sl"); 02667 len = 0; 02668 memset(exten, 0, sizeof(exten)); 02669 timeout = firstdigittimeout; 02670 } else if (!strcmp(exten,ast_pickup_ext())) { 02671 /* Scan all channels and see if any there 02672 * ringing channqels with that have call groups 02673 * that equal this channels pickup group 02674 */ 02675 if (ast_pickup_call(chan)) { 02676 ast_log(LOG_WARNING, "No call pickup possible...\n"); 02677 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02678 transmit_notify_request(sub, "G/cg"); 02679 } 02680 ast_hangup(chan); 02681 return NULL; 02682 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 02683 if (option_verbose > 2) { 02684 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 02685 } 02686 /* Disable Caller*ID if enabled */ 02687 p->hidecallerid = 1; 02688 ast_set_callerid(chan, "", "", NULL); 02689 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02690 transmit_notify_request(sub, "L/sl"); 02691 len = 0; 02692 memset(exten, 0, sizeof(exten)); 02693 timeout = firstdigittimeout; 02694 } else if (p->callreturn && !strcmp(exten, "*69")) { 02695 res = 0; 02696 if (!ast_strlen_zero(p->lastcallerid)) { 02697 res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language); 02698 } 02699 if (!res) 02700 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02701 transmit_notify_request(sub, "L/sl"); 02702 break; 02703 } else if (!strcmp(exten, "*78")) { 02704 /* Do not disturb */ 02705 if (option_verbose > 2) { 02706 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name); 02707 } 02708 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02709 transmit_notify_request(sub, "L/sl"); 02710 p->dnd = 1; 02711 getforward = 0; 02712 memset(exten, 0, sizeof(exten)); 02713 len = 0; 02714 } else if (!strcmp(exten, "*79")) { 02715 /* Do not disturb */ 02716 if (option_verbose > 2) { 02717 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name); 02718 } 02719 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02720 transmit_notify_request(sub, "L/sl"); 02721 p->dnd = 0; 02722 getforward = 0; 02723 memset(exten, 0, sizeof(exten)); 02724 len = 0; 02725 } else if (p->cancallforward && !strcmp(exten, "*72")) { 02726 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02727 transmit_notify_request(sub, "L/sl"); 02728 getforward = 1; 02729 memset(exten, 0, sizeof(exten)); 02730 len = 0; 02731 } else if (p->cancallforward && !strcmp(exten, "*73")) { 02732 if (option_verbose > 2) { 02733 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name); 02734 } 02735 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02736 transmit_notify_request(sub, "L/sl"); 02737 memset(p->call_forward, 0, sizeof(p->call_forward)); 02738 getforward = 0; 02739 memset(exten, 0, sizeof(exten)); 02740 len = 0; 02741 } else if (!strcmp(exten, ast_parking_ext()) && 02742 sub->next->owner && ast_bridged_channel(sub->next->owner)) { 02743 /* This is a three way call, the main call being a real channel, 02744 and we're parking the first call. */ 02745 ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); 02746 if (option_verbose > 2) { 02747 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 02748 } 02749 break; 02750 } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(exten, "*60")) { 02751 if (option_verbose > 2) { 02752 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcallerid); 02753 } 02754 res = ast_db_put("blacklist", p->lastcallerid, "1"); 02755 if (!res) { 02756 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02757 transmit_notify_request(sub, "L/sl"); 02758 memset(exten, 0, sizeof(exten)); 02759 len = 0; 02760 } 02761 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 02762 if (option_verbose > 2) { 02763 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 02764 } 02765 /* Enable Caller*ID if enabled */ 02766 p->hidecallerid = 0; 02767 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 02768 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02769 transmit_notify_request(sub, "L/sl"); 02770 len = 0; 02771 memset(exten, 0, sizeof(exten)); 02772 timeout = firstdigittimeout; 02773 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 02774 ((exten[0] != '*') || (strlen(exten) > 2))) { 02775 if (option_debug) 02776 ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->cid.cid_num ? chan->cid.cid_num : "<Unknown Caller>", chan->context); 02777 break; 02778 } 02779 if (!timeout) 02780 timeout = gendigittimeout; 02781 if (len && !ast_ignore_pattern(chan->context, exten)) 02782 /*tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02783 ast_indicate(chan, -1); 02784 } 02785 #if 0 02786 for (;;) { 02787 res = ast_waitfordigit(chan, to); 02788 if (!res) { 02789 ast_log(LOG_DEBUG, "Timeout...\n"); 02790 break; 02791 } 02792 if (res < 0) { 02793 ast_log(LOG_DEBUG, "Got hangup...\n"); 02794 ast_hangup(chan); 02795 break; 02796 } 02797 exten[pos++] = res; 02798 if (!ast_ignore_pattern(chan->context, exten)) 02799 ast_indicate(chan, -1); 02800 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) { 02801 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 02802 to = 3000; 02803 else 02804 to = 8000; 02805 } else 02806 break; 02807 } 02808 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) { 02809 strncpy(chan->exten, exten, sizeof(chan->exten) - 1); 02810 if (!p->rtp) { 02811 start_rtp(p); 02812 } 02813 ast_setstate(chan, AST_STATE_RING); 02814 chan->rings = 1; 02815 if (ast_pbx_run(chan)) { 02816 ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name); 02817 } else 02818 return NULL; 02819 } 02820 #endif 02821 ast_hangup(chan); 02822 return NULL; 02823 }
|
|
Definition at line 1254 of file chan_mgcp.c. References AST_FRAME_IMAGE, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_write(), ast_frame::frametype, mgcp_subchannel::lock, LOG_WARNING, ast_channel::nativeformats, mgcp_subchannel::parent, ast_channel::readformat, mgcp_subchannel::rtp, mgcp_endpoint::singlepath, mgcp_endpoint::sub, ast_frame::subclass, ast_channel::tech_pvt, and ast_channel::writeformat. 01255 { 01256 struct mgcp_subchannel *sub = ast->tech_pvt; 01257 int res = 0; 01258 if (frame->frametype != AST_FRAME_VOICE) { 01259 if (frame->frametype == AST_FRAME_IMAGE) 01260 return 0; 01261 else { 01262 ast_log(LOG_WARNING, "Can't send %d type frames with MGCP write\n", frame->frametype); 01263 return 0; 01264 } 01265 } else { 01266 if (!(frame->subclass & ast->nativeformats)) { 01267 ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %d (read/write = %d/%d)\n", 01268 frame->subclass, ast->nativeformats, ast->readformat, ast->writeformat); 01269 return -1; 01270 } 01271 } 01272 if (sub) { 01273 ast_mutex_lock(&sub->lock); 01274 if ((sub->parent->sub == sub) || !sub->parent->singlepath) { 01275 if (sub->rtp) { 01276 res = ast_rtp_write(sub->rtp, frame); 01277 } 01278 } 01279 ast_mutex_unlock(&sub->lock); 01280 } 01281 return res; 01282 }
|
|
Definition at line 3274 of file chan_mgcp.c. References ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strlen_zero(), ast_verbose(), find_and_retrans(), find_subchannel_and_lock(), free, handle_request(), handle_response(), mgcp_subchannel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, mgcpsock, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::owner_ep, mgcp_message::owner_sub, mgcp_endpoint::parent, mgcp_subchannel::parent, parse(), result, mgcp_gateway::retransid, and mgcp_message::seqno. Referenced by do_monitor(). 03275 { 03276 struct mgcp_request req; 03277 struct sockaddr_in sin; 03278 struct mgcp_subchannel *sub; 03279 int res; 03280 socklen_t len; 03281 int result; 03282 int ident; 03283 char iabuf[INET_ADDRSTRLEN]; 03284 len = sizeof(sin); 03285 memset(&req, 0, sizeof(req)); 03286 res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 03287 if (res < 0) { 03288 if (errno != ECONNREFUSED) 03289 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 03290 return 1; 03291 } 03292 req.data[res] = '\0'; 03293 req.len = res; 03294 if (mgcpdebug) { 03295 ast_verbose("MGCP read: \n%s\nfrom %s:%d\n", req.data, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 03296 } 03297 parse(&req); 03298 if (req.headers < 1) { 03299 /* Must have at least one header */ 03300 return 1; 03301 } 03302 if (ast_strlen_zero(req.identifier)) { 03303 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 03304 return 1; 03305 } 03306 03307 if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) { 03308 /* Try to find who this message is for, if it's important */ 03309 sub = find_subchannel_and_lock(NULL, ident, &sin); 03310 if (sub) { 03311 struct mgcp_gateway *gw = sub->parent->parent; 03312 struct mgcp_message *cur, *prev; 03313 03314 ast_mutex_unlock(&sub->lock); 03315 ast_mutex_lock(&gw->msgs_lock); 03316 for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) { 03317 if (cur->seqno == ident) { 03318 ast_log(LOG_DEBUG, "Got response back on transaction %d\n", ident); 03319 if (prev) 03320 prev->next = cur->next; 03321 else 03322 gw->msgs = cur->next; 03323 break; 03324 } 03325 } 03326 03327 /* stop retrans timer if the queue is empty */ 03328 if (!gw->msgs && (gw->retransid != -1)) { 03329 ast_sched_del(sched, gw->retransid); 03330 gw->retransid = -1; 03331 } 03332 03333 ast_mutex_unlock(&gw->msgs_lock); 03334 if (cur) { 03335 handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req); 03336 free(cur); 03337 return 1; 03338 } 03339 03340 ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n", 03341 gw->name, ident); 03342 } 03343 } else { 03344 if (ast_strlen_zero(req.endpoint) || 03345 ast_strlen_zero(req.version) || 03346 ast_strlen_zero(req.verb)) { 03347 ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n"); 03348 return 1; 03349 } 03350 /* Process request, with iflock held */ 03351 sub = find_subchannel_and_lock(req.endpoint, 0, &sin); 03352 if (sub) { 03353 /* look first to find a matching response in the queue */ 03354 if (!find_and_retrans(sub, &req)) 03355 /* pass the request off to the currently mastering subchannel */ 03356 handle_request(sub, &req, &sin); 03357 ast_mutex_unlock(&sub->lock); 03358 } 03359 } 03360 return 1; 03361 }
|
|
Definition at line 1662 of file chan_mgcp.c. References ast_log(), ast_strlen_zero(), ast_verbose(), mgcp_request::data, mgcp_request::endpoint, mgcp_request::header, mgcp_request::headers, mgcp_request::identifier, mgcp_request::line, mgcp_request::lines, LOG_WARNING, MGCP_MAX_HEADERS, MGCP_MAX_LINES, mgcpdebug, mgcp_request::verb, and mgcp_request::version. Referenced by __login_exec(), aqm_exec(), ast_hint_state_changed(), ast_parse_allow_disallow(), dial_exec_full(), enumlookup_exec(), get_in_brackets(), group_check_exec(), mgcpsock_read(), mixmonitor_exec(), pbx_builtin_background(), pqm_exec(), privacy_exec(), reload_agents(), rqm_exec(), sendimage_exec(), sendtext_exec(), transfer_exec(), txtcidname_exec(), and upqm_exec(). 01663 { 01664 /* Divide fields by NULL's */ 01665 char *c; 01666 int f = 0; 01667 c = req->data; 01668 01669 /* First header starts immediately */ 01670 req->header[f] = c; 01671 while(*c) { 01672 if (*c == '\n') { 01673 /* We've got a new header */ 01674 *c = 0; 01675 #if 0 01676 printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f])); 01677 #endif 01678 if (ast_strlen_zero(req->header[f])) { 01679 /* Line by itself means we're now in content */ 01680 c++; 01681 break; 01682 } 01683 if (f >= MGCP_MAX_HEADERS - 1) { 01684 ast_log(LOG_WARNING, "Too many MGCP headers...\n"); 01685 } else 01686 f++; 01687 req->header[f] = c + 1; 01688 } else if (*c == '\r') { 01689 /* Ignore but eliminate \r's */ 01690 *c = 0; 01691 } 01692 c++; 01693 } 01694 /* Check for last header */ 01695 if (!ast_strlen_zero(req->header[f])) 01696 f++; 01697 req->headers = f; 01698 /* Now we process any mime content */ 01699 f = 0; 01700 req->line[f] = c; 01701 while(*c) { 01702 if (*c == '\n') { 01703 /* We've got a new line */ 01704 *c = 0; 01705 #if 0 01706 printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f])); 01707 #endif 01708 if (f >= MGCP_MAX_LINES - 1) { 01709 ast_log(LOG_WARNING, "Too many SDP lines...\n"); 01710 } else 01711 f++; 01712 req->line[f] = c + 1; 01713 } else if (*c == '\r') { 01714 /* Ignore and eliminate \r's */ 01715 *c = 0; 01716 } 01717 c++; 01718 } 01719 /* Check for last line */ 01720 if (!ast_strlen_zero(req->line[f])) 01721 f++; 01722 req->lines = f; 01723 /* Parse up the initial header */ 01724 c = req->header[0]; 01725 while(*c && *c < 33) c++; 01726 /* First the verb */ 01727 req->verb = c; 01728 while(*c && (*c > 32)) c++; 01729 if (*c) { 01730 *c = '\0'; 01731 c++; 01732 while(*c && (*c < 33)) c++; 01733 req->identifier = c; 01734 while(*c && (*c > 32)) c++; 01735 if (*c) { 01736 *c = '\0'; 01737 c++; 01738 while(*c && (*c < 33)) c++; 01739 req->endpoint = c; 01740 while(*c && (*c > 32)) c++; 01741 if (*c) { 01742 *c = '\0'; 01743 c++; 01744 while(*c && (*c < 33)) c++; 01745 req->version = c; 01746 while(*c && (*c > 32)) c++; 01747 while(*c && (*c < 33)) c++; 01748 while(*c && (*c > 32)) c++; 01749 *c = '\0'; 01750 } 01751 } 01752 } 01753 01754 if (mgcpdebug) { 01755 ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n", 01756 req->verb, req->identifier, req->endpoint, req->version); 01757 ast_verbose("%d headers, %d lines\n", req->headers, req->lines); 01758 } 01759 if (*c) 01760 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 01761 }
|
|
Definition at line 1763 of file chan_mgcp.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_rtp_get_current_formats(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_strdupa, ast_strlen_zero(), ast_verbose(), capability, mgcp_endpoint::capability, get_sdp(), get_sdp_iterate(), host, hp, LOG_WARNING, mgcpdebug, mgcp_endpoint::nonCodecCapability, nonCodecCapability, mgcp_subchannel::parent, portno, mgcp_subchannel::rtp, sdpLineNum_iterator_init(), and mgcp_endpoint::sub. Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite(). 01764 { 01765 char *m; 01766 char *c; 01767 char *a; 01768 char host[258]; 01769 int len; 01770 int portno; 01771 int peercapability, peerNonCodecCapability; 01772 struct sockaddr_in sin; 01773 char *codecs; 01774 struct ast_hostent ahp; struct hostent *hp; 01775 int codec, codec_count=0; 01776 int iterator; 01777 struct mgcp_endpoint *p = sub->parent; 01778 01779 /* Get codec and RTP info from SDP */ 01780 m = get_sdp(req, "m"); 01781 c = get_sdp(req, "c"); 01782 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 01783 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 01784 return -1; 01785 } 01786 if (sscanf(c, "IN IP4 %256s", host) != 1) { 01787 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 01788 return -1; 01789 } 01790 /* XXX This could block for a long time, and block the main thread! XXX */ 01791 hp = ast_gethostbyname(host, &ahp); 01792 if (!hp) { 01793 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 01794 return -1; 01795 } 01796 if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) { 01797 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 01798 return -1; 01799 } 01800 sin.sin_family = AF_INET; 01801 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 01802 sin.sin_port = htons(portno); 01803 ast_rtp_set_peer(sub->rtp, &sin); 01804 #if 0 01805 printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 01806 #endif 01807 /* Scan through the RTP payload types specified in a "m=" line: */ 01808 ast_rtp_pt_clear(sub->rtp); 01809 codecs = ast_strdupa(m + len); 01810 while (!ast_strlen_zero(codecs)) { 01811 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 01812 if (codec_count) 01813 break; 01814 ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs); 01815 return -1; 01816 } 01817 ast_rtp_set_m_type(sub->rtp, codec); 01818 codec_count++; 01819 codecs += len; 01820 } 01821 01822 /* Next, scan through each "a=rtpmap:" line, noting each */ 01823 /* specified RTP payload type (with corresponding MIME subtype): */ 01824 sdpLineNum_iterator_init(&iterator); 01825 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 01826 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 01827 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) 01828 continue; 01829 /* Note: should really look at the 'freq' and '#chans' params too */ 01830 ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype); 01831 } 01832 01833 /* Now gather all of the codecs that were asked for: */ 01834 ast_rtp_get_current_formats(sub->rtp, &peercapability, &peerNonCodecCapability); 01835 p->capability = capability & peercapability; 01836 if (mgcpdebug) { 01837 ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n", 01838 capability, peercapability, p->capability); 01839 ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n", 01840 nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability); 01841 } 01842 if (!p->capability) { 01843 ast_log(LOG_WARNING, "No compatible codecs!\n"); 01844 return -1; 01845 } 01846 return 0; 01847 }
|
|
Definition at line 4031 of file chan_mgcp.c. References ast_mutex_lock(), mgcp_gateway::delme, mgcp_endpoint::delme, destroy_endpoint(), mgcp_gateway::endpoints, gateways, mgcp_endpoint::next, and t. Referenced by reload_config(), and unload_module(). 04032 { 04033 struct mgcp_gateway *g, *z, *r; 04034 struct mgcp_endpoint *e, *p, *t; 04035 04036 ast_mutex_lock(&gatelock); 04037 04038 /* prune gateways */ 04039 for (z = NULL, g = gateways; g;) { 04040 /* prune endpoints */ 04041 for (p = NULL, e = g->endpoints; e; ) { 04042 if (e->delme || g->delme) { 04043 t = e; 04044 e = e->next; 04045 if (!p) 04046 g->endpoints = e; 04047 else 04048 p->next = e; 04049 destroy_endpoint(t); 04050 } else { 04051 p = e; 04052 e = e->next; 04053 } 04054 } 04055 04056 if (g->delme) { 04057 r = g; 04058 g = g->next; 04059 if (!z) 04060 gateways = g; 04061 else 04062 z->next = g; 04063 04064 destroy_gateway(r); 04065 } else { 04066 z = g; 04067 g = g->next; 04068 } 04069 } 04070 04071 ast_mutex_unlock(&gatelock); 04072 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 4299 of file chan_mgcp.c. References mgcp_reload(). 04300 { 04301 mgcp_reload(0, 0, NULL); 04302 return 0; 04303 }
|
|
Definition at line 4074 of file chan_mgcp.c. References __ourip, ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_getformatbyname(), ast_gethostbyname(), ast_inet_ntoa(), ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_variable_browse(), ast_verbose(), bindaddr, build_gateway(), capability, cfg, config, DEFAULT_MGCP_CA_PORT, mgcp_endpoint::delme, mgcp_gateway::delme, dtmfmode, mgcp_gateway::endpoints, format, gateways, hp, io, IPTOS_MINCOST, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mgcpsock, mgcpsock_read_id, monitor_thread, mgcp_endpoint::name, mgcp_gateway::name, ast_variable::name, mgcp_endpoint::needaudit, mgcp_gateway::next, mgcp_endpoint::next, ast_variable::next, option_verbose, ourhost, ourport, prune_gateways(), tos, transmit_audit_endpoint(), ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3. 04075 { 04076 struct ast_config *cfg; 04077 struct ast_variable *v; 04078 struct mgcp_gateway *g; 04079 struct mgcp_endpoint *e; 04080 char iabuf[INET_ADDRSTRLEN]; 04081 char *cat; 04082 struct ast_hostent ahp; 04083 struct hostent *hp; 04084 int format; 04085 04086 if (gethostname(ourhost, sizeof(ourhost)-1)) { 04087 ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n"); 04088 return 0; 04089 } 04090 cfg = ast_config_load(config); 04091 04092 /* We *must* have a config file otherwise stop immediately */ 04093 if (!cfg) { 04094 ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config); 04095 return 0; 04096 } 04097 memset(&bindaddr, 0, sizeof(bindaddr)); 04098 dtmfmode = 0; 04099 v = ast_variable_browse(cfg, "general"); 04100 while(v) { 04101 /* Create the interface list */ 04102 if (!strcasecmp(v->name, "bindaddr")) { 04103 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 04104 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 04105 } else { 04106 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 04107 } 04108 } else if (!strcasecmp(v->name, "allow")) { 04109 format = ast_getformatbyname(v->value); 04110 if (format < 1) 04111 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 04112 else 04113 capability |= format; 04114 } else if (!strcasecmp(v->name, "disallow")) { 04115 format = ast_getformatbyname(v->value); 04116 if (format < 1) 04117 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 04118 else 04119 capability &= ~format; 04120 } else if (!strcasecmp(v->name, "tos")) { 04121 if (sscanf(v->value, "%d", &format) == 1) 04122 tos = format & 0xff; 04123 else if (!strcasecmp(v->value, "lowdelay")) 04124 tos = IPTOS_LOWDELAY; 04125 else if (!strcasecmp(v->value, "throughput")) 04126 tos = IPTOS_THROUGHPUT; 04127 else if (!strcasecmp(v->value, "reliability")) 04128 tos = IPTOS_RELIABILITY; 04129 else if (!strcasecmp(v->value, "mincost")) 04130 tos = IPTOS_MINCOST; 04131 else if (!strcasecmp(v->value, "none")) 04132 tos = 0; 04133 else 04134 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 04135 } else if (!strcasecmp(v->name, "port")) { 04136 if (sscanf(v->value, "%d", &ourport) == 1) { 04137 bindaddr.sin_port = htons(ourport); 04138 } else { 04139 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 04140 } 04141 } 04142 v = v->next; 04143 } 04144 04145 /* SC: mark existing entries for deletion */ 04146 ast_mutex_lock(&gatelock); 04147 g = gateways; 04148 while (g) { 04149 g->delme = 1; 04150 e = g->endpoints; 04151 while (e) { 04152 e->delme = 1; 04153 e = e->next; 04154 } 04155 g = g->next; 04156 } 04157 ast_mutex_unlock(&gatelock); 04158 04159 cat = ast_category_browse(cfg, NULL); 04160 while(cat) { 04161 if (strcasecmp(cat, "general")) { 04162 ast_mutex_lock(&gatelock); 04163 g = build_gateway(cat, ast_variable_browse(cfg, cat)); 04164 if (g) { 04165 if (option_verbose > 2) { 04166 ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name); 04167 } 04168 g->next = gateways; 04169 gateways = g; 04170 } 04171 ast_mutex_unlock(&gatelock); 04172 04173 /* FS: process queue and IO */ 04174 if (monitor_thread == pthread_self()) { 04175 if (sched) ast_sched_runq(sched); 04176 if (io) ast_io_wait(io, 10); 04177 } 04178 } 04179 cat = ast_category_browse(cfg, cat); 04180 } 04181 04182 /* SC: prune deleted entries etc. */ 04183 prune_gateways(); 04184 04185 if (ntohl(bindaddr.sin_addr.s_addr)) { 04186 memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip)); 04187 } else { 04188 hp = ast_gethostbyname(ourhost, &ahp); 04189 if (!hp) { 04190 ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n"); 04191 ast_config_destroy(cfg); 04192 return 0; 04193 } 04194 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 04195 } 04196 if (!ntohs(bindaddr.sin_port)) 04197 bindaddr.sin_port = ntohs(DEFAULT_MGCP_CA_PORT); 04198 bindaddr.sin_family = AF_INET; 04199 ast_mutex_lock(&netlock); 04200 if (mgcpsock > -1) 04201 close(mgcpsock); 04202 04203 if (mgcpsock_read_id != NULL) 04204 ast_io_remove(io, mgcpsock_read_id); 04205 mgcpsock_read_id = NULL; 04206 04207 mgcpsock = socket(AF_INET, SOCK_DGRAM, 0); 04208 if (mgcpsock < 0) { 04209 ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno)); 04210 } else { 04211 if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 04212 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 04213 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 04214 strerror(errno)); 04215 close(mgcpsock); 04216 mgcpsock = -1; 04217 } else { 04218 if (option_verbose > 1) { 04219 ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n", 04220 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 04221 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 04222 } 04223 if (setsockopt(mgcpsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 04224 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 04225 } 04226 } 04227 ast_mutex_unlock(&netlock); 04228 ast_config_destroy(cfg); 04229 04230 /* SC: send audit only to the new endpoints */ 04231 g = gateways; 04232 while (g) { 04233 e = g->endpoints; 04234 while (e && e->needaudit) { 04235 e->needaudit = 0; 04236 transmit_audit_endpoint(e); 04237 ast_verbose(VERBOSE_PREFIX_3 "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name); 04238 e = e->next; 04239 } 04240 g = g->next; 04241 } 04242 04243 return 0; 04244 }
|
|
Definition at line 1940 of file chan_mgcp.c. References init_req(), and oseq. Referenced by transmit_audit_endpoint(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_modify_request(), transmit_notify_request(), transmit_notify_request_with_callerid(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), and transmit_state_notify(). 01941 { 01942 memset(req, 0, sizeof(struct mgcp_request)); 01943 oseq++; 01944 if (oseq > 999999999) 01945 oseq = 1; 01946 init_req(p, req, verb); 01947 return 0; 01948 }
|
|
Definition at line 563 of file chan_mgcp.c. References __mgcp_xmit(), mgcp_gateway::addr, ast_inet_ntoa(), ast_verbose(), mgcp_response::buf, mgcp_response::len, mgcp_endpoint::parent, mgcp_subchannel::parent, and mgcp_endpoint::sub. Referenced by find_and_retrans(). 00564 { 00565 struct mgcp_endpoint *p = sub->parent; 00566 int res; 00567 char iabuf[INET_ADDRSTRLEN]; 00568 if (mgcpdebug) { 00569 ast_verbose("Retransmitting:\n%s\n to %s:%d\n", resp->buf, ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00570 } 00571 res = __mgcp_xmit(p->parent, resp->buf, resp->len); 00572 if (res > 0) 00573 res = 0; 00574 return res; 00575 }
|
|
Definition at line 1933 of file chan_mgcp.c. References init_resp(). Referenced by __transmit_response(), transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), and transmit_response_with_unsupported(). 01934 { 01935 memset(resp, 0, sizeof(*resp)); 01936 init_resp(resp, msg, req, msgrest); 01937 return 0; 01938 }
|
|
Definition at line 3451 of file chan_mgcp.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. 03452 { 03453 /* If we're supposed to be stopped -- stay stopped */ 03454 if (monitor_thread == AST_PTHREADT_STOP) 03455 return 0; 03456 if (ast_mutex_lock(&monlock)) { 03457 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 03458 return -1; 03459 } 03460 if (monitor_thread == pthread_self()) { 03461 ast_mutex_unlock(&monlock); 03462 ast_log(LOG_WARNING, "Cannot kill myself\n"); 03463 return -1; 03464 } 03465 if (monitor_thread != AST_PTHREADT_NULL) { 03466 /* Wake up the thread */ 03467 pthread_kill(monitor_thread, SIGURG); 03468 } else { 03469 /* Start a new monitor */ 03470 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 03471 ast_mutex_unlock(&monlock); 03472 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 03473 return -1; 03474 } 03475 } 03476 ast_mutex_unlock(&monlock); 03477 return 0; 03478 }
|
|
Definition at line 672 of file chan_mgcp.c. References __mgcp_xmit(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, handle_response(), LOG_WARNING, MAX_RETRANS, mgcpdebug, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::retrans, and mgcp_gateway::retransid. Referenced by __sip_reliable_xmit(), and mgcp_postrequest(). 00673 { 00674 struct mgcp_gateway *gw = (struct mgcp_gateway *)data; 00675 struct mgcp_message *cur, *exq = NULL, *w, *prev; 00676 int res = 0; 00677 00678 /* find out expired msgs */ 00679 ast_mutex_lock(&gw->msgs_lock); 00680 00681 prev = NULL, cur = gw->msgs; 00682 while (cur) { 00683 if (cur->retrans < MAX_RETRANS) { 00684 cur->retrans++; 00685 if (mgcpdebug) { 00686 ast_verbose("Retransmitting #%d transaction %u on [%s]\n", 00687 cur->retrans, cur->seqno, gw->name); 00688 } 00689 __mgcp_xmit(gw, cur->buf, cur->len); 00690 00691 prev = cur; 00692 cur = cur->next; 00693 } else { 00694 if (prev) 00695 prev->next = cur->next; 00696 else 00697 gw->msgs = cur->next; 00698 00699 ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n", 00700 cur->seqno, gw->name); 00701 00702 w = cur; 00703 cur = cur->next; 00704 00705 if (exq) { 00706 w->next = exq; 00707 } else { 00708 w->next = NULL; 00709 } 00710 exq = w; 00711 } 00712 } 00713 00714 if (!gw->msgs) { 00715 gw->retransid = -1; 00716 res = 0; 00717 } else { 00718 res = 1; 00719 } 00720 ast_mutex_unlock(&gw->msgs_lock); 00721 00722 while (exq) { 00723 cur = exq; 00724 /* time-out transaction */ 00725 handle_response(cur->owner_ep, cur->owner_sub, 406, cur->seqno, NULL); 00726 exq = exq->next; 00727 free(cur); 00728 } 00729 00730 return res; 00731 }
|
|
Definition at line 1481 of file chan_mgcp.c. Referenced by process_sdp().
|
|
Definition at line 800 of file chan_mgcp.c. References mgcp_gateway::addr, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), mgcp_request::cmd, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_request::data, free, mgcp_request::len, LOG_DEBUG, LOG_WARNING, malloc, MGCP_CMD_CRCX, MGCP_CMD_DLCX, MGCP_CMD_MDCX, MGCP_CMD_RQNT, mgcp_postrequest(), mgcpdebug, mgcp_request::next, mgcp_endpoint::parent, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, mgcp_endpoint::slowsequence, and t. Referenced by transmit_audit_endpoint(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_info_with_digit(), transmit_info_with_vidupdate(), transmit_invite(), transmit_message_with_text(), transmit_modify_request(), transmit_notify_request(), transmit_notify_request_with_callerid(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), transmit_sip_request(), and transmit_state_notify(). 00802 { 00803 int res = 0; 00804 struct mgcp_request **queue, *q, *r, *t; 00805 char iabuf[INET_ADDRSTRLEN]; 00806 ast_mutex_t *l; 00807 00808 ast_log(LOG_DEBUG, "Slow sequence is %d\n", p->slowsequence); 00809 if (p->slowsequence) { 00810 queue = &p->cmd_queue; 00811 l = &p->cmd_queue_lock; 00812 ast_mutex_lock(l); 00813 } else { 00814 switch (req->cmd) { 00815 case MGCP_CMD_DLCX: 00816 queue = &sub->cx_queue; 00817 l = &sub->cx_queue_lock; 00818 ast_mutex_lock(l); 00819 q = sub->cx_queue; 00820 /* delete pending cx cmds */ 00821 while (q) { 00822 r = q->next; 00823 free(q); 00824 q = r; 00825 } 00826 *queue = NULL; 00827 break; 00828 00829 case MGCP_CMD_CRCX: 00830 case MGCP_CMD_MDCX: 00831 queue = &sub->cx_queue; 00832 l = &sub->cx_queue_lock; 00833 ast_mutex_lock(l); 00834 break; 00835 00836 case MGCP_CMD_RQNT: 00837 queue = &p->rqnt_queue; 00838 l = &p->rqnt_queue_lock; 00839 ast_mutex_lock(l); 00840 break; 00841 00842 default: 00843 queue = &p->cmd_queue; 00844 l = &p->cmd_queue_lock; 00845 ast_mutex_lock(l); 00846 break; 00847 } 00848 } 00849 00850 r = (struct mgcp_request *) malloc (sizeof(struct mgcp_request)); 00851 if (!r) { 00852 ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n"); 00853 ast_mutex_unlock(l); 00854 return -1; 00855 } 00856 memcpy(r, req, sizeof(struct mgcp_request)); 00857 00858 if (!(*queue)) { 00859 if (mgcpdebug) { 00860 ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, 00861 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00862 } 00863 00864 res = mgcp_postrequest(p, sub, req->data, req->len, seqno); 00865 } else { 00866 if (mgcpdebug) { 00867 ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data, 00868 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00869 } 00870 } 00871 00872 /* XXX SC: find tail. We could also keep tail in the data struct for faster access */ 00873 for (t = *queue; t && t->next; t = t->next); 00874 00875 r->next = NULL; 00876 if (t) 00877 t->next = r; 00878 else 00879 *queue = r; 00880 00881 ast_mutex_unlock(l); 00882 00883 return res; 00884 }
|
|
Definition at line 577 of file chan_mgcp.c. References __mgcp_xmit(), mgcp_gateway::addr, ast_inet_ntoa(), ast_verbose(), mgcp_request::data, mgcp_request::len, mgcp_endpoint::parent, mgcp_subchannel::parent, and mgcp_endpoint::sub. Referenced by __transmit_response(), transmit_response(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_sdp(), and transmit_response_with_unsupported(). 00578 { 00579 struct mgcp_endpoint *p = sub->parent; 00580 int res; 00581 char iabuf[INET_ADDRSTRLEN]; 00582 if (mgcpdebug) { 00583 ast_verbose("Transmitting:\n%s\n to %s:%d\n", req->data, ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00584 } 00585 res = __mgcp_xmit(p->parent, req->data, req->len); 00586 if (res > 0) 00587 res = 0; 00588 return res; 00589 }
|
|
|
Definition at line 2253 of file chan_mgcp.c. References add_header(), mgcp_request::cmd, MGCP_CMD_AUEP, oseq, reqprep(), send_request(), and mgcp_request::trid. Referenced by handle_request(), mgcp_audit_endpoint(), and reload_config(). 02254 { 02255 struct mgcp_request resp; 02256 reqprep(&resp, p, "AUEP"); 02257 /* SC: removed unknown param VS */ 02258 /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/ 02259 add_header(&resp, "F", "A"); 02260 /* SC: fill in new fields */ 02261 resp.cmd = MGCP_CMD_AUEP; 02262 resp.trid = oseq; 02263 return send_request(p, NULL, &resp, oseq); /* SC */ 02264 }
|
|
Definition at line 2108 of file chan_mgcp.c. References AST_FORMAT_MAX_AUDIO, ast_rtp_lookup_mime_subtype(), mgcp_endpoint::capability, mgcp_subchannel::parent, and mgcp_endpoint::sub. Referenced by start_rtp(). 02109 { 02110 struct mgcp_request resp; 02111 char local[256]; 02112 char tmp[80]; 02113 int x; 02114 struct mgcp_endpoint *p = sub->parent; 02115 02116 snprintf(local, sizeof(local), "p:20"); 02117 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02118 if (p->capability & x) { 02119 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02120 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02121 } 02122 } 02123 if (mgcpdebug) { 02124 ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", 02125 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02126 } 02127 reqprep(&resp, p, "CRCX"); 02128 add_header(&resp, "C", sub->callid); 02129 add_header(&resp, "L", local); 02130 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02131 /* SC: X header should not be sent. kept for compatibility */ 02132 add_header(&resp, "X", sub->txident); 02133 /*add_header(&resp, "S", "");*/ 02134 ast_rtp_offered_from_local(sub->rtp, 1); 02135 add_sdp(&resp, sub, rtp); 02136 /* SC: fill in new fields */ 02137 resp.cmd = MGCP_CMD_CRCX; 02138 resp.trid = oseq; 02139 return send_request(p, sub, &resp, oseq); /* SC */ 02140 }
|
|
Definition at line 2266 of file chan_mgcp.c. References add_header(), ast_verbose(), mgcp_subchannel::callid, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_subchannel::id, MGCP_CMD_DLCX, mgcp_cxmodes, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), send_request(), mgcp_endpoint::sub, mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by destroy_endpoint(), handle_request(), handle_response(), mgcp_hangup(), and unalloc_sub(). 02267 { 02268 struct mgcp_endpoint *p = sub->parent; 02269 struct mgcp_request resp; 02270 02271 if (mgcpdebug) { 02272 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", 02273 sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02274 } 02275 reqprep(&resp, p, "DLCX"); 02276 /* SC: check if call id is avail */ 02277 if (sub->callid[0]) 02278 add_header(&resp, "C", sub->callid); 02279 /* SC: X header should not be sent. kept for compatibility */ 02280 add_header(&resp, "X", sub->txident); 02281 /* SC: check if cxident is avail */ 02282 if (sub->cxident[0]) 02283 add_header(&resp, "I", sub->cxident); 02284 /* SC: fill in new fields */ 02285 resp.cmd = MGCP_CMD_DLCX; 02286 resp.trid = oseq; 02287 return send_request(p, sub, &resp, oseq); /* SC */ 02288 }
|
|
Definition at line 2290 of file chan_mgcp.c. References add_header(), ast_verbose(), MGCP_CMD_DLCX, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, reqprep(), send_request(), mgcp_endpoint::sub, and VERBOSE_PREFIX_3. Referenced by handle_response(). 02291 { 02292 struct mgcp_request resp; 02293 02294 if (mgcpdebug) { 02295 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", 02296 cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); 02297 } 02298 reqprep(&resp, p, "DLCX"); 02299 /* SC: check if call id is avail */ 02300 if (callid && *callid) 02301 add_header(&resp, "C", callid); 02302 /* SC: check if cxident is avail */ 02303 if (cxident && *cxident) 02304 add_header(&resp, "I", cxident); 02305 /* SC: fill in new fields */ 02306 resp.cmd = MGCP_CMD_DLCX; 02307 resp.trid = oseq; 02308 return send_request(p, p->sub, &resp, oseq); 02309 }
|
|
Definition at line 2218 of file chan_mgcp.c. References add_header(), ast_strlen_zero(), ast_verbose(), mgcp_subchannel::callid, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_endpoint::dtmfmode, mgcp_endpoint::hookstate, mgcp_subchannel::id, MGCP_CMD_MDCX, mgcp_cxmodes, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::rtp, send_request(), mgcp_endpoint::sub, mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), mgcp_call(), and mgcp_hangup(). 02219 { 02220 struct mgcp_request resp; 02221 struct mgcp_endpoint *p = sub->parent; 02222 02223 if (ast_strlen_zero(sub->cxident)) { 02224 /* We don't have a CXident yet, store the destination and 02225 wait a bit */ 02226 return 0; 02227 } 02228 if (mgcpdebug) { 02229 ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", 02230 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02231 } 02232 reqprep(&resp, p, "MDCX"); 02233 add_header(&resp, "C", sub->callid); 02234 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02235 /* SC: X header should not be sent. kept for compatibility */ 02236 add_header(&resp, "X", sub->txident); 02237 add_header(&resp, "I", sub->cxident); 02238 switch (sub->parent->hookstate) { 02239 case MGCP_ONHOOK: 02240 add_header(&resp, "R", "L/hd(N)"); 02241 break; 02242 case MGCP_OFFHOOK: 02243 add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N), L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); 02244 break; 02245 } 02246 /* SC: fill in new fields */ 02247 resp.cmd = MGCP_CMD_MDCX; 02248 resp.trid = oseq; 02249 return send_request(p, sub, &resp, oseq); /* SC */ 02250 }
|
|
Definition at line 2067 of file chan_mgcp.c. References AST_FORMAT_MAX_AUDIO, ast_rtp_get_peer(), ast_rtp_lookup_mime_subtype(), ast_strlen_zero(), mgcp_endpoint::capability, capability, mgcp_subchannel::cxident, mgcp_subchannel::parent, mgcp_endpoint::sub, and mgcp_subchannel::tmpdest. Referenced by handle_response(), and mgcp_set_rtp_peer(). 02068 { 02069 struct mgcp_request resp; 02070 char local[256]; 02071 char tmp[80]; 02072 int x; 02073 int capability; 02074 struct mgcp_endpoint *p = sub->parent; 02075 02076 capability = p->capability; 02077 if (codecs) 02078 capability = codecs; 02079 if (ast_strlen_zero(sub->cxident) && rtp) { 02080 /* We don't have a CXident yet, store the destination and 02081 wait a bit */ 02082 ast_rtp_get_peer(rtp, &sub->tmpdest); 02083 return 0; 02084 } 02085 snprintf(local, sizeof(local), "p:20"); 02086 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02087 if (p->capability & x) { 02088 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02089 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02090 } 02091 } 02092 reqprep(&resp, p, "MDCX"); 02093 add_header(&resp, "C", sub->callid); 02094 add_header(&resp, "L", local); 02095 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02096 /* SC: X header should not be sent. kept for compatibility */ 02097 add_header(&resp, "X", sub->txident); 02098 add_header(&resp, "I", sub->cxident); 02099 /*add_header(&resp, "S", "");*/ 02100 ast_rtp_offered_from_local(sub->rtp, 0); 02101 add_sdp(&resp, sub, rtp); 02102 /* SC: fill in new fields */ 02103 resp.cmd = MGCP_CMD_MDCX; 02104 resp.trid = oseq; 02105 return send_request(p, sub, &resp, oseq); /* SC */ 02106 }
|
|
|
Definition at line 2171 of file chan_mgcp.c. References add_header(), ast_strlen_zero(), ast_verbose(), mgcp_request::cmd, mgcp_endpoint::curtone, mgcp_subchannel::cxmode, mgcp_endpoint::dtmfmode, mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_endpoint::lastcallerid, MGCP_CMD_RQNT, mgcp_cxmodes, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, n, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_endpoint::rqnt_ident, mgcp_subchannel::rtp, send_request(), mgcp_endpoint::sub, t, mgcp_request::trid, and VERBOSE_PREFIX_3. Referenced by mgcp_call(), and mgcp_hangup(). 02172 { 02173 struct mgcp_request resp; 02174 char tone2[256]; 02175 char *l, *n; 02176 time_t t; 02177 struct tm tm; 02178 struct mgcp_endpoint *p = sub->parent; 02179 02180 time(&t); 02181 localtime_r(&t,&tm); 02182 n = callername; 02183 l = callernum; 02184 if (!n) 02185 n = ""; 02186 if (!l) 02187 l = ""; 02188 02189 /* Keep track of last callerid for blacklist and callreturn */ 02190 strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1); 02191 02192 snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 02193 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n); 02194 strncpy(p->curtone, tone, sizeof(p->curtone) - 1); 02195 reqprep(&resp, p, "RQNT"); 02196 add_header(&resp, "X", p->rqnt_ident); /* SC */ 02197 switch (p->hookstate) { 02198 case MGCP_ONHOOK: 02199 add_header(&resp, "R", "L/hd(N)"); 02200 break; 02201 case MGCP_OFFHOOK: 02202 add_header(&resp, "R", (sub->rtp && (p->dtmfmode & MGCP_DTMF_INBAND)) ? "L/hu(N),L/hf(N)" : "L/hu(N),L/hf(N),D/[0-9#*](N)"); 02203 break; 02204 } 02205 if (!ast_strlen_zero(tone2)) { 02206 add_header(&resp, "S", tone2); 02207 } 02208 if (mgcpdebug) { 02209 ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", 02210 tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); 02211 } 02212 /* SC: fill in new fields */ 02213 resp.cmd = MGCP_CMD_RQNT; 02214 resp.trid = oseq; 02215 return send_request(p, NULL, &resp, oseq); /* SC */ 02216 }
|
|
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 4305 of file chan_mgcp.c. References ast_channel_register(), ast_channel_unregister(), ast_cli_unregister(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), cli_audit_endpoint, cli_debug, cli_mgcp_reload, cli_no_debug, cli_show_endpoints, mgcp_endpoint::delme, mgcp_gateway::delme, mgcp_gateway::endpoints, gateways, LOG_WARNING, mgcp_reload(), mgcp_reloading, mgcp_rtp, mgcp_tech, mgcpsock, monitor_thread, mgcp_gateway::next, mgcp_endpoint::next, prune_gateways(), and sched_context_destroy(). 04306 { 04307 struct mgcp_endpoint *e; 04308 struct mgcp_gateway *g; 04309 04310 /* Check to see if we're reloading */ 04311 if (ast_mutex_trylock(&mgcp_reload_lock)) { 04312 ast_log(LOG_WARNING, "MGCP is currently reloading. Unable to remove module.\n"); 04313 return -1; 04314 } else { 04315 mgcp_reloading = 1; 04316 ast_mutex_unlock(&mgcp_reload_lock); 04317 } 04318 04319 /* First, take us out of the channel loop */ 04320 ast_channel_unregister(&mgcp_tech); 04321 04322 /* Shut down the monitoring thread */ 04323 if (!ast_mutex_lock(&monlock)) { 04324 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 04325 pthread_cancel(monitor_thread); 04326 pthread_kill(monitor_thread, SIGURG); 04327 pthread_join(monitor_thread, NULL); 04328 } 04329 monitor_thread = AST_PTHREADT_STOP; 04330 ast_mutex_unlock(&monlock); 04331 } else { 04332 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 04333 /* We always want to leave this in a consistent state */ 04334 ast_channel_register(&mgcp_tech); 04335 mgcp_reloading = 0; 04336 mgcp_reload(0, 0, NULL); 04337 return -1; 04338 } 04339 04340 if (!ast_mutex_lock(&gatelock)) { 04341 g = gateways; 04342 while (g) { 04343 g->delme = 1; 04344 e = g->endpoints; 04345 while (e) { 04346 e->delme = 1; 04347 e = e->next; 04348 } 04349 g = g->next; 04350 } 04351 04352 prune_gateways(); 04353 ast_mutex_unlock(&gatelock); 04354 } else { 04355 ast_log(LOG_WARNING, "Unable to lock the gateways list.\n"); 04356 /* We always want to leave this in a consistent state */ 04357 ast_channel_register(&mgcp_tech); 04358 /* Allow the monitor to restart */ 04359 monitor_thread = AST_PTHREADT_NULL; 04360 mgcp_reloading = 0; 04361 mgcp_reload(0, 0, NULL); 04362 return -1; 04363 } 04364 04365 close(mgcpsock); 04366 ast_rtp_proto_unregister(&mgcp_rtp); 04367 ast_cli_unregister(&cli_show_endpoints); 04368 ast_cli_unregister(&cli_audit_endpoint); 04369 ast_cli_unregister(&cli_debug); 04370 ast_cli_unregister(&cli_no_debug); 04371 ast_cli_unregister(&cli_mgcp_reload); 04372 sched_context_destroy(sched); 04373 04374 return 0; 04375 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 4377 of file chan_mgcp.c. References usecnt. 04378 { 04379 return usecnt; 04380 }
|
|
Definition at line 272 of file chan_mgcp.c. |
|
Definition at line 234 of file chan_mgcp.c. |
|
Definition at line 240 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 238 of file chan_mgcp.c. |
|
Initial value: "Usage: mgcp audit endpoint <endpointid>\n" " Lists the capabilities of an endpoint in the MGCP (Media Gateway Control Protocol) subsystem.\n" " mgcp debug MUST be on to see the results of this command.\n" Definition at line 1175 of file chan_mgcp.c. |
|
Definition at line 473 of file chan_mgcp.c. |
|
Definition at line 215 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 207 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 224 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 228 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 268 of file chan_mgcp.c. Referenced by add_sdp(), build_gateway(), iax2_call(), mgcp_new(), mgcp_request(), process_sdp(), reload_config(), set_config(), set_local_capabilities(), and transmit_modify_with_sdp(). |
|
Definition at line 184 of file chan_mgcp.c. Referenced by build_gateway(), builtin_atxfer(), check_access(), misdn_new(), monitor_handle_notowned(), and vpb_new(). |
|
Definition at line 183 of file chan_mgcp.c. Referenced by build_gateway(), builtin_atxfer(), check_access(), misdn_new(), monitor_handle_notowned(), and vpb_new(). |
|
Initial value: { { "mgcp", "audit", "endpoint", NULL }, mgcp_audit_endpoint, "Audit specified MGCP endpoint", audit_endpoint_usage } Definition at line 1180 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "debug", NULL }, mgcp_do_debug, "Enable MGCP debugging", debug_usage } Definition at line 3971 of file chan_mgcp.c. |
|
Initial value: { { "mgcp", "reload", NULL }, mgcp_reload, "Reload MGCP configuration", mgcp_reload_usage } Definition at line 3975 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "no", "debug", NULL }, mgcp_no_debug, "Disable MGCP debugging", no_debug_usage } Definition at line 3973 of file chan_mgcp.c. |
|
Initial value: { { "mgcp", "show", "endpoints", NULL }, mgcp_show_endpoints, "Show defined MGCP endpoints", show_endpoints_usage } Definition at line 1119 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 139 of file chan_mgcp.c. |
|
Definition at line 179 of file chan_mgcp.c. |
|
Definition at line 195 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 196 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Initial value: "Usage: mgcp debug\n" " Enables dumping of MGCP packets for debugging purposes\n" Definition at line 3959 of file chan_mgcp.c. |
|
Definition at line 136 of file chan_mgcp.c. |
|
Definition at line 186 of file chan_mgcp.c. Referenced by build_gateway(), reload_config(), and set_local_capabilities(). |
|
Definition at line 248 of file chan_mgcp.c. Referenced by disa_exec(), and mgcp_ss(). |
|
Referenced by build_gateway(), do_monitor(), find_subchannel_and_lock(), mgcp_audit_endpoint(), mgcp_show_endpoints(), prune_gateways(), reload_config(), and unload_module(). |
|
Definition at line 251 of file chan_mgcp.c. Referenced by mgcp_ss(). |
|
Definition at line 205 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 278 of file chan_mgcp.c. |
|
Definition at line 181 of file chan_mgcp.c. |
|
Definition at line 236 of file chan_mgcp.c. Referenced by action_mailboxcount(), action_mailboxstatus(), build_gateway(), disa_exec(), handle_request_subscribe(), and realtime_directory(). |
|
Definition at line 254 of file chan_mgcp.c. Referenced by mgcp_ss(). |
|
Definition at line 160 of file chan_mgcp.c. Referenced by transmit_connection_del(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Initial value: "Usage: mgcp reload\n" " Reloads MGCP configuration from mgcp.conf\n" Definition at line 3967 of file chan_mgcp.c. |
|
Definition at line 467 of file chan_mgcp.c. Referenced by do_monitor(), mgcp_reload(), and unload_module(). |
|
Initial value: { .type = type, .get_rtp_info = mgcp_get_rtp_peer, .set_rtp_peer = mgcp_set_rtp_peer, } Definition at line 3935 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 500 of file chan_mgcp.c. Referenced by load_module(), mgcp_new(), and unload_module(). |
|
Definition at line 275 of file chan_mgcp.c. Referenced by add_sdp(), mgcp_audit_endpoint(), mgcp_call(), mgcp_hangup(), mgcp_indicate(), parse(), process_sdp(), retrans_pkt(), and send_request(). |
|
Definition at line 471 of file chan_mgcp.c. Referenced by do_monitor(), mgcpsock_read(), reload_config(), and unload_module(). |
|
Definition at line 3363 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 264 of file chan_mgcp.c. |
|
Definition at line 182 of file chan_mgcp.c. Referenced by build_gateway(), and read_config(). |
|
Definition at line 187 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Initial value: "Usage: mgcp no debug\n" " Disables dumping of MGCP packets for debugging purposes\n" Definition at line 3963 of file chan_mgcp.c. |
|
Definition at line 269 of file chan_mgcp.c. Referenced by process_sdp(). |
|
Definition at line 245 of file chan_mgcp.c. Referenced by init_req(), reqprep(), transmit_audit_endpoint(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 271 of file chan_mgcp.c. Referenced by ast_find_ourip(), and reload_config(). |
|
Definition at line 273 of file chan_mgcp.c. Referenced by build_contact(), and reload_config(). |
|
Definition at line 277 of file chan_mgcp.c. |
|
Initial value: "Usage: mgcp show endpoints\n" " Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n" Definition at line 1115 of file chan_mgcp.c. |
|
Definition at line 226 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 217 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 138 of file chan_mgcp.c. |
|
Definition at line 219 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 203 of file chan_mgcp.c. |
|
Definition at line 222 of file chan_mgcp.c. Referenced by build_gateway(), and leave_voicemail(). |
|
Definition at line 137 of file chan_mgcp.c. |
|
Definition at line 242 of file chan_mgcp.c. |