#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"
Include dependency graph for chan_mgcp.c:
Go to the source code of this file.
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. Referenced by build_gateway(). |
|
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(), send_request(), and transmit_connect_with_sdp(). |
|
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(), transmit_modify_request(), and transmit_modify_with_sdp(). |
|
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 1492 of file chan_mgcp.c. References mgcp_request::header. Referenced by build_route(), copy_all_header(), copy_via_headers(), get_header(), and handle_response_register(). 01493 { 01494 int x; 01495 int len = strlen(name); 01496 char *r; 01497 for (x=*start;x<req->headers;x++) { 01498 if (!strncasecmp(req->header[x], name, len) && 01499 (req->header[x][len] == ':')) { 01500 r = req->header[x] + len + 1; 01501 while(*r && (*r < 33)) 01502 r++; 01503 *start = x+1; 01504 return r; 01505 } 01506 } 01507 /* Don't return NULL, so get_header is always a valid pointer */ 01508 return ""; 01509 }
|
|
Definition at line 550 of file chan_mgcp.c. References mgcp_gateway::addr, ast_log(), mgcp_gateway::defaddr, LOG_WARNING, and mgcpsock. 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 1866 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_sdp(), add_text(), add_vidupdate(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), and transmit_state_notify(). 01867 { 01868 if (req->len >= sizeof(req->data) - 4) { 01869 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 01870 return -1; 01871 } 01872 if (!req->lines) { 01873 /* Add extra empty return */ 01874 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 01875 req->len += strlen(req->data + req->len); 01876 } 01877 req->line[req->lines] = req->data + req->len; 01878 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 01879 req->len += strlen(req->line[req->lines]); 01880 if (req->lines < MGCP_MAX_LINES) 01881 req->lines++; 01882 else { 01883 ast_log(LOG_WARNING, "Out of line space\n"); 01884 return -1; 01885 } 01886 return 0; 01887 }
|
|
Definition at line 1968 of file chan_mgcp.c. References add_line(), AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_get_peer(), ast_rtp_get_us(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_MAX, ast_verbose(), mgcp_endpoint::capability, mgcp_response::len, LOG_WARNING, mgcpdebug, mgcp_endpoint::nonCodecCapability, mgcp_gateway::ourip, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, s, t, and mgcp_subchannel::tmpdest. Referenced by transmit_connect_with_sdp(), transmit_invite(), transmit_modify_with_sdp(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp(). 01969 { 01970 int len; 01971 int codec; 01972 char costr[80]; 01973 struct sockaddr_in sin; 01974 char v[256]; 01975 char s[256]; 01976 char o[256]; 01977 char c[256]; 01978 char t[256]; 01979 char m[256] = ""; 01980 char a[1024] = ""; 01981 char iabuf[INET_ADDRSTRLEN]; 01982 int x; 01983 struct sockaddr_in dest; 01984 struct mgcp_endpoint *p = sub->parent; 01985 /* XXX We break with the "recommendation" and send our IP, in order that our 01986 peer doesn't have to ast_gethostbyname() us XXX */ 01987 len = 0; 01988 if (!sub->rtp) { 01989 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 01990 return -1; 01991 } 01992 ast_rtp_get_us(sub->rtp, &sin); 01993 if (rtp) { 01994 ast_rtp_get_peer(rtp, &dest); 01995 } else { 01996 if (sub->tmpdest.sin_addr.s_addr) { 01997 dest.sin_addr = sub->tmpdest.sin_addr; 01998 dest.sin_port = sub->tmpdest.sin_port; 01999 /* Reset temporary destination */ 02000 memset(&sub->tmpdest, 0, sizeof(sub->tmpdest)); 02001 } else { 02002 dest.sin_addr = p->parent->ourip; 02003 dest.sin_port = sin.sin_port; 02004 } 02005 } 02006 if (mgcpdebug) { 02007 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->ourip), ntohs(sin.sin_port)); 02008 } 02009 snprintf(v, sizeof(v), "v=0\r\n"); 02010 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02011 snprintf(s, sizeof(s), "s=session\r\n"); 02012 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02013 snprintf(t, sizeof(t), "t=0 0\r\n"); 02014 snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 02015 for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02016 if (p->capability & x) { 02017 if (mgcpdebug) { 02018 ast_verbose("Answering with capability %d\n", x); 02019 } 02020 codec = ast_rtp_lookup_code(sub->rtp, 1, x); 02021 if (codec > -1) { 02022 snprintf(costr, sizeof(costr), " %d", codec); 02023 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02024 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x)); 02025 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02026 } 02027 } 02028 } 02029 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 02030 if (p->nonCodecCapability & x) { 02031 if (mgcpdebug) { 02032 ast_verbose("Answering with non-codec capability %d\n", x); 02033 } 02034 codec = ast_rtp_lookup_code(sub->rtp, 0, x); 02035 if (codec > -1) { 02036 snprintf(costr, sizeof(costr), " %d", codec); 02037 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02038 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x)); 02039 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02040 if (x == AST_RTP_DTMF) { 02041 /* Indicate we support DTMF... Not sure about 16, 02042 but MSN supports it so dang it, we will too... */ 02043 snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec); 02044 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02045 } 02046 } 02047 } 02048 } 02049 strncat(m, "\r\n", sizeof(m) - strlen(m) - 1); 02050 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a); 02051 snprintf(costr, sizeof(costr), "%d", len); 02052 add_line(resp, v); 02053 add_line(resp, o); 02054 add_line(resp, s); 02055 add_line(resp, c); 02056 add_line(resp, t); 02057 add_line(resp, m); 02058 add_line(resp, a); 02059 return 0; 02060 }
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 2818 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_message(), handle_request(), handle_request_refer(), and zt_handle_event(). 02819 { 02820 /* ************************* 02821 * I hope this works. 02822 * Copied out of chan_zap 02823 * Cross your fingers 02824 * *************************/ 02825 02826 /* In order to transfer, we need at least one of the channels to 02827 actually be in a call bridge. We can't conference two applications 02828 together (but then, why would we want to?) */ 02829 if (ast_bridged_channel(p->sub->owner)) { 02830 /* The three-way person we're about to transfer to could still be in MOH, so 02831 stop if now if appropriate */ 02832 if (ast_bridged_channel(p->sub->next->owner)) 02833 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02834 if (p->sub->owner->_state == AST_STATE_RINGING) { 02835 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02836 } 02837 if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { 02838 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02839 ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); 02840 return -1; 02841 } 02842 /* Orphan the channel */ 02843 unalloc_sub(p->sub->next); 02844 } else if (ast_bridged_channel(p->sub->next->owner)) { 02845 if (p->sub->owner->_state == AST_STATE_RINGING) { 02846 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02847 } 02848 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02849 if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { 02850 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02851 ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); 02852 return -1; 02853 } 02854 /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ 02855 if (option_verbose > 2) { 02856 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); 02857 } 02858 p->sub = p->sub->next; 02859 unalloc_sub(p->sub->next); 02860 /* Tell the caller not to hangup */ 02861 return 1; 02862 } else { 02863 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 02864 p->sub->owner->name, p->sub->next->owner->name); 02865 p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02866 if (p->sub->next->owner) { 02867 p->sub->next->alreadygone = 1; 02868 mgcp_queue_hangup(p->sub->next); 02869 } 02870 } 02871 return 0; 02872 }
|
|
Definition at line 3528 of file chan_mgcp.c. References __ourip, 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_ouraddrfor(), 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, DEFAULT_MGCP_GW_PORT, 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_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, ast_variable::next, mgcp_subchannel::next, mgcp_endpoint::next, mgcp_gateway::next, mgcp_endpoint::onhooktime, mgcp_gateway::ourip, 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(). 03529 { 03530 struct mgcp_gateway *gw; 03531 struct mgcp_endpoint *e; 03532 struct mgcp_subchannel *sub; 03533 /*char txident[80];*/ 03534 int i=0, y=0; 03535 int gw_reload = 0; 03536 int ep_reload = 0; 03537 canreinvite = CANREINVITE; 03538 03539 /* SC: locate existing gateway */ 03540 gw = gateways; 03541 while (gw) { 03542 if (!strcasecmp(cat, gw->name)) { 03543 /* gateway already exists */ 03544 gw->delme = 0; 03545 gw_reload = 1; 03546 break; 03547 } 03548 gw = gw->next; 03549 } 03550 03551 if (!gw) 03552 gw = malloc(sizeof(struct mgcp_gateway)); 03553 03554 if (gw) { 03555 if (!gw_reload) { 03556 memset(gw, 0, sizeof(struct mgcp_gateway)); 03557 gw->expire = -1; 03558 gw->retransid = -1; /* SC */ 03559 ast_mutex_init(&gw->msgs_lock); 03560 strncpy(gw->name, cat, sizeof(gw->name) - 1); 03561 /* SC: check if the name is numeric ip */ 03562 if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE) 03563 gw->isnamedottedip = 1; 03564 } 03565 while(v) { 03566 if (!strcasecmp(v->name, "host")) { 03567 if (!strcasecmp(v->value, "dynamic")) { 03568 /* They'll register with us */ 03569 gw->dynamic = 1; 03570 memset(&gw->addr.sin_addr, 0, 4); 03571 if (gw->addr.sin_port) { 03572 /* If we've already got a port, make it the default rather than absolute */ 03573 gw->defaddr.sin_port = gw->addr.sin_port; 03574 gw->addr.sin_port = 0; 03575 } 03576 } else { 03577 /* Non-dynamic. Make sure we become that way if we're not */ 03578 if (gw->expire > -1) 03579 ast_sched_del(sched, gw->expire); 03580 gw->expire = -1; 03581 gw->dynamic = 0; 03582 if (ast_get_ip(&gw->addr, v->value)) { 03583 if (!gw_reload) { 03584 ast_mutex_destroy(&gw->msgs_lock); 03585 free(gw); 03586 } 03587 return NULL; 03588 } 03589 } 03590 } else if (!strcasecmp(v->name, "defaultip")) { 03591 if (ast_get_ip(&gw->defaddr, v->value)) { 03592 if (!gw_reload) { 03593 ast_mutex_destroy(&gw->msgs_lock); 03594 free(gw); 03595 } 03596 return NULL; 03597 } 03598 } else if (!strcasecmp(v->name, "permit") || 03599 !strcasecmp(v->name, "deny")) { 03600 gw->ha = ast_append_ha(v->name, v->value, gw->ha); 03601 } else if (!strcasecmp(v->name, "port")) { 03602 gw->addr.sin_port = htons(atoi(v->value)); 03603 } else if (!strcasecmp(v->name, "context")) { 03604 strncpy(context, v->value, sizeof(context) - 1); 03605 } else if (!strcasecmp(v->name, "dtmfmode")) { 03606 if (!strcasecmp(v->value, "inband")) 03607 dtmfmode = MGCP_DTMF_INBAND; 03608 else if (!strcasecmp(v->value, "rfc2833")) 03609 dtmfmode = MGCP_DTMF_RFC2833; 03610 else if (!strcasecmp(v->value, "hybrid")) 03611 dtmfmode = MGCP_DTMF_HYBRID; 03612 else if (!strcasecmp(v->value, "none")) 03613 dtmfmode = 0; 03614 else 03615 ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno); 03616 } else if (!strcasecmp(v->name, "nat")) { 03617 nat = ast_true(v->value); 03618 } else if (!strcasecmp(v->name, "callerid")) { 03619 if (!strcasecmp(v->value, "asreceived")) { 03620 cid_num[0] = '\0'; 03621 cid_name[0] = '\0'; 03622 } else { 03623 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 03624 } 03625 } else if (!strcasecmp(v->name, "language")) { 03626 strncpy(language, v->value, sizeof(language)-1); 03627 } else if (!strcasecmp(v->name, "accountcode")) { 03628 strncpy(accountcode, v->value, sizeof(accountcode)-1); 03629 } else if (!strcasecmp(v->name, "amaflags")) { 03630 y = ast_cdr_amaflags2int(v->value); 03631 if (y < 0) { 03632 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 03633 } else { 03634 amaflags = y; 03635 } 03636 } else if (!strcasecmp(v->name, "musiconhold")) { 03637 strncpy(musicclass, v->value, sizeof(musicclass)-1); 03638 } else if (!strcasecmp(v->name, "callgroup")) { 03639 cur_callergroup = ast_get_group(v->value); 03640 } else if (!strcasecmp(v->name, "pickupgroup")) { 03641 cur_pickupgroup = ast_get_group(v->value); 03642 } else if (!strcasecmp(v->name, "immediate")) { 03643 immediate = ast_true(v->value); 03644 } else if (!strcasecmp(v->name, "cancallforward")) { 03645 cancallforward = ast_true(v->value); 03646 } else if (!strcasecmp(v->name, "singlepath")) { 03647 singlepath = ast_true(v->value); 03648 } else if (!strcasecmp(v->name, "canreinvite")) { 03649 canreinvite = ast_true(v->value); 03650 } else if (!strcasecmp(v->name, "mailbox")) { 03651 strncpy(mailbox, v->value, sizeof(mailbox) -1); 03652 } else if (!strcasecmp(v->name, "adsi")) { 03653 adsi = ast_true(v->value); 03654 } else if (!strcasecmp(v->name, "callreturn")) { 03655 callreturn = ast_true(v->value); 03656 } else if (!strcasecmp(v->name, "callwaiting")) { 03657 callwaiting = ast_true(v->value); 03658 } else if (!strcasecmp(v->name, "slowsequence")) { 03659 slowsequence = ast_true(v->value); 03660 } else if (!strcasecmp(v->name, "transfer")) { 03661 transfer = ast_true(v->value); 03662 } else if (!strcasecmp(v->name, "threewaycalling")) { 03663 threewaycalling = ast_true(v->value); 03664 } else if (!strcasecmp(v->name, "wcardep")) { 03665 /* SC: locate existing endpoint */ 03666 e = gw->endpoints; 03667 while (e) { 03668 if (!strcasecmp(v->value, e->name)) { 03669 /* endpoint already exists */ 03670 e->delme = 0; 03671 ep_reload = 1; 03672 break; 03673 } 03674 e = e->next; 03675 } 03676 03677 if (!e) { 03678 /* Allocate wildcard endpoint */ 03679 e = malloc(sizeof(struct mgcp_endpoint)); 03680 ep_reload = 0; 03681 } 03682 03683 if (e) { 03684 if (!ep_reload) { 03685 memset(e, 0, sizeof(struct mgcp_endpoint)); 03686 ast_mutex_init(&e->lock); 03687 ast_mutex_init(&e->rqnt_queue_lock); 03688 ast_mutex_init(&e->cmd_queue_lock); 03689 strncpy(e->name, v->value, sizeof(e->name) - 1); 03690 e->needaudit = 1; 03691 } 03692 strncpy(gw->wcardep, v->value, sizeof(gw->wcardep) - 1); 03693 /*strncpy(e->name, "aaln/" "*", sizeof(e->name) - 1);*/ 03694 /* XXX Should we really check for uniqueness?? XXX */ 03695 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03696 strncpy(e->context, context, sizeof(e->context) - 1); 03697 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03698 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03699 strncpy(e->language, language, sizeof(e->language) - 1); 03700 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03701 strncpy(e->mailbox, mailbox, sizeof(e->mailbox) - 1); 03702 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03703 e->msgstate = -1; 03704 e->amaflags = amaflags; 03705 e->capability = capability; 03706 e->parent = gw; 03707 e->dtmfmode = dtmfmode; 03708 if (!ep_reload && e->sub && e->sub->rtp) 03709 e->dtmfmode |= MGCP_DTMF_INBAND; 03710 e->adsi = adsi; 03711 e->type = TYPE_LINE; 03712 e->immediate = immediate; 03713 e->callgroup=cur_callergroup; 03714 e->pickupgroup=cur_pickupgroup; 03715 e->callreturn = callreturn; 03716 e->cancallforward = cancallforward; 03717 e->singlepath = singlepath; 03718 e->canreinvite = canreinvite; 03719 e->callwaiting = callwaiting; 03720 e->hascallwaiting = callwaiting; 03721 e->slowsequence = slowsequence; 03722 e->transfer = transfer; 03723 e->threewaycalling = threewaycalling; 03724 e->onhooktime = time(NULL); 03725 /* ASSUME we're onhook */ 03726 e->hookstate = MGCP_ONHOOK; 03727 if (!ep_reload) { 03728 /*snprintf(txident, sizeof(txident), "%08x", rand());*/ 03729 for (i = 0; i < MAX_SUBS; i++) { 03730 sub = malloc(sizeof(struct mgcp_subchannel)); 03731 if (sub) { 03732 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03733 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03734 ast_mutex_init(&sub->lock); 03735 ast_mutex_init(&sub->cx_queue_lock); 03736 sub->parent = e; 03737 sub->id = i; 03738 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03739 /*stnrcpy(sub->txident, txident, sizeof(sub->txident) - 1);*/ 03740 sub->cxmode = MGCP_CX_INACTIVE; 03741 sub->nat = nat; 03742 sub->next = e->sub; 03743 e->sub = sub; 03744 } else { 03745 /* XXX Should find a way to clean up our memory */ 03746 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03747 return NULL; 03748 } 03749 } 03750 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03751 sub = e->sub; 03752 /* find the end of the list */ 03753 while(sub->next){ 03754 sub = sub->next; 03755 } 03756 /* set the last sub->next to the first sub */ 03757 sub->next = e->sub; 03758 03759 e->next = gw->endpoints; 03760 gw->endpoints = e; 03761 } 03762 } 03763 } else if (!strcasecmp(v->name, "trunk") || 03764 !strcasecmp(v->name, "line")) { 03765 03766 /* SC: locate existing endpoint */ 03767 e = gw->endpoints; 03768 while (e) { 03769 if (!strcasecmp(v->value, e->name)) { 03770 /* endpoint already exists */ 03771 e->delme = 0; 03772 ep_reload = 1; 03773 break; 03774 } 03775 e = e->next; 03776 } 03777 03778 if (!e) { 03779 e = malloc(sizeof(struct mgcp_endpoint)); 03780 ep_reload = 0; 03781 } 03782 03783 if (e) { 03784 if (!ep_reload) { 03785 memset(e, 0, sizeof(struct mgcp_endpoint)); 03786 ast_mutex_init(&e->lock); 03787 ast_mutex_init(&e->rqnt_queue_lock); 03788 ast_mutex_init(&e->cmd_queue_lock); 03789 strncpy(e->name, v->value, sizeof(e->name) - 1); 03790 e->needaudit = 1; 03791 } 03792 /* XXX Should we really check for uniqueness?? XXX */ 03793 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03794 strncpy(e->context, context, sizeof(e->context) - 1); 03795 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03796 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03797 strncpy(e->language, language, sizeof(e->language) - 1); 03798 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03799 strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1); 03800 if (!ast_strlen_zero(mailbox)) { 03801 ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name); 03802 } 03803 if (!ep_reload) { 03804 /* XXX SC: potential issue due to reload */ 03805 e->msgstate = -1; 03806 e->parent = gw; 03807 } 03808 e->amaflags = amaflags; 03809 e->capability = capability; 03810 e->dtmfmode = dtmfmode; 03811 e->adsi = adsi; 03812 if (!strcasecmp(v->name, "trunk")) 03813 e->type = TYPE_TRUNK; 03814 else 03815 e->type = TYPE_LINE; 03816 03817 e->immediate = immediate; 03818 e->callgroup=cur_callergroup; 03819 e->pickupgroup=cur_pickupgroup; 03820 e->callreturn = callreturn; 03821 e->cancallforward = cancallforward; 03822 e->canreinvite = canreinvite; 03823 e->singlepath = singlepath; 03824 e->callwaiting = callwaiting; 03825 e->hascallwaiting = callwaiting; 03826 e->slowsequence = slowsequence; 03827 e->transfer = transfer; 03828 e->threewaycalling = threewaycalling; 03829 if (!ep_reload) { 03830 e->onhooktime = time(NULL); 03831 /* ASSUME we're onhook */ 03832 e->hookstate = MGCP_ONHOOK; 03833 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03834 } 03835 03836 for (i = 0, sub = NULL; i < MAX_SUBS; i++) { 03837 if (!ep_reload) { 03838 sub = malloc(sizeof(struct mgcp_subchannel)); 03839 } else { 03840 if (!sub) 03841 sub = e->sub; 03842 else 03843 sub = sub->next; 03844 } 03845 03846 if (sub) { 03847 if (!ep_reload) { 03848 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03849 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03850 ast_mutex_init(&sub->lock); 03851 ast_mutex_init(&sub->cx_queue_lock); 03852 strncpy(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic) - 1); 03853 sub->parent = e; 03854 sub->id = i; 03855 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03856 sub->cxmode = MGCP_CX_INACTIVE; 03857 sub->next = e->sub; 03858 e->sub = sub; 03859 } 03860 sub->nat = nat; 03861 } else { 03862 /* XXX Should find a way to clean up our memory */ 03863 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03864 return NULL; 03865 } 03866 } 03867 if (!ep_reload) { 03868 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03869 sub = e->sub; 03870 /* find the end of the list */ 03871 while (sub->next) { 03872 sub = sub->next; 03873 } 03874 /* set the last sub->next to the first sub */ 03875 sub->next = e->sub; 03876 03877 e->next = gw->endpoints; 03878 gw->endpoints = e; 03879 } 03880 } 03881 } else 03882 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 03883 v = v->next; 03884 } 03885 } 03886 if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) { 03887 ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name); 03888 if (!gw_reload) { 03889 ast_mutex_destroy(&gw->msgs_lock); 03890 free(gw); 03891 } 03892 return NULL; 03893 } 03894 gw->defaddr.sin_family = AF_INET; 03895 gw->addr.sin_family = AF_INET; 03896 if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port)) 03897 gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03898 if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) 03899 gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03900 if (gw->addr.sin_addr.s_addr) 03901 if (ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip)) 03902 memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip)); 03903 03904 return (gw_reload ? NULL : gw); 03905 }
|
|
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 4380 of file chan_mgcp.c. References desc. 04381 { 04382 return (char *) desc; 04383 }
|
|
|
Definition at line 4014 of file chan_mgcp.c. References ast_free_ha(), dump_queue(), free, and mgcp_gateway::ha. Referenced by prune_gateways(). 04015 { 04016 if (g->ha) 04017 ast_free_ha(g->ha); 04018 04019 dump_queue(g, NULL); 04020 04021 free (g); 04022 }
|
|
Definition at line 3358 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(), gateways, has_voicemail(), mgcp_do_reload(), MGCP_ONHOOK, mgcp_reloading, mgcpsock, mgcpsock_read(), mgcpsock_read_id, option_verbose, transmit_notify_request(), TYPE_LINE, and VERBOSE_PREFIX_1. 03359 { 03360 int res; 03361 int reloading; 03362 /*struct mgcp_gateway *g;*/ 03363 /*struct mgcp_endpoint *e;*/ 03364 /*time_t thispass = 0, lastpass = 0;*/ 03365 03366 /* Add an I/O event to our UDP socket */ 03367 if (mgcpsock > -1) 03368 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03369 03370 /* This thread monitors all the frame relay interfaces which are not yet in use 03371 (and thus do not have a separate thread) indefinitely */ 03372 /* From here on out, we die whenever asked */ 03373 for(;;) { 03374 /* Check for a reload request */ 03375 ast_mutex_lock(&mgcp_reload_lock); 03376 reloading = mgcp_reloading; 03377 mgcp_reloading = 0; 03378 ast_mutex_unlock(&mgcp_reload_lock); 03379 if (reloading) { 03380 if (option_verbose > 0) 03381 ast_verbose(VERBOSE_PREFIX_1 "Reloading MGCP\n"); 03382 mgcp_do_reload(); 03383 /* Add an I/O event to our UDP socket */ 03384 if (mgcpsock > -1) 03385 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03386 } 03387 03388 /* Check for interfaces needing to be killed */ 03389 /* Don't let anybody kill us right away. Nobody should lock the interface list 03390 and wait for the monitor list, but the other way around is okay. */ 03391 ast_mutex_lock(&monlock); 03392 /* Lock the network interface */ 03393 ast_mutex_lock(&netlock); 03394 03395 #if 0 03396 /* XXX THIS IS COMPLETELY HOSED */ 03397 /* The gateway goes into a state of panic */ 03398 /* If the vmwi indicator is sent while it is reseting interfaces */ 03399 lastpass = thispass; 03400 thispass = time(NULL); 03401 g = gateways; 03402 while(g) { 03403 if (thispass != lastpass) { 03404 e = g->endpoints; 03405 while(e) { 03406 if (e->type == TYPE_LINE) { 03407 res = has_voicemail(e); 03408 if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){ 03409 if (res) { 03410 transmit_notify_request(e, "L/vmwi(+)"); 03411 } else { 03412 transmit_notify_request(e, "L/vmwi(-)"); 03413 } 03414 e->msgstate = res; 03415 e->onhooktime = thispass; 03416 } 03417 } 03418 e = e->next; 03419 } 03420 } 03421 g = g->next; 03422 } 03423 #endif 03424 /* Okay, now that we know what to do, release the network lock */ 03425 ast_mutex_unlock(&netlock); 03426 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 03427 ast_mutex_unlock(&monlock); 03428 pthread_testcancel(); 03429 /* Wait for sched or io */ 03430 res = ast_sched_wait(sched); 03431 /* SC: copied from chan_sip.c */ 03432 if ((res < 0) || (res > 1000)) 03433 res = 1000; 03434 res = ast_io_wait(io, res); 03435 ast_mutex_lock(&monlock); 03436 if (res >= 0) 03437 ast_sched_runq(sched); 03438 ast_mutex_unlock(&monlock); 03439 } 03440 /* Never reached */ 03441 return NULL; 03442 }
|
|
|
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_endpoint(), 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 3235 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(). 03236 { 03237 int seqno=0; 03238 time_t now; 03239 struct mgcp_response *prev = NULL, *cur, *next, *answer=NULL; 03240 time(&now); 03241 if (sscanf(req->identifier, "%d", &seqno) != 1) 03242 seqno = 0; 03243 cur = sub->parent->parent->responses; 03244 while(cur) { 03245 next = cur->next; 03246 if (now - cur->whensent > RESPONSE_TIMEOUT) { 03247 /* Delete this entry */ 03248 if (prev) 03249 prev->next = next; 03250 else 03251 sub->parent->parent->responses = next; 03252 free(cur); 03253 } else { 03254 if (seqno == cur->seqno) 03255 answer = cur; 03256 prev = cur; 03257 } 03258 cur = next; 03259 } 03260 if (answer) { 03261 resend_response(sub, answer); 03262 return 1; 03263 } 03264 return 0; 03265 }
|
|
Definition at line 2341 of file chan_mgcp.c. References mgcp_gateway::addr, ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), mgcp_postrequest(), mgcpdebug, mgcp_request::next, mgcp_endpoint::parent, and mgcp_request::trid. Referenced by agi_handle_command(), handle_response(), and handle_showagi(). 02343 { 02344 struct mgcp_request *prev, *req; 02345 char iabuf[INET_ADDRSTRLEN]; 02346 02347 ast_mutex_lock(l); 02348 for (prev = NULL, req = *queue; req; prev = req, req = req->next) { 02349 if (req->trid == ident) { 02350 /* remove from queue */ 02351 if (!prev) 02352 *queue = req->next; 02353 else 02354 prev->next = req->next; 02355 02356 /* send next pending command */ 02357 if (*queue) { 02358 if (mgcpdebug) { 02359 ast_verbose("Posting Queued Request:\n%s to %s:%d\n", (*queue)->data, 02360 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 02361 } 02362 02363 mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid); 02364 } 02365 break; 02366 } 02367 } 02368 ast_mutex_unlock(l); 02369 return req; 02370 }
|
|
Definition at line 1539 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(). 01540 { 01541 struct mgcp_endpoint *p = NULL; 01542 struct mgcp_subchannel *sub = NULL; 01543 struct mgcp_gateway *g; 01544 char iabuf[INET_ADDRSTRLEN]; 01545 char tmp[256] = ""; 01546 char *at = NULL, *c; 01547 int found = 0; 01548 if (name) { 01549 strncpy(tmp, name, sizeof(tmp) - 1); 01550 at = strchr(tmp, '@'); 01551 if (!at) { 01552 ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name); 01553 return NULL; 01554 } 01555 *at = '\0'; 01556 at++; 01557 } 01558 ast_mutex_lock(&gatelock); 01559 if (at && (at[0] == '[')) { 01560 at++; 01561 c = strrchr(at, ']'); 01562 if (c) 01563 *c = '\0'; 01564 } 01565 g = gateways; 01566 while(g) { 01567 if ((!name || !strcasecmp(g->name, at)) && 01568 (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) { 01569 /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */ 01570 if (sin && g->dynamic && name) { 01571 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01572 (g->addr.sin_port != sin->sin_port)) { 01573 memcpy(&g->addr, sin, sizeof(g->addr)); 01574 if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip)) 01575 memcpy(&g->ourip, &__ourip, sizeof(g->ourip)); 01576 if (option_verbose > 2) 01577 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)); 01578 } 01579 } 01580 /* SC: not dynamic, check if the name matches */ 01581 else if (name) { 01582 if (strcasecmp(g->name, at)) { 01583 g = g->next; 01584 continue; 01585 } 01586 } 01587 /* SC: not dynamic, no name, check if the addr matches */ 01588 else if (!name && sin) { 01589 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01590 (g->addr.sin_port != sin->sin_port)) { 01591 g = g->next; 01592 continue; 01593 } 01594 } else { 01595 g = g->next; 01596 continue; 01597 } 01598 /* SC */ 01599 p = g->endpoints; 01600 while(p) { 01601 if (option_debug) 01602 ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n", 01603 p->name, g->name); 01604 if (msgid) { 01605 #if 0 /* SC: new transport mech */ 01606 sub = p->sub; 01607 do { 01608 if (option_debug) 01609 ast_log(LOG_DEBUG, "Searching on %s@%s-%d for subchannel with lastout: %d\n", 01610 p->name, g->name, sub->id, msgid); 01611 if (sub->lastout == msgid) { 01612 if (option_debug) 01613 ast_log(LOG_DEBUG, "Found subchannel sub%d to handle request %d sub->lastout: %d\n", 01614 sub->id, msgid, sub->lastout); 01615 found = 1; 01616 break; 01617 } 01618 sub = sub->next; 01619 } while (sub != p->sub); 01620 if (found) { 01621 break; 01622 } 01623 #endif 01624 /* SC */ 01625 sub = p->sub; 01626 found = 1; 01627 /* SC */ 01628 break; 01629 } else if (name && !strcasecmp(p->name, tmp)) { 01630 ast_log(LOG_DEBUG, "Coundn't determine subchannel, assuming current master %s@%s-%d\n", 01631 p->name, g->name, p->sub->id); 01632 sub = p->sub; 01633 found = 1; 01634 break; 01635 } 01636 p = p->next; 01637 } 01638 if (sub && found) { 01639 ast_mutex_lock(&sub->lock); 01640 break; 01641 } 01642 } 01643 g = g->next; 01644 } 01645 ast_mutex_unlock(&gatelock); 01646 if (!sub) { 01647 if (name) { 01648 if (g) 01649 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at); 01650 else 01651 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp); 01652 } 01653 } 01654 return sub; 01655 }
|
|
Definition at line 1518 of file chan_mgcp.c. References s. Referenced by handle_response(). 01519 { 01520 char *s; 01521 01522 *next = NULL, *len = 0; 01523 if (!c) return NULL; 01524 01525 while (*c && (*c < 33 || *c == ',')) 01526 c++; 01527 01528 s = c; 01529 while (*c && (*c >= 33 && *c != ',')) 01530 c++, (*len)++; 01531 *next = c; 01532 01533 if (*len == 0) 01534 s = NULL, *next = NULL; 01535 01536 return s; 01537 }
|
|
Definition at line 1511 of file chan_mgcp.c. References __get_header(). Referenced by __transmit_response(), build_route(), 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(). 01512 { 01513 int start = 0; 01514 return __get_header(req, name, &start); 01515 }
|
|
Definition at line 1463 of file chan_mgcp.c. References get_sdp_by_line(), and mgcp_request::line. Referenced by process_sdp(). 01464 { 01465 int x; 01466 int len = strlen(name); 01467 char *r; 01468 01469 for (x=0; x<req->lines; x++) { 01470 r = get_sdp_by_line(req->line[x], name, len); 01471 if (r[0] != '\0') return r; 01472 } 01473 return ""; 01474 }
|
|
Definition at line 1453 of file chan_mgcp.c. Referenced by get_sdp(), and get_sdp_iterate(). 01454 { 01455 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 01456 char* r = line + nameLen + 1; 01457 while (*r && (*r < 33)) ++r; 01458 return r; 01459 } 01460 return ""; 01461 }
|
|
Definition at line 1481 of file chan_mgcp.c. References get_sdp_by_line(), and mgcp_request::line. Referenced by process_sdp(). 01482 { 01483 int len = strlen(name); 01484 char *r; 01485 while (*iterator < req->lines) { 01486 r = get_sdp_by_line(req->line[(*iterator)++], name, len); 01487 if (r[0] != '\0') return r; 01488 } 01489 return ""; 01490 }
|
|
Definition at line 2874 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(), t, transmit_modify_request(), and transmit_notify_request(). Referenced by handle_request(). 02875 { 02876 struct mgcp_endpoint *p = sub->parent; 02877 struct ast_channel *c; 02878 pthread_t t; 02879 pthread_attr_t attr; 02880 pthread_attr_init(&attr); 02881 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02882 02883 /* Off hook / answer */ 02884 if (sub->outgoing) { 02885 /* Answered */ 02886 if (sub->owner) { 02887 if (ast_bridged_channel(sub->owner)) { 02888 ast_moh_stop(ast_bridged_channel(sub->owner)); 02889 } 02890 sub->cxmode = MGCP_CX_SENDRECV; 02891 if (!sub->rtp) { 02892 start_rtp(sub); 02893 } else { 02894 transmit_modify_request(sub); 02895 } 02896 /*transmit_notify_request(sub, "aw");*/ 02897 transmit_notify_request(sub, ""); 02898 mgcp_queue_control(sub, AST_CONTROL_ANSWER); 02899 } 02900 } else { 02901 /* Start switch */ 02902 /*sub->cxmode = MGCP_CX_SENDRECV;*/ 02903 if (!sub->owner) { 02904 if (!sub->rtp) { 02905 start_rtp(sub); 02906 } else { 02907 transmit_modify_request(sub); 02908 } 02909 if (p->immediate) { 02910 /* The channel is immediately up. Start right away */ 02911 #ifdef DLINK_BUGGY_FIRMWARE 02912 transmit_notify_request(sub, "rt"); 02913 #else 02914 transmit_notify_request(sub, "G/rt"); 02915 #endif 02916 c = mgcp_new(sub, AST_STATE_RING); 02917 if (!c) { 02918 ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name); 02919 transmit_notify_request(sub, "G/cg"); 02920 ast_hangup(c); 02921 } 02922 } else { 02923 if (has_voicemail(p)) { 02924 transmit_notify_request(sub, "L/sl"); 02925 } else { 02926 transmit_notify_request(sub, "L/dl"); 02927 } 02928 c = mgcp_new(sub, AST_STATE_DOWN); 02929 if (c) { 02930 if (ast_pthread_create(&t, &attr, mgcp_ss, c)) { 02931 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 02932 ast_hangup(c); 02933 } 02934 } else { 02935 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name); 02936 } 02937 } 02938 } else { 02939 if (p->hookstate == MGCP_OFFHOOK) { 02940 ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02941 } else { 02942 ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02943 ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?"); 02944 } 02945 if (ast_bridged_channel(sub->owner)) { 02946 ast_moh_stop(ast_bridged_channel(sub->owner)); 02947 } 02948 sub->cxmode = MGCP_CX_SENDRECV; 02949 if (!sub->rtp) { 02950 start_rtp(sub); 02951 } else { 02952 transmit_modify_request(sub); 02953 } 02954 /*transmit_notify_request(sub, "aw");*/ 02955 transmit_notify_request(sub, ""); 02956 /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/ 02957 } 02958 } 02959 }
|
|
Definition at line 2961 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(), mgcpdebug, 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(). 02962 { 02963 char *ev, *s; 02964 struct ast_frame f = { 0, }; 02965 struct mgcp_endpoint *p = sub->parent; 02966 struct mgcp_gateway *g = NULL; 02967 char iabuf[INET_ADDRSTRLEN]; 02968 int res; 02969 02970 if (mgcpdebug) { 02971 ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name); 02972 } 02973 /* Clear out potential response */ 02974 if (!strcasecmp(req->verb, "RSIP")) { 02975 /* Test if this RSIP request is just a keepalive */ 02976 if(!strcasecmp( get_header(req, "RM"), "X-keepalive")) { 02977 if (option_verbose > 2) 02978 ast_verbose(VERBOSE_PREFIX_3 "Received keepalive request from %s@%s\n", p->name, p->parent->name); 02979 transmit_response(sub, "200", req, "OK"); 02980 } else { 02981 dump_queue(p->parent, p); 02982 dump_cmd_queues(p, NULL); 02983 02984 if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) { 02985 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); 02986 } 02987 /* JS: For RSIP on wildcard we reset all endpoints */ 02988 if (!strcmp(p->name, p->parent->wcardep)) { 02989 /* Reset all endpoints */ 02990 struct mgcp_endpoint *tmp_ep; 02991 02992 g = p->parent; 02993 tmp_ep = g->endpoints; 02994 while (tmp_ep) { 02995 /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/ 02996 if (strcmp(tmp_ep->name, g->wcardep) != 0) { 02997 struct mgcp_subchannel *tmp_sub, *first_sub; 02998 if (option_verbose > 2) { 02999 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name); 03000 } 03001 03002 first_sub = tmp_ep->sub; 03003 tmp_sub = tmp_ep->sub; 03004 while (tmp_sub) { 03005 mgcp_queue_hangup(tmp_sub); 03006 tmp_sub = tmp_sub->next; 03007 if (tmp_sub == first_sub) 03008 break; 03009 } 03010 } 03011 tmp_ep = tmp_ep->next; 03012 } 03013 } else if (sub->owner) { 03014 mgcp_queue_hangup(sub); 03015 } 03016 transmit_response(sub, "200", req, "OK"); 03017 /* JS: We dont send NTFY or AUEP to wildcard ep */ 03018 if (strcmp(p->name, p->parent->wcardep) != 0) { 03019 transmit_notify_request(sub, ""); 03020 /* SC: Audit endpoint. 03021 Idea is to prevent lost lines due to race conditions 03022 */ 03023 transmit_audit_endpoint(p); 03024 } 03025 } 03026 } else if (!strcasecmp(req->verb, "NTFY")) { 03027 /* Acknowledge and be sure we keep looking for the same things */ 03028 transmit_response(sub, "200", req, "OK"); 03029 /* Notified of an event */ 03030 ev = get_header(req, "O"); 03031 s = strchr(ev, '/'); 03032 if (s) ev = s + 1; 03033 ast_log(LOG_DEBUG, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev); 03034 /* Keep looking for events unless this was a hangup */ 03035 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) { 03036 transmit_notify_request(sub, p->curtone); 03037 } 03038 if (!strcasecmp(ev, "hd")) { 03039 p->hookstate = MGCP_OFFHOOK; 03040 sub->cxmode = MGCP_CX_SENDRECV; 03041 handle_hd_hf(sub, ev); 03042 } else if (!strcasecmp(ev, "hf")) { 03043 /* We can assume we are offhook if we received a hookflash */ 03044 /* First let's just do call wait and ignore threeway */ 03045 /* We're currently in charge */ 03046 if (p->hookstate != MGCP_OFFHOOK) { 03047 /* Cisco c7940 sends hf even if the phone is onhook */ 03048 /* Thanks to point on IRC for pointing this out */ 03049 return -1; 03050 } 03051 /* do not let * conference two down channels */ 03052 if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) 03053 return -1; 03054 03055 if (p->callwaiting || p->transfer || p->threewaycalling) { 03056 if (option_verbose > 2) { 03057 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); 03058 } 03059 p->sub = p->sub->next; 03060 03061 /* transfer control to our next subchannel */ 03062 if (!sub->next->owner) { 03063 /* plave the first call on hold and start up a new call */ 03064 sub->cxmode = MGCP_CX_MUTE; 03065 if (option_verbose > 2) { 03066 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03067 } 03068 transmit_modify_request(sub); 03069 if (sub->owner && ast_bridged_channel(sub->owner)) { 03070 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03071 } 03072 sub->next->cxmode = MGCP_CX_RECVONLY; 03073 handle_hd_hf(sub->next, ev); 03074 } else if (sub->owner && sub->next->owner) { 03075 /* We've got two active calls lets decide whether or not to conference or just flip flop */ 03076 if ((!sub->outgoing) && (!sub->next->outgoing)) { 03077 /* We made both calls lets conferenct */ 03078 if (option_verbose > 2) { 03079 ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", 03080 sub->id, sub->next->id, p->name, p->parent->name); 03081 } 03082 sub->cxmode = MGCP_CX_CONF; 03083 sub->next->cxmode = MGCP_CX_CONF; 03084 if (ast_bridged_channel(sub->next->owner)) 03085 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03086 transmit_modify_request(sub); 03087 transmit_modify_request(sub->next); 03088 } else { 03089 /* Let's flipflop between calls */ 03090 /* XXX Need to check for state up ??? */ 03091 /* XXX Need a way to indicate the current call, or maybe the call that's waiting */ 03092 if (option_verbose > 2) { 03093 ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", 03094 sub->id, sub->next->id, p->name, p->parent->name); 03095 } 03096 sub->cxmode = MGCP_CX_MUTE; 03097 if (option_verbose > 2) { 03098 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03099 } 03100 transmit_modify_request(sub); 03101 if (ast_bridged_channel(sub->owner)) 03102 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03103 03104 if (ast_bridged_channel(sub->next->owner)) 03105 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03106 03107 handle_hd_hf(sub->next, ev); 03108 #if 0 03109 if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { 03110 handle_hd_hf(sub->next, ev); 03111 } else { 03112 ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); 03113 sub->next->cxmode = MGCP_CX_SENDRECV; 03114 transmit_modify_request(sub->next); 03115 } 03116 #endif 03117 } 03118 } else { 03119 /* We've most likely lost one of our calls find an active call and bring it up */ 03120 if (sub->owner) { 03121 p->sub = sub; 03122 } else if (sub->next->owner) { 03123 p->sub = sub->next; 03124 } else { 03125 /* We seem to have lost both our calls */ 03126 /* XXX - What do we do now? */ 03127 return -1; 03128 } 03129 if (ast_bridged_channel(p->sub->owner)) { 03130 ast_moh_stop(ast_bridged_channel(p->sub->owner)); 03131 } 03132 p->sub->cxmode = MGCP_CX_SENDRECV; 03133 transmit_modify_request(p->sub); 03134 } 03135 } else { 03136 ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", 03137 p->name, p->parent->name); 03138 } 03139 /*ast_moh_stop(sub->owner->bridge);*/ 03140 } else if (!strcasecmp(ev, "hu")) { 03141 p->hookstate = MGCP_ONHOOK; 03142 sub->cxmode = MGCP_CX_RECVONLY; 03143 ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); 03144 /* JS: Do we need to send MDCX before a DLCX ? 03145 if (sub->rtp) { 03146 transmit_modify_request(sub); 03147 } 03148 */ 03149 if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { 03150 /* We're allowed to transfer, we have two avtive calls and */ 03151 /* we made at least one of the calls. Let's try and transfer */ 03152 ast_mutex_lock(&p->sub->next->lock); 03153 res = attempt_transfer(p); 03154 if (res < 0) { 03155 if (p->sub->next->owner) { 03156 sub->next->alreadygone = 1; 03157 mgcp_queue_hangup(sub->next); 03158 } 03159 } else if (res) { 03160 ast_log(LOG_WARNING, "Transfer attempt failed\n"); 03161 ast_mutex_unlock(&p->sub->next->lock); 03162 return -1; 03163 } 03164 ast_mutex_unlock(&p->sub->next->lock); 03165 } else { 03166 /* Hangup the current call */ 03167 /* If there is another active call, mgcp_hangup will ring the phone with the other call */ 03168 if (sub->owner) { 03169 sub->alreadygone = 1; 03170 mgcp_queue_hangup(sub); 03171 } else { 03172 /* SC: verbose level check */ 03173 if (option_verbose > 2) { 03174 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n", 03175 p->name, p->parent->name, sub->id); 03176 } 03177 /* Instruct the other side to remove the connection since it apparently * 03178 * still thinks the channel is active. * 03179 * For Cisco IAD2421 /BAK/ */ 03180 transmit_connection_del(sub); 03181 } 03182 } 03183 if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) { 03184 p->hidecallerid = 0; 03185 if (p->hascallwaiting && !p->callwaiting) { 03186 if (option_verbose > 2) 03187 ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id); 03188 p->callwaiting = -1; 03189 } 03190 if (has_voicemail(p)) { 03191 if (option_verbose > 2) { 03192 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name); 03193 } 03194 transmit_notify_request(sub, "L/vmwi(+)"); 03195 } else { 03196 if (option_verbose > 2) { 03197 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name); 03198 } 03199 transmit_notify_request(sub, "L/vmwi(-)"); 03200 } 03201 } 03202 } else if ((strlen(ev) == 1) && 03203 (((ev[0] >= '0') && (ev[0] <= '9')) || 03204 ((ev[0] >= 'A') && (ev[0] <= 'D')) || 03205 (ev[0] == '*') || (ev[0] == '#'))) { 03206 f.frametype = AST_FRAME_DTMF; 03207 f.subclass = ev[0]; 03208 f.src = "mgcp"; 03209 if (sub->owner) { 03210 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ 03211 mgcp_queue_frame(sub, &f); 03212 ast_mutex_lock(&sub->next->lock); 03213 if (sub->next->owner) { 03214 mgcp_queue_frame(sub->next, &f); 03215 } 03216 ast_mutex_unlock(&sub->next->lock); 03217 } 03218 if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { 03219 memset(p->curtone, 0, sizeof(p->curtone)); 03220 } 03221 } else if (!strcasecmp(ev, "T")) { 03222 /* Digit timeout -- unimportant */ 03223 } else if (!strcasecmp(ev, "ping")) { 03224 /* ping -- unimportant */ 03225 } else { 03226 ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name); 03227 } 03228 } else { 03229 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 03230 transmit_response(sub, "510", req, "Unknown verb"); 03231 } 03232 return 0; 03233 }
|
|
Definition at line 2373 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_subchannel::id, mgcp_request::lines, LOG_NOTICE, LOG_WARNING, MGCP_CMD_AUEP, MGCP_CMD_CRCX, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_queue_hangup(), n, mgcp_gateway::name, option_verbose, mgcp_subchannel::owner, mgcp_endpoint::parent, process_sdp(), mgcp_subchannel::rtp, mgcp_endpoint::slowsequence, start_rtp(), 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(). 02375 { 02376 char *c; 02377 struct mgcp_request *req; 02378 struct mgcp_gateway *gw = p->parent; 02379 02380 if (result < 200) { 02381 /* provisional response */ 02382 return; 02383 } 02384 02385 if (p->slowsequence) 02386 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02387 else if (sub) 02388 req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident); 02389 else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident))) 02390 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02391 02392 if (!req) { 02393 if (option_verbose > 2) { 02394 ast_verbose(VERBOSE_PREFIX_3 "No command found on [%s] for transaction %d. Ignoring...\n", 02395 gw->name, ident); 02396 } 02397 return; 02398 } 02399 02400 if (p && (result >= 400) && (result <= 599)) { 02401 switch (result) { 02402 case 401: 02403 p->hookstate = MGCP_OFFHOOK; 02404 break; 02405 case 402: 02406 p->hookstate = MGCP_ONHOOK; 02407 break; 02408 case 406: 02409 ast_log(LOG_NOTICE, "Transaction %d timed out\n", ident); 02410 break; 02411 case 407: 02412 ast_log(LOG_NOTICE, "Transaction %d aborted\n", ident); 02413 break; 02414 } 02415 if (sub) { 02416 if (sub->owner) { 02417 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02418 result, p->name, p->parent->name, sub ? sub->id:-1); 02419 mgcp_queue_hangup(sub); 02420 } 02421 } else { 02422 if (p->sub->next->owner) { 02423 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02424 result, p->name, p->parent->name, sub ? sub->id:-1); 02425 mgcp_queue_hangup(p->sub); 02426 } 02427 02428 if (p->sub->owner) { 02429 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02430 result, p->name, p->parent->name, sub ? sub->id:-1); 02431 mgcp_queue_hangup(p->sub); 02432 } 02433 02434 dump_cmd_queues(p, NULL); 02435 } 02436 } 02437 02438 if (resp) { 02439 if (req->cmd == MGCP_CMD_CRCX) { 02440 if ((c = get_header(resp, "I"))) { 02441 if (!ast_strlen_zero(c) && sub) { 02442 /* SC: if we are hanging up do not process this conn. */ 02443 if (sub->owner) { 02444 if (!ast_strlen_zero(sub->cxident)) { 02445 if (strcasecmp(c, sub->cxident)) { 02446 ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c); 02447 } 02448 } 02449 strncpy(sub->cxident, c, sizeof(sub->cxident) - 1); 02450 if (sub->tmpdest.sin_addr.s_addr) { 02451 transmit_modify_with_sdp(sub, NULL, 0); 02452 } 02453 } else { 02454 /* XXX SC: delete this one 02455 callid and conn id may already be lost. 02456 so the following del conn may have a side effect of 02457 cleaning up the next subchannel */ 02458 transmit_connection_del(sub); 02459 } 02460 } 02461 } 02462 } 02463 02464 if (req->cmd == MGCP_CMD_AUEP) { 02465 /* SC: check stale connection ids */ 02466 if ((c = get_header(resp, "I"))) { 02467 char *v, *n; 02468 int len; 02469 while ((v = get_csv(c, &len, &n))) { 02470 if (len) { 02471 if (strncasecmp(v, p->sub->cxident, len) && 02472 strncasecmp(v, p->sub->next->cxident, len)) { 02473 /* connection id not found. delete it */ 02474 char cxident[80]; 02475 memcpy(cxident, v, len); 02476 cxident[len] = '\0'; 02477 if (option_verbose > 2) { 02478 ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n", 02479 cxident, p->name, gw->name); 02480 } 02481 transmit_connection_del_w_params(p, NULL, cxident); 02482 } 02483 } 02484 c = n; 02485 } 02486 } 02487 02488 /* Try to determine the hookstate returned from an audit endpoint command */ 02489 if ((c = get_header(resp, "ES"))) { 02490 if (!ast_strlen_zero(c)) { 02491 if (strstr(c, "hu")) { 02492 if (p->hookstate != MGCP_ONHOOK) { 02493 /* SC: XXX cleanup if we think we are offhook XXX */ 02494 if ((p->sub->owner || p->sub->next->owner ) && 02495 p->hookstate == MGCP_OFFHOOK) 02496 mgcp_queue_hangup(sub); 02497 p->hookstate = MGCP_ONHOOK; 02498 02499 /* SC: update the requested events according to the new hookstate */ 02500 transmit_notify_request(p->sub, ""); 02501 02502 /* SC: verbose level check */ 02503 if (option_verbose > 2) { 02504 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name); 02505 } 02506 } 02507 } else if (strstr(c, "hd")) { 02508 if (p->hookstate != MGCP_OFFHOOK) { 02509 p->hookstate = MGCP_OFFHOOK; 02510 02511 /* SC: update the requested events according to the new hookstate */ 02512 transmit_notify_request(p->sub, ""); 02513 02514 /* SC: verbose level check */ 02515 if (option_verbose > 2) { 02516 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name); 02517 } 02518 } 02519 } 02520 } 02521 } 02522 } 02523 02524 if (resp && resp->lines) { 02525 /* SC: do not process sdp if we are hanging up. this may be a late response */ 02526 if (sub && sub->owner) { 02527 if (!sub->rtp) 02528 start_rtp(sub); 02529 if (sub->rtp) 02530 process_sdp(sub, resp); 02531 } 02532 } 02533 } 02534 02535 free(req); 02536 }
|
|
Definition at line 517 of file chan_mgcp.c. References ast_app_has_voicemail(), and mgcp_endpoint::mailbox. Referenced by do_housekeeping(), do_monitor(), forward_message(), 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 1906 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 initreqprep(), reqprep(), and transmit_register(). 01907 { 01908 /* Initialize a response */ 01909 if (req->headers || req->len) { 01910 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01911 return -1; 01912 } 01913 req->header[req->headers] = req->data + req->len; 01914 /* SC: check if we need brackets around the gw name */ 01915 if (p->parent->isnamedottedip) 01916 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); 01917 else 01918 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); 01919 req->len += strlen(req->header[req->headers]); 01920 if (req->headers < MGCP_MAX_HEADERS) 01921 req->headers++; 01922 else 01923 ast_log(LOG_WARNING, "Out of header space\n"); 01924 return 0; 01925 }
|
|
Definition at line 1889 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(). 01890 { 01891 /* Initialize a response */ 01892 if (req->headers || req->len) { 01893 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01894 return -1; 01895 } 01896 req->header[req->headers] = req->data + req->len; 01897 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest); 01898 req->len += strlen(req->header[req->headers]); 01899 if (req->headers < MGCP_MAX_HEADERS) 01900 req->headers++; 01901 else 01902 ast_log(LOG_WARNING, "Out of header space\n"); 01903 return 0; 01904 }
|
|
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 4375 of file chan_mgcp.c. References ASTERISK_GPL_KEY. 04376 { 04377 return ASTERISK_GPL_KEY; 04378 }
|
|
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 4239 of file chan_mgcp.c. References ast_channel_register(), ast_cli_register(), ast_log(), ast_rtp_proto_register(), io_context_create(), LOG_ERROR, LOG_WARNING, reload_config(), restart_monitor(), sched_context_create(), and type. 04240 { 04241 int res; 04242 04243 sched = sched_context_create(); 04244 if (!sched) { 04245 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 04246 return -1; 04247 } 04248 io = io_context_create(); 04249 if (!io) { 04250 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 04251 return -1; 04252 } 04253 04254 if (!(res = reload_config())) { 04255 /* Make sure we can register our mgcp channel type */ 04256 if (ast_channel_register(&mgcp_tech)) { 04257 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 04258 return -1; 04259 } 04260 ast_rtp_proto_register(&mgcp_rtp); 04261 ast_cli_register(&cli_show_endpoints); 04262 ast_cli_register(&cli_audit_endpoint); 04263 ast_cli_register(&cli_debug); 04264 ast_cli_register(&cli_no_debug); 04265 ast_cli_register(&cli_mgcp_reload); 04266 04267 /* And start the monitor for the first time */ 04268 restart_monitor(); 04269 } 04270 04271 return res; 04272 }
|
|
|
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 3934 of file chan_mgcp.c. References ast_cli(), mgcpdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 03935 { 03936 if (argc != 2) 03937 return RESULT_SHOWUSAGE; 03938 mgcpdebug = 1; 03939 ast_cli(fd, "MGCP Debugging Enabled\n"); 03940 return RESULT_SUCCESS; 03941 }
|
|
Definition at line 4274 of file chan_mgcp.c. References reload_config(). Referenced by do_monitor(). 04275 { 04276 reload_config(); 04277 return 0; 04278 }
|
|
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 3907 of file chan_mgcp.c. References mgcp_endpoint::canreinvite, mgcp_subchannel::parent, and mgcp_subchannel::rtp. 03908 { 03909 struct mgcp_subchannel *sub; 03910 sub = chan->tech_pvt; 03911 if (sub && sub->rtp && sub->parent->canreinvite) 03912 return sub->rtp; 03913 return NULL; 03914 }
|
|
Definition at line 979 of file chan_mgcp.c. References mgcp_subchannel::alreadygone, ast_bridged_channel(), ast_dsp_free(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_strlen_zero(), ast_update_use_count(), ast_verbose(), mgcp_subchannel::callid, mgcp_endpoint::callwaiting, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, mgcp_endpoint::dsp, mgcp_endpoint::dtmfmode, has_voicemail(), mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, mgcp_endpoint::hookstate, mgcp_subchannel::lock, LOG_DEBUG, mgcp_subchannel::magic, MGCP_CX_INACTIVE, MGCP_CX_RECVONLY, MGCP_DTMF_HYBRID, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, MGCP_SUBCHANNEL_MAGIC, mgcpdebug, mgcp_gateway::name, mgcp_endpoint::name, ast_channel::name, mgcp_subchannel::next, option_debug, option_verbose, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, mgcp_endpoint::sub, ast_channel::tech_pvt, mgcp_subchannel::tmpdest, transmit_connection_del(), transmit_modify_request(), transmit_notify_request(), transmit_notify_request_with_callerid(), usecnt, usecnt_lock, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3. 00980 { 00981 struct mgcp_subchannel *sub = ast->tech_pvt; 00982 struct mgcp_endpoint *p = sub->parent; 00983 00984 if (option_debug) { 00985 ast_log(LOG_DEBUG, "mgcp_hangup(%s)\n", ast->name); 00986 } 00987 if (!ast->tech_pvt) { 00988 ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); 00989 return 0; 00990 } 00991 if (strcmp(sub->magic, MGCP_SUBCHANNEL_MAGIC)) { 00992 ast_log(LOG_DEBUG, "Invalid magic. MGCP subchannel freed up already.\n"); 00993 return 0; 00994 } 00995 ast_mutex_lock(&sub->lock); 00996 if (mgcpdebug) { 00997 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s\n", ast->name, p->name, p->parent->name); 00998 } 00999 01000 if ((p->dtmfmode & MGCP_DTMF_INBAND) && p->dsp) { 01001 /* SC: check whether other channel is active. */ 01002 if (!sub->next->owner) { 01003 if (p->dtmfmode & MGCP_DTMF_HYBRID) 01004 p->dtmfmode &= ~MGCP_DTMF_INBAND; 01005 if (mgcpdebug) { 01006 ast_verbose(VERBOSE_PREFIX_2 "MGCP free dsp on %s@%s\n", p->name, p->parent->name); 01007 } 01008 ast_dsp_free(p->dsp); 01009 p->dsp = NULL; 01010 } 01011 } 01012 01013 sub->owner = NULL; 01014 if (!ast_strlen_zero(sub->cxident)) { 01015 transmit_connection_del(sub); 01016 } 01017 sub->cxident[0] = '\0'; 01018 if ((sub == p->sub) && sub->next->owner) { 01019 if (p->hookstate == MGCP_OFFHOOK) { 01020 if (sub->next->owner && ast_bridged_channel(sub->next->owner)) { 01021 transmit_notify_request_with_callerid(p->sub, "L/wt", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name); 01022 } 01023 } else { 01024 /* set our other connection as the primary and swith over to it */ 01025 p->sub = sub->next; 01026 p->sub->cxmode = MGCP_CX_RECVONLY; 01027 transmit_modify_request(p->sub); 01028 if (sub->next->owner && ast_bridged_channel(sub->next->owner)) { 01029 transmit_notify_request_with_callerid(p->sub, "L/rg", ast_bridged_channel(sub->next->owner)->cid.cid_num, ast_bridged_channel(sub->next->owner)->cid.cid_name); 01030 } 01031 } 01032 01033 } else if ((sub == p->sub->next) && p->hookstate == MGCP_OFFHOOK) { 01034 transmit_notify_request(sub, "L/v"); 01035 } else if (p->hookstate == MGCP_OFFHOOK) { 01036 transmit_notify_request(sub, "L/ro"); 01037 } else { 01038 transmit_notify_request(sub, ""); 01039 } 01040 01041 ast->tech_pvt = NULL; 01042 sub->alreadygone = 0; 01043 sub->outgoing = 0; 01044 sub->cxmode = MGCP_CX_INACTIVE; 01045 sub->callid[0] = '\0'; 01046 /* Reset temporary destination */ 01047 memset(&sub->tmpdest, 0, sizeof(sub->tmpdest)); 01048 if (sub->rtp) { 01049 ast_rtp_destroy(sub->rtp); 01050 sub->rtp = NULL; 01051 } 01052 01053 /* SC: Decrement use count */ 01054 ast_mutex_lock(&usecnt_lock); 01055 usecnt--; 01056 ast_mutex_unlock(&usecnt_lock); 01057 ast_update_use_count(); 01058 /* SC: Decrement use count */ 01059 01060 if ((p->hookstate == MGCP_ONHOOK) && (!sub->next->rtp)) { 01061 p->hidecallerid = 0; 01062 if (p->hascallwaiting && !p->callwaiting) { 01063 if (option_verbose > 2) 01064 ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on %s\n", ast->name); 01065 p->callwaiting = -1; 01066 } 01067 if (has_voicemail(p)) { 01068 if (mgcpdebug) { 01069 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(+)\n", 01070 ast->name, p->name, p->parent->name); 01071 } 01072 transmit_notify_request(sub, "L/vmwi(+)"); 01073 } else { 01074 if (mgcpdebug) { 01075 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_hangup(%s) on %s@%s set vmwi(-)\n", 01076 ast->name, p->name, p->parent->name); 01077 } 01078 transmit_notify_request(sub, "L/vmwi(-)"); 01079 } 01080 } 01081 ast_mutex_unlock(&sub->lock); 01082 return 0; 01083 }
|
|
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, 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 3943 of file chan_mgcp.c. References ast_cli(), mgcpdebug, RESULT_SHOWUSAGE, and RESULT_SUCCESS. 03944 { 03945 if (argc != 3) 03946 return RESULT_SHOWUSAGE; 03947 mgcpdebug = 0; 03948 ast_cli(fd, "MGCP Debugging Disabled\n"); 03949 return RESULT_SUCCESS; 03950 }
|
|
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 find_command(), and 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_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), mgcp_subchannel::lock, 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_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), mgcp_subchannel::lock, ast_channel::lock, and mgcp_subchannel::owner. Referenced by attempt_transfer(), destroy_endpoint(), 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 4280 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(). 04281 { 04282 ast_mutex_lock(&mgcp_reload_lock); 04283 if (mgcp_reloading) { 04284 ast_verbose("Previous mgcp reload not yet done\n"); 04285 } else 04286 mgcp_reloading = 1; 04287 ast_mutex_unlock(&mgcp_reload_lock); 04288 restart_monitor(); 04289 return 0; 04290 }
|
|
Definition at line 3473 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. 03474 { 03475 int oldformat; 03476 struct mgcp_subchannel *sub; 03477 struct ast_channel *tmpc = NULL; 03478 char tmp[256]; 03479 char *dest = data; 03480 03481 oldformat = format; 03482 format &= capability; 03483 if (!format) { 03484 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 03485 return NULL; 03486 } 03487 strncpy(tmp, dest, sizeof(tmp) - 1); 03488 if (ast_strlen_zero(tmp)) { 03489 ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n"); 03490 return NULL; 03491 } 03492 sub = find_subchannel_and_lock(tmp, 0, NULL); 03493 if (!sub) { 03494 ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp); 03495 *cause = AST_CAUSE_UNREGISTERED; 03496 return NULL; 03497 } 03498 03499 if (option_verbose > 2) { 03500 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp); 03501 ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n", 03502 sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); 03503 } 03504 /* Must be busy */ 03505 if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) || 03506 ((!sub->parent->callwaiting) && (sub->owner)) || 03507 (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) { 03508 if (sub->parent->hookstate == MGCP_ONHOOK) { 03509 if (has_voicemail(sub->parent)) { 03510 transmit_notify_request(sub,"L/vmwi(+)"); 03511 } else { 03512 transmit_notify_request(sub,"L/vmwi(-)"); 03513 } 03514 } 03515 *cause = AST_CAUSE_BUSY; 03516 ast_mutex_unlock(&sub->lock); 03517 return NULL; 03518 } 03519 tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); 03520 ast_mutex_unlock(&sub->lock); 03521 if (!tmpc) 03522 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 03523 restart_monitor(); 03524 return tmpc; 03525 }
|
|
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 3916 of file chan_mgcp.c. References ast_channel::tech_pvt, and transmit_modify_with_sdp(). 03917 { 03918 /* XXX Is there such thing as video support with MGCP? XXX */ 03919 struct mgcp_subchannel *sub; 03920 sub = chan->tech_pvt; 03921 if (sub) { 03922 transmit_modify_with_sdp(sub, rtp, codecs); 03923 return 0; 03924 } 03925 return -1; 03926 }
|
|
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 2563 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, ast_callerid::cid_ani, 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, ast_channel::rings, start_rtp(), ast_channel::tech_pvt, transmit_notify_request(), and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(). 02564 { 02565 struct ast_channel *chan = data; 02566 struct mgcp_subchannel *sub = chan->tech_pvt; 02567 struct mgcp_endpoint *p = sub->parent; 02568 char exten[AST_MAX_EXTENSION] = ""; 02569 int len = 0; 02570 int timeout = firstdigittimeout; 02571 int res; 02572 int getforward = 0; 02573 02574 while(len < AST_MAX_EXTENSION-1) { 02575 res = ast_waitfordigit(chan, timeout); 02576 timeout = 0; 02577 if (res < 0) { 02578 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 02579 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02580 ast_indicate(chan, -1); 02581 ast_hangup(chan); 02582 return NULL; 02583 } else if (res) { 02584 exten[len++]=res; 02585 exten[len] = '\0'; 02586 } 02587 if (!ast_ignore_pattern(chan->context, exten)) { 02588 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02589 ast_indicate(chan, -1); 02590 } else { 02591 /* XXX Redundant? We should already be playing dialtone */ 02592 /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02593 transmit_notify_request(sub, "L/dl"); 02594 } 02595 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 02596 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 02597 if (getforward) { 02598 /* Record this as the forwarding extension */ 02599 strncpy(p->call_forward, exten, sizeof(p->call_forward) - 1); 02600 if (option_verbose > 2) { 02601 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n", 02602 p->call_forward, chan->name); 02603 } 02604 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02605 transmit_notify_request(sub, "L/sl"); 02606 if (res) 02607 break; 02608 usleep(500000); 02609 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02610 ast_indicate(chan, -1); 02611 sleep(1); 02612 memset(exten, 0, sizeof(exten)); 02613 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02614 transmit_notify_request(sub, "L/dl"); 02615 len = 0; 02616 getforward = 0; 02617 } else { 02618 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02619 ast_indicate(chan, -1); 02620 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 02621 ast_set_callerid(chan, 02622 p->hidecallerid ? "" : p->cid_num, 02623 p->hidecallerid ? "" : p->cid_name, 02624 chan->cid.cid_ani ? NULL : p->cid_num); 02625 ast_setstate(chan, AST_STATE_RING); 02626 /*zt_enable_ec(p);*/ 02627 if (p->dtmfmode & MGCP_DTMF_HYBRID) { 02628 p->dtmfmode |= MGCP_DTMF_INBAND; 02629 ast_indicate(chan, -1); 02630 } 02631 res = ast_pbx_run(chan); 02632 if (res) { 02633 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 02634 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02635 /*transmit_notify_request(p, "nbz", 1);*/ 02636 transmit_notify_request(sub, "G/cg"); 02637 } 02638 return NULL; 02639 } 02640 } else { 02641 /* It's a match, but they just typed a digit, and there is an ambiguous match, 02642 so just set the timeout to matchdigittimeout and wait some more */ 02643 timeout = matchdigittimeout; 02644 } 02645 } else if (res == 0) { 02646 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 02647 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02648 transmit_notify_request(sub, "G/cg"); 02649 /*zt_wait_event(p->subs[index].zfd);*/ 02650 ast_hangup(chan); 02651 return NULL; 02652 } else if (p->hascallwaiting && p->callwaiting && !strcmp(exten, "*70")) { 02653 if (option_verbose > 2) { 02654 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 02655 } 02656 /* Disable call waiting if enabled */ 02657 p->callwaiting = 0; 02658 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02659 transmit_notify_request(sub, "L/sl"); 02660 len = 0; 02661 memset(exten, 0, sizeof(exten)); 02662 timeout = firstdigittimeout; 02663 } else if (!strcmp(exten,ast_pickup_ext())) { 02664 /* Scan all channels and see if any there 02665 * ringing channqels with that have call groups 02666 * that equal this channels pickup group 02667 */ 02668 if (ast_pickup_call(chan)) { 02669 ast_log(LOG_WARNING, "No call pickup possible...\n"); 02670 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02671 transmit_notify_request(sub, "G/cg"); 02672 } 02673 ast_hangup(chan); 02674 return NULL; 02675 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 02676 if (option_verbose > 2) { 02677 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 02678 } 02679 /* Disable Caller*ID if enabled */ 02680 p->hidecallerid = 1; 02681 ast_set_callerid(chan, "", "", NULL); 02682 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02683 transmit_notify_request(sub, "L/sl"); 02684 len = 0; 02685 memset(exten, 0, sizeof(exten)); 02686 timeout = firstdigittimeout; 02687 } else if (p->callreturn && !strcmp(exten, "*69")) { 02688 res = 0; 02689 if (!ast_strlen_zero(p->lastcallerid)) { 02690 res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language); 02691 } 02692 if (!res) 02693 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02694 transmit_notify_request(sub, "L/sl"); 02695 break; 02696 } else if (!strcmp(exten, "*78")) { 02697 /* Do not disturb */ 02698 if (option_verbose > 2) { 02699 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name); 02700 } 02701 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02702 transmit_notify_request(sub, "L/sl"); 02703 p->dnd = 1; 02704 getforward = 0; 02705 memset(exten, 0, sizeof(exten)); 02706 len = 0; 02707 } else if (!strcmp(exten, "*79")) { 02708 /* Do not disturb */ 02709 if (option_verbose > 2) { 02710 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name); 02711 } 02712 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02713 transmit_notify_request(sub, "L/sl"); 02714 p->dnd = 0; 02715 getforward = 0; 02716 memset(exten, 0, sizeof(exten)); 02717 len = 0; 02718 } else if (p->cancallforward && !strcmp(exten, "*72")) { 02719 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02720 transmit_notify_request(sub, "L/sl"); 02721 getforward = 1; 02722 memset(exten, 0, sizeof(exten)); 02723 len = 0; 02724 } else if (p->cancallforward && !strcmp(exten, "*73")) { 02725 if (option_verbose > 2) { 02726 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name); 02727 } 02728 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02729 transmit_notify_request(sub, "L/sl"); 02730 memset(p->call_forward, 0, sizeof(p->call_forward)); 02731 getforward = 0; 02732 memset(exten, 0, sizeof(exten)); 02733 len = 0; 02734 } else if (!strcmp(exten, ast_parking_ext()) && 02735 sub->next->owner && ast_bridged_channel(sub->next->owner)) { 02736 /* This is a three way call, the main call being a real channel, 02737 and we're parking the first call. */ 02738 ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); 02739 if (option_verbose > 2) { 02740 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 02741 } 02742 break; 02743 } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(exten, "*60")) { 02744 if (option_verbose > 2) { 02745 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcallerid); 02746 } 02747 res = ast_db_put("blacklist", p->lastcallerid, "1"); 02748 if (!res) { 02749 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02750 transmit_notify_request(sub, "L/sl"); 02751 memset(exten, 0, sizeof(exten)); 02752 len = 0; 02753 } 02754 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 02755 if (option_verbose > 2) { 02756 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 02757 } 02758 /* Enable Caller*ID if enabled */ 02759 p->hidecallerid = 0; 02760 ast_set_callerid(chan, p->cid_num, p->cid_name, NULL); 02761 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02762 transmit_notify_request(sub, "L/sl"); 02763 len = 0; 02764 memset(exten, 0, sizeof(exten)); 02765 timeout = firstdigittimeout; 02766 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 02767 ((exten[0] != '*') || (strlen(exten) > 2))) { 02768 if (option_debug) 02769 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); 02770 break; 02771 } 02772 if (!timeout) 02773 timeout = gendigittimeout; 02774 if (len && !ast_ignore_pattern(chan->context, exten)) 02775 /*tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02776 ast_indicate(chan, -1); 02777 } 02778 #if 0 02779 for (;;) { 02780 res = ast_waitfordigit(chan, to); 02781 if (!res) { 02782 ast_log(LOG_DEBUG, "Timeout...\n"); 02783 break; 02784 } 02785 if (res < 0) { 02786 ast_log(LOG_DEBUG, "Got hangup...\n"); 02787 ast_hangup(chan); 02788 break; 02789 } 02790 exten[pos++] = res; 02791 if (!ast_ignore_pattern(chan->context, exten)) 02792 ast_indicate(chan, -1); 02793 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) { 02794 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 02795 to = 3000; 02796 else 02797 to = 8000; 02798 } else 02799 break; 02800 } 02801 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) { 02802 strncpy(chan->exten, exten, sizeof(chan->exten) - 1); 02803 if (!p->rtp) { 02804 start_rtp(p); 02805 } 02806 ast_setstate(chan, AST_STATE_RING); 02807 chan->rings = 1; 02808 if (ast_pbx_run(chan)) { 02809 ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name); 02810 } else 02811 return NULL; 02812 } 02813 #endif 02814 ast_hangup(chan); 02815 return NULL; 02816 }
|
|
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 3267 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, mgcpdebug, 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(). 03268 { 03269 struct mgcp_request req; 03270 struct sockaddr_in sin; 03271 struct mgcp_subchannel *sub; 03272 int res; 03273 socklen_t len; 03274 int result; 03275 int ident; 03276 char iabuf[INET_ADDRSTRLEN]; 03277 len = sizeof(sin); 03278 memset(&req, 0, sizeof(req)); 03279 res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 03280 if (res < 0) { 03281 if (errno != ECONNREFUSED) 03282 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 03283 return 1; 03284 } 03285 req.data[res] = '\0'; 03286 req.len = res; 03287 if (mgcpdebug) { 03288 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)); 03289 } 03290 parse(&req); 03291 if (req.headers < 1) { 03292 /* Must have at least one header */ 03293 return 1; 03294 } 03295 if (ast_strlen_zero(req.identifier)) { 03296 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 03297 return 1; 03298 } 03299 03300 if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) { 03301 /* Try to find who this message is for, if it's important */ 03302 sub = find_subchannel_and_lock(NULL, ident, &sin); 03303 if (sub) { 03304 struct mgcp_gateway *gw = sub->parent->parent; 03305 struct mgcp_message *cur, *prev; 03306 03307 ast_mutex_unlock(&sub->lock); 03308 ast_mutex_lock(&gw->msgs_lock); 03309 for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) { 03310 if (cur->seqno == ident) { 03311 ast_log(LOG_DEBUG, "Got response back on transaction %d\n", ident); 03312 if (prev) 03313 prev->next = cur->next; 03314 else 03315 gw->msgs = cur->next; 03316 break; 03317 } 03318 } 03319 03320 /* stop retrans timer if the queue is empty */ 03321 if (!gw->msgs && (gw->retransid != -1)) { 03322 ast_sched_del(sched, gw->retransid); 03323 gw->retransid = -1; 03324 } 03325 03326 ast_mutex_unlock(&gw->msgs_lock); 03327 if (cur) { 03328 handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req); 03329 free(cur); 03330 return 1; 03331 } 03332 03333 ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n", 03334 gw->name, ident); 03335 } 03336 } else { 03337 if (ast_strlen_zero(req.endpoint) || 03338 ast_strlen_zero(req.version) || 03339 ast_strlen_zero(req.verb)) { 03340 ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n"); 03341 return 1; 03342 } 03343 /* Process request, with iflock held */ 03344 sub = find_subchannel_and_lock(req.endpoint, 0, &sin); 03345 if (sub) { 03346 /* look first to find a matching response in the queue */ 03347 if (!find_and_retrans(sub, &req)) 03348 /* pass the request off to the currently mastering subchannel */ 03349 handle_request(sub, &req, &sin); 03350 ast_mutex_unlock(&sub->lock); 03351 } 03352 } 03353 return 1; 03354 }
|
|
Definition at line 1657 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(). 01658 { 01659 /* Divide fields by NULL's */ 01660 char *c; 01661 int f = 0; 01662 c = req->data; 01663 01664 /* First header starts immediately */ 01665 req->header[f] = c; 01666 while(*c) { 01667 if (*c == '\n') { 01668 /* We've got a new header */ 01669 *c = 0; 01670 #if 0 01671 printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f])); 01672 #endif 01673 if (ast_strlen_zero(req->header[f])) { 01674 /* Line by itself means we're now in content */ 01675 c++; 01676 break; 01677 } 01678 if (f >= MGCP_MAX_HEADERS - 1) { 01679 ast_log(LOG_WARNING, "Too many MGCP headers...\n"); 01680 } else 01681 f++; 01682 req->header[f] = c + 1; 01683 } else if (*c == '\r') { 01684 /* Ignore but eliminate \r's */ 01685 *c = 0; 01686 } 01687 c++; 01688 } 01689 /* Check for last header */ 01690 if (!ast_strlen_zero(req->header[f])) 01691 f++; 01692 req->headers = f; 01693 /* Now we process any mime content */ 01694 f = 0; 01695 req->line[f] = c; 01696 while(*c) { 01697 if (*c == '\n') { 01698 /* We've got a new line */ 01699 *c = 0; 01700 #if 0 01701 printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f])); 01702 #endif 01703 if (f >= MGCP_MAX_LINES - 1) { 01704 ast_log(LOG_WARNING, "Too many SDP lines...\n"); 01705 } else 01706 f++; 01707 req->line[f] = c + 1; 01708 } else if (*c == '\r') { 01709 /* Ignore and eliminate \r's */ 01710 *c = 0; 01711 } 01712 c++; 01713 } 01714 /* Check for last line */ 01715 if (!ast_strlen_zero(req->line[f])) 01716 f++; 01717 req->lines = f; 01718 /* Parse up the initial header */ 01719 c = req->header[0]; 01720 while(*c && *c < 33) c++; 01721 /* First the verb */ 01722 req->verb = c; 01723 while(*c && (*c > 32)) c++; 01724 if (*c) { 01725 *c = '\0'; 01726 c++; 01727 while(*c && (*c < 33)) c++; 01728 req->identifier = c; 01729 while(*c && (*c > 32)) c++; 01730 if (*c) { 01731 *c = '\0'; 01732 c++; 01733 while(*c && (*c < 33)) c++; 01734 req->endpoint = c; 01735 while(*c && (*c > 32)) c++; 01736 if (*c) { 01737 *c = '\0'; 01738 c++; 01739 while(*c && (*c < 33)) c++; 01740 req->version = c; 01741 while(*c && (*c > 32)) c++; 01742 while(*c && (*c < 33)) c++; 01743 while(*c && (*c > 32)) c++; 01744 *c = '\0'; 01745 } 01746 } 01747 } 01748 01749 if (mgcpdebug) { 01750 ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n", 01751 req->verb, req->identifier, req->endpoint, req->version); 01752 ast_verbose("%d headers, %d lines\n", req->headers, req->lines); 01753 } 01754 if (*c) 01755 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 01756 }
|
|
Definition at line 1758 of file chan_mgcp.c. References 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, and sdpLineNum_iterator_init(). Referenced by handle_request(), handle_request_invite(), handle_response(), and handle_response_invite(). 01759 { 01760 char *m; 01761 char *c; 01762 char *a; 01763 char host[258]; 01764 int len; 01765 int portno; 01766 int peercapability, peerNonCodecCapability; 01767 struct sockaddr_in sin; 01768 char *codecs; 01769 struct ast_hostent ahp; struct hostent *hp; 01770 int codec, codec_count=0; 01771 int iterator; 01772 struct mgcp_endpoint *p = sub->parent; 01773 01774 /* Get codec and RTP info from SDP */ 01775 m = get_sdp(req, "m"); 01776 c = get_sdp(req, "c"); 01777 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 01778 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 01779 return -1; 01780 } 01781 if (sscanf(c, "IN IP4 %256s", host) != 1) { 01782 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 01783 return -1; 01784 } 01785 /* XXX This could block for a long time, and block the main thread! XXX */ 01786 hp = ast_gethostbyname(host, &ahp); 01787 if (!hp) { 01788 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 01789 return -1; 01790 } 01791 if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) { 01792 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 01793 return -1; 01794 } 01795 sin.sin_family = AF_INET; 01796 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 01797 sin.sin_port = htons(portno); 01798 ast_rtp_set_peer(sub->rtp, &sin); 01799 #if 0 01800 printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 01801 #endif 01802 /* Scan through the RTP payload types specified in a "m=" line: */ 01803 ast_rtp_pt_clear(sub->rtp); 01804 codecs = ast_strdupa(m + len); 01805 while (!ast_strlen_zero(codecs)) { 01806 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 01807 if (codec_count) 01808 break; 01809 ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs); 01810 return -1; 01811 } 01812 ast_rtp_set_m_type(sub->rtp, codec); 01813 codec_count++; 01814 codecs += len; 01815 } 01816 01817 /* Next, scan through each "a=rtpmap:" line, noting each */ 01818 /* specified RTP payload type (with corresponding MIME subtype): */ 01819 sdpLineNum_iterator_init(&iterator); 01820 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 01821 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 01822 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) 01823 continue; 01824 /* Note: should really look at the 'freq' and '#chans' params too */ 01825 ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype); 01826 } 01827 01828 /* Now gather all of the codecs that were asked for: */ 01829 ast_rtp_get_current_formats(sub->rtp, &peercapability, &peerNonCodecCapability); 01830 p->capability = capability & peercapability; 01831 if (mgcpdebug) { 01832 ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n", 01833 capability, peercapability, p->capability); 01834 ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n", 01835 nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability); 01836 } 01837 if (!p->capability) { 01838 ast_log(LOG_WARNING, "No compatible codecs!\n"); 01839 return -1; 01840 } 01841 return 0; 01842 }
|
|
Definition at line 4024 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), mgcp_endpoint::delme, destroy_endpoint(), destroy_gateway(), gateways, mgcp_gateway::next, mgcp_endpoint::next, and t. Referenced by reload_config(), and unload_module(). 04025 { 04026 struct mgcp_gateway *g, *z, *r; 04027 struct mgcp_endpoint *e, *p, *t; 04028 04029 ast_mutex_lock(&gatelock); 04030 04031 /* prune gateways */ 04032 for (z = NULL, g = gateways; g;) { 04033 /* prune endpoints */ 04034 for (p = NULL, e = g->endpoints; e; ) { 04035 if (e->delme || g->delme) { 04036 t = e; 04037 e = e->next; 04038 if (!p) 04039 g->endpoints = e; 04040 else 04041 p->next = e; 04042 destroy_endpoint(t); 04043 } else { 04044 p = e; 04045 e = e->next; 04046 } 04047 } 04048 04049 if (g->delme) { 04050 r = g; 04051 g = g->next; 04052 if (!z) 04053 gateways = g; 04054 else 04055 z->next = g; 04056 04057 destroy_gateway(r); 04058 } else { 04059 z = g; 04060 g = g->next; 04061 } 04062 } 04063 04064 ast_mutex_unlock(&gatelock); 04065 }
|
|
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 4292 of file chan_mgcp.c. References mgcp_reload(). 04293 { 04294 mgcp_reload(0, 0, NULL); 04295 return 0; 04296 }
|
|
Definition at line 4067 of file chan_mgcp.c. References __ourip, 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_gateway::delme, dtmfmode, mgcp_gateway::endpoints, format, gateways, hp, 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_endpoint::next, mgcp_gateway::next, ast_variable::next, option_verbose, ourhost, ourport, prune_gateways(), tos, transmit_audit_endpoint(), ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3. 04068 { 04069 struct ast_config *cfg; 04070 struct ast_variable *v; 04071 struct mgcp_gateway *g; 04072 struct mgcp_endpoint *e; 04073 char iabuf[INET_ADDRSTRLEN]; 04074 char *cat; 04075 struct ast_hostent ahp; 04076 struct hostent *hp; 04077 int format; 04078 04079 if (gethostname(ourhost, sizeof(ourhost)-1)) { 04080 ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n"); 04081 return 0; 04082 } 04083 cfg = ast_config_load(config); 04084 04085 /* We *must* have a config file otherwise stop immediately */ 04086 if (!cfg) { 04087 ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config); 04088 return 0; 04089 } 04090 memset(&bindaddr, 0, sizeof(bindaddr)); 04091 dtmfmode = 0; 04092 v = ast_variable_browse(cfg, "general"); 04093 while(v) { 04094 /* Create the interface list */ 04095 if (!strcasecmp(v->name, "bindaddr")) { 04096 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 04097 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 04098 } else { 04099 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 04100 } 04101 } else if (!strcasecmp(v->name, "allow")) { 04102 format = ast_getformatbyname(v->value); 04103 if (format < 1) 04104 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 04105 else 04106 capability |= format; 04107 } else if (!strcasecmp(v->name, "disallow")) { 04108 format = ast_getformatbyname(v->value); 04109 if (format < 1) 04110 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 04111 else 04112 capability &= ~format; 04113 } else if (!strcasecmp(v->name, "tos")) { 04114 if (sscanf(v->value, "%d", &format) == 1) 04115 tos = format & 0xff; 04116 else if (!strcasecmp(v->value, "lowdelay")) 04117 tos = IPTOS_LOWDELAY; 04118 else if (!strcasecmp(v->value, "throughput")) 04119 tos = IPTOS_THROUGHPUT; 04120 else if (!strcasecmp(v->value, "reliability")) 04121 tos = IPTOS_RELIABILITY; 04122 else if (!strcasecmp(v->value, "mincost")) 04123 tos = IPTOS_MINCOST; 04124 else if (!strcasecmp(v->value, "none")) 04125 tos = 0; 04126 else 04127 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 04128 } else if (!strcasecmp(v->name, "port")) { 04129 if (sscanf(v->value, "%d", &ourport) == 1) { 04130 bindaddr.sin_port = htons(ourport); 04131 } else { 04132 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 04133 } 04134 } 04135 v = v->next; 04136 } 04137 04138 /* SC: mark existing entries for deletion */ 04139 ast_mutex_lock(&gatelock); 04140 g = gateways; 04141 while (g) { 04142 g->delme = 1; 04143 e = g->endpoints; 04144 while (e) { 04145 e->delme = 1; 04146 e = e->next; 04147 } 04148 g = g->next; 04149 } 04150 ast_mutex_unlock(&gatelock); 04151 04152 cat = ast_category_browse(cfg, NULL); 04153 while(cat) { 04154 if (strcasecmp(cat, "general")) { 04155 ast_mutex_lock(&gatelock); 04156 g = build_gateway(cat, ast_variable_browse(cfg, cat)); 04157 if (g) { 04158 if (option_verbose > 2) { 04159 ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name); 04160 } 04161 g->next = gateways; 04162 gateways = g; 04163 } 04164 ast_mutex_unlock(&gatelock); 04165 04166 /* FS: process queue and IO */ 04167 if (monitor_thread == pthread_self()) { 04168 if (sched) ast_sched_runq(sched); 04169 if (io) ast_io_wait(io, 10); 04170 } 04171 } 04172 cat = ast_category_browse(cfg, cat); 04173 } 04174 04175 /* SC: prune deleted entries etc. */ 04176 prune_gateways(); 04177 04178 if (ntohl(bindaddr.sin_addr.s_addr)) { 04179 memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip)); 04180 } else { 04181 hp = ast_gethostbyname(ourhost, &ahp); 04182 if (!hp) { 04183 ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n"); 04184 ast_config_destroy(cfg); 04185 return 0; 04186 } 04187 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 04188 } 04189 if (!ntohs(bindaddr.sin_port)) 04190 bindaddr.sin_port = ntohs(DEFAULT_MGCP_CA_PORT); 04191 bindaddr.sin_family = AF_INET; 04192 ast_mutex_lock(&netlock); 04193 if (mgcpsock > -1) 04194 close(mgcpsock); 04195 04196 if (mgcpsock_read_id != NULL) 04197 ast_io_remove(io, mgcpsock_read_id); 04198 mgcpsock_read_id = NULL; 04199 04200 mgcpsock = socket(AF_INET, SOCK_DGRAM, 0); 04201 if (mgcpsock < 0) { 04202 ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno)); 04203 } else { 04204 if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 04205 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 04206 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 04207 strerror(errno)); 04208 close(mgcpsock); 04209 mgcpsock = -1; 04210 } else { 04211 if (option_verbose > 1) { 04212 ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n", 04213 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 04214 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 04215 } 04216 if (setsockopt(mgcpsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 04217 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 04218 } 04219 } 04220 ast_mutex_unlock(&netlock); 04221 ast_config_destroy(cfg); 04222 04223 /* SC: send audit only to the new endpoints */ 04224 g = gateways; 04225 while (g) { 04226 e = g->endpoints; 04227 while (e && e->needaudit) { 04228 e->needaudit = 0; 04229 transmit_audit_endpoint(e); 04230 ast_verbose(VERBOSE_PREFIX_3 "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name); 04231 e = e->next; 04232 } 04233 g = g->next; 04234 } 04235 04236 return 0; 04237 }
|
|
Definition at line 1935 of file chan_mgcp.c. References init_req(), and oseq. Referenced by transmit_audit_endpoint(), transmit_connect_with_sdp(), 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_modify_with_sdp(), 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(). 01936 { 01937 memset(req, 0, sizeof(struct mgcp_request)); 01938 oseq++; 01939 if (oseq > 999999999) 01940 oseq = 1; 01941 init_req(p, req, verb); 01942 return 0; 01943 }
|
|
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, mgcpdebug, mgcp_endpoint::parent, and mgcp_subchannel::parent. 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 1928 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(). 01929 { 01930 memset(resp, 0, sizeof(*resp)); 01931 init_resp(resp, msg, req, msgrest); 01932 return 0; 01933 }
|
|
Definition at line 3444 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. 03445 { 03446 /* If we're supposed to be stopped -- stay stopped */ 03447 if (monitor_thread == AST_PTHREADT_STOP) 03448 return 0; 03449 if (ast_mutex_lock(&monlock)) { 03450 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 03451 return -1; 03452 } 03453 if (monitor_thread == pthread_self()) { 03454 ast_mutex_unlock(&monlock); 03455 ast_log(LOG_WARNING, "Cannot kill myself\n"); 03456 return -1; 03457 } 03458 if (monitor_thread != AST_PTHREADT_NULL) { 03459 /* Wake up the thread */ 03460 pthread_kill(monitor_thread, SIGURG); 03461 } else { 03462 /* Start a new monitor */ 03463 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 03464 ast_mutex_unlock(&monlock); 03465 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 03466 return -1; 03467 } 03468 } 03469 ast_mutex_unlock(&monlock); 03470 return 0; 03471 }
|
|
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, 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 1476 of file chan_mgcp.c. Referenced by process_sdp(). 01477 { 01478 *iterator = 0; 01479 }
|
|
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_connect_with_sdp(), 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_modify_with_sdp(), 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, mgcpdebug, mgcp_endpoint::parent, and mgcp_subchannel::parent. 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 2248 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(). 02249 { 02250 struct mgcp_request resp; 02251 reqprep(&resp, p, "AUEP"); 02252 /* SC: removed unknown param VS */ 02253 /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/ 02254 add_header(&resp, "F", "A"); 02255 /* SC: fill in new fields */ 02256 resp.cmd = MGCP_CMD_AUEP; 02257 resp.trid = oseq; 02258 return send_request(p, NULL, &resp, oseq); /* SC */ 02259 }
|
|
Definition at line 2103 of file chan_mgcp.c. References add_header(), add_sdp(), AST_FORMAT_MAX_AUDIO, ast_rtp_lookup_mime_subtype(), ast_rtp_offered_from_local(), ast_verbose(), mgcp_subchannel::callid, mgcp_endpoint::capability, mgcp_request::cmd, mgcp_subchannel::cxmode, mgcp_subchannel::id, MGCP_CMD_CRCX, mgcp_cxmodes, mgcpdebug, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::rtp, send_request(), mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by start_rtp(). 02104 { 02105 struct mgcp_request resp; 02106 char local[256]; 02107 char tmp[80]; 02108 int x; 02109 struct mgcp_endpoint *p = sub->parent; 02110 02111 snprintf(local, sizeof(local), "p:20"); 02112 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02113 if (p->capability & x) { 02114 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02115 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02116 } 02117 } 02118 if (mgcpdebug) { 02119 ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", 02120 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02121 } 02122 reqprep(&resp, p, "CRCX"); 02123 add_header(&resp, "C", sub->callid); 02124 add_header(&resp, "L", local); 02125 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02126 /* SC: X header should not be sent. kept for compatibility */ 02127 add_header(&resp, "X", sub->txident); 02128 /*add_header(&resp, "S", "");*/ 02129 ast_rtp_offered_from_local(sub->rtp, 1); 02130 add_sdp(&resp, sub, rtp); 02131 /* SC: fill in new fields */ 02132 resp.cmd = MGCP_CMD_CRCX; 02133 resp.trid = oseq; 02134 return send_request(p, sub, &resp, oseq); /* SC */ 02135 }
|
|
Definition at line 2261 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, mgcpdebug, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), send_request(), mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by destroy_endpoint(), handle_request(), handle_response(), mgcp_hangup(), and unalloc_sub(). 02262 { 02263 struct mgcp_endpoint *p = sub->parent; 02264 struct mgcp_request resp; 02265 02266 if (mgcpdebug) { 02267 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", 02268 sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02269 } 02270 reqprep(&resp, p, "DLCX"); 02271 /* SC: check if call id is avail */ 02272 if (sub->callid[0]) 02273 add_header(&resp, "C", sub->callid); 02274 /* SC: X header should not be sent. kept for compatibility */ 02275 add_header(&resp, "X", sub->txident); 02276 /* SC: check if cxident is avail */ 02277 if (sub->cxident[0]) 02278 add_header(&resp, "I", sub->cxident); 02279 /* SC: fill in new fields */ 02280 resp.cmd = MGCP_CMD_DLCX; 02281 resp.trid = oseq; 02282 return send_request(p, sub, &resp, oseq); /* SC */ 02283 }
|
|
Definition at line 2285 of file chan_mgcp.c. References add_header(), ast_verbose(), MGCP_CMD_DLCX, mgcpdebug, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, reqprep(), send_request(), mgcp_endpoint::sub, and VERBOSE_PREFIX_3. Referenced by handle_response(). 02286 { 02287 struct mgcp_request resp; 02288 02289 if (mgcpdebug) { 02290 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", 02291 cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); 02292 } 02293 reqprep(&resp, p, "DLCX"); 02294 /* SC: check if call id is avail */ 02295 if (callid && *callid) 02296 add_header(&resp, "C", callid); 02297 /* SC: check if cxident is avail */ 02298 if (cxident && *cxident) 02299 add_header(&resp, "I", cxident); 02300 /* SC: fill in new fields */ 02301 resp.cmd = MGCP_CMD_DLCX; 02302 resp.trid = oseq; 02303 return send_request(p, p->sub, &resp, oseq); 02304 }
|
|
Definition at line 2213 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, mgcpdebug, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::rtp, send_request(), mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), mgcp_call(), and mgcp_hangup(). 02214 { 02215 struct mgcp_request resp; 02216 struct mgcp_endpoint *p = sub->parent; 02217 02218 if (ast_strlen_zero(sub->cxident)) { 02219 /* We don't have a CXident yet, store the destination and 02220 wait a bit */ 02221 return 0; 02222 } 02223 if (mgcpdebug) { 02224 ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", 02225 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02226 } 02227 reqprep(&resp, p, "MDCX"); 02228 add_header(&resp, "C", sub->callid); 02229 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02230 /* SC: X header should not be sent. kept for compatibility */ 02231 add_header(&resp, "X", sub->txident); 02232 add_header(&resp, "I", sub->cxident); 02233 switch (sub->parent->hookstate) { 02234 case MGCP_ONHOOK: 02235 add_header(&resp, "R", "L/hd(N)"); 02236 break; 02237 case MGCP_OFFHOOK: 02238 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)"); 02239 break; 02240 } 02241 /* SC: fill in new fields */ 02242 resp.cmd = MGCP_CMD_MDCX; 02243 resp.trid = oseq; 02244 return send_request(p, sub, &resp, oseq); /* SC */ 02245 }
|
|
Definition at line 2062 of file chan_mgcp.c. References add_header(), add_sdp(), AST_FORMAT_MAX_AUDIO, ast_rtp_get_peer(), ast_rtp_lookup_mime_subtype(), ast_rtp_offered_from_local(), ast_strlen_zero(), mgcp_subchannel::callid, mgcp_endpoint::capability, capability, mgcp_request::cmd, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, MGCP_CMD_MDCX, mgcp_cxmodes, oseq, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::rtp, send_request(), mgcp_subchannel::tmpdest, mgcp_request::trid, and mgcp_subchannel::txident. Referenced by handle_response(), and mgcp_set_rtp_peer(). 02063 { 02064 struct mgcp_request resp; 02065 char local[256]; 02066 char tmp[80]; 02067 int x; 02068 int capability; 02069 struct mgcp_endpoint *p = sub->parent; 02070 02071 capability = p->capability; 02072 if (codecs) 02073 capability = codecs; 02074 if (ast_strlen_zero(sub->cxident) && rtp) { 02075 /* We don't have a CXident yet, store the destination and 02076 wait a bit */ 02077 ast_rtp_get_peer(rtp, &sub->tmpdest); 02078 return 0; 02079 } 02080 snprintf(local, sizeof(local), "p:20"); 02081 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02082 if (p->capability & x) { 02083 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02084 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02085 } 02086 } 02087 reqprep(&resp, p, "MDCX"); 02088 add_header(&resp, "C", sub->callid); 02089 add_header(&resp, "L", local); 02090 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02091 /* SC: X header should not be sent. kept for compatibility */ 02092 add_header(&resp, "X", sub->txident); 02093 add_header(&resp, "I", sub->cxident); 02094 /*add_header(&resp, "S", "");*/ 02095 ast_rtp_offered_from_local(sub->rtp, 0); 02096 add_sdp(&resp, sub, rtp); 02097 /* SC: fill in new fields */ 02098 resp.cmd = MGCP_CMD_MDCX; 02099 resp.trid = oseq; 02100 return send_request(p, sub, &resp, oseq); /* SC */ 02101 }
|
|
|
Definition at line 2166 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, mgcpdebug, n, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_endpoint::rqnt_ident, mgcp_subchannel::rtp, send_request(), t, mgcp_request::trid, and VERBOSE_PREFIX_3. Referenced by mgcp_call(), and mgcp_hangup(). 02167 { 02168 struct mgcp_request resp; 02169 char tone2[256]; 02170 char *l, *n; 02171 time_t t; 02172 struct tm tm; 02173 struct mgcp_endpoint *p = sub->parent; 02174 02175 time(&t); 02176 localtime_r(&t,&tm); 02177 n = callername; 02178 l = callernum; 02179 if (!n) 02180 n = ""; 02181 if (!l) 02182 l = ""; 02183 02184 /* Keep track of last callerid for blacklist and callreturn */ 02185 strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1); 02186 02187 snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 02188 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n); 02189 strncpy(p->curtone, tone, sizeof(p->curtone) - 1); 02190 reqprep(&resp, p, "RQNT"); 02191 add_header(&resp, "X", p->rqnt_ident); /* SC */ 02192 switch (p->hookstate) { 02193 case MGCP_ONHOOK: 02194 add_header(&resp, "R", "L/hd(N)"); 02195 break; 02196 case MGCP_OFFHOOK: 02197 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)"); 02198 break; 02199 } 02200 if (!ast_strlen_zero(tone2)) { 02201 add_header(&resp, "S", tone2); 02202 } 02203 if (mgcpdebug) { 02204 ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", 02205 tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); 02206 } 02207 /* SC: fill in new fields */ 02208 resp.cmd = MGCP_CMD_RQNT; 02209 resp.trid = oseq; 02210 return send_request(p, NULL, &resp, oseq); /* SC */ 02211 }
|
|
|
|
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 4298 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(), gateways, LOG_WARNING, mgcp_reload(), mgcp_reloading, mgcpsock, monitor_thread, prune_gateways(), and sched_context_destroy(). 04299 { 04300 struct mgcp_endpoint *e; 04301 struct mgcp_gateway *g; 04302 04303 /* Check to see if we're reloading */ 04304 if (ast_mutex_trylock(&mgcp_reload_lock)) { 04305 ast_log(LOG_WARNING, "MGCP is currently reloading. Unable to remove module.\n"); 04306 return -1; 04307 } else { 04308 mgcp_reloading = 1; 04309 ast_mutex_unlock(&mgcp_reload_lock); 04310 } 04311 04312 /* First, take us out of the channel loop */ 04313 ast_channel_unregister(&mgcp_tech); 04314 04315 /* Shut down the monitoring thread */ 04316 if (!ast_mutex_lock(&monlock)) { 04317 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 04318 pthread_cancel(monitor_thread); 04319 pthread_kill(monitor_thread, SIGURG); 04320 pthread_join(monitor_thread, NULL); 04321 } 04322 monitor_thread = AST_PTHREADT_STOP; 04323 ast_mutex_unlock(&monlock); 04324 } else { 04325 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 04326 /* We always want to leave this in a consistent state */ 04327 ast_channel_register(&mgcp_tech); 04328 mgcp_reloading = 0; 04329 mgcp_reload(0, 0, NULL); 04330 return -1; 04331 } 04332 04333 if (!ast_mutex_lock(&gatelock)) { 04334 g = gateways; 04335 while (g) { 04336 g->delme = 1; 04337 e = g->endpoints; 04338 while (e) { 04339 e->delme = 1; 04340 e = e->next; 04341 } 04342 g = g->next; 04343 } 04344 04345 prune_gateways(); 04346 ast_mutex_unlock(&gatelock); 04347 } else { 04348 ast_log(LOG_WARNING, "Unable to lock the gateways list.\n"); 04349 /* We always want to leave this in a consistent state */ 04350 ast_channel_register(&mgcp_tech); 04351 /* Allow the monitor to restart */ 04352 monitor_thread = AST_PTHREADT_NULL; 04353 mgcp_reloading = 0; 04354 mgcp_reload(0, 0, NULL); 04355 return -1; 04356 } 04357 04358 close(mgcpsock); 04359 ast_rtp_proto_unregister(&mgcp_rtp); 04360 ast_cli_unregister(&cli_show_endpoints); 04361 ast_cli_unregister(&cli_audit_endpoint); 04362 ast_cli_unregister(&cli_debug); 04363 ast_cli_unregister(&cli_no_debug); 04364 ast_cli_unregister(&cli_mgcp_reload); 04365 sched_context_destroy(sched); 04366 04367 return 0; 04368 }
|
|
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 4370 of file chan_mgcp.c. References usecnt. 04371 { 04372 return usecnt; 04373 }
|
|
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(), mkintf(), and setup_zap(). |
|
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_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Definition at line 207 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Definition at line 224 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), mkintf(), and setup_zap(). |
|
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_device(), build_gateway(), iax2_call(), mgcp_new(), mgcp_request(), process_sdp(), reload_config(), set_config(), set_local_capabilities(), skinny_new(), skinny_request(), and transmit_modify_with_sdp(). |
|
Definition at line 184 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), builtin_atxfer(), check_access(), load_module(), misdn_new(), mkif(), mkintf(), monitor_handle_notowned(), setup_zap(), vpb_new(), and zt_handle_event(). |
|
Definition at line 183 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), builtin_atxfer(), check_access(), load_module(), misdn_new(), mkif(), mkintf(), monitor_handle_notowned(), setup_zap(), vpb_new(), and zt_handle_event(). |
|
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. |
|
Initial value: { { "mgcp", "debug", NULL }, mgcp_do_debug, "Enable MGCP debugging", debug_usage } Definition at line 3964 of file chan_mgcp.c. |
|
Initial value: { { "mgcp", "reload", NULL }, mgcp_reload, "Reload MGCP configuration", mgcp_reload_usage } Definition at line 3968 of file chan_mgcp.c. |
|
Initial value: { { "mgcp", "no", "debug", NULL }, mgcp_no_debug, "Disable MGCP debugging", no_debug_usage } Definition at line 3966 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. |
|
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_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Definition at line 196 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Initial value: "Usage: mgcp debug\n" " Enables dumping of MGCP packets for debugging purposes\n" Definition at line 3952 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(), load_module(), mkif(), reload_config(), and set_local_capabilities(). |
|
Definition at line 248 of file chan_mgcp.c. Referenced by disa_exec(), mgcp_ss(), skinny_ss(), and ss_thread(). |
|
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(), skinny_ss(), and ss_thread(). |
|
Definition at line 205 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), build_port_config(), cb_events(), fill_defaults(), free_port_cfg(), misdn_cfg_get(), misdn_cfg_get_config_string(), mkintf(), and setup_zap(). |
|
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_device(), build_gateway(), disa_exec(), handle_request_subscribe(), mkintf(), realtime_directory(), and setup_zap(). |
|
Definition at line 254 of file chan_mgcp.c. Referenced by mgcp_ss(), skinny_ss(), and ss_thread(). |
|
Definition at line 160 of file chan_mgcp.c. Referenced by transmit_connect_with_sdp(), transmit_connection_del(), transmit_modify_request(), transmit_modify_with_sdp(), 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 3960 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 3928 of file chan_mgcp.c. |
|
Definition at line 500 of file chan_mgcp.c. |
|
|
Definition at line 471 of file chan_mgcp.c. Referenced by __mgcp_xmit(), do_monitor(), mgcpsock_read(), reload_config(), and unload_module(). |
|
Definition at line 3356 of file chan_mgcp.c. Referenced by do_monitor(), and reload_config(). |
|
Definition at line 264 of file chan_mgcp.c. |
|
Definition at line 182 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Definition at line 187 of file chan_mgcp.c. Referenced by build_device(), and build_gateway(). |
|
Initial value: "Usage: mgcp no debug\n" " Disables dumping of MGCP packets for debugging purposes\n" Definition at line 3956 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_connect_with_sdp(), transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_request(), transmit_modify_with_sdp(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 271 of file chan_mgcp.c. Referenced by ast_find_ourip(), handle_message(), and reload_config(). |
|
Definition at line 273 of file chan_mgcp.c. Referenced by build_contact(), build_via(), handle_message(), initreqprep(), 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_device(), build_gateway(), mkintf(), and setup_zap(). |
|
Definition at line 203 of file chan_mgcp.c. |
|
Definition at line 222 of file chan_mgcp.c. Referenced by build_device(), build_gateway(), leave_voicemail(), mkintf(), and setup_zap(). |
|
Definition at line 137 of file chan_mgcp.c. |
|
Definition at line 242 of file chan_mgcp.c. |