#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <sys/signal.h>
#include <signal.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <ctype.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/say.h"
#include "asterisk/cdr.h"
#include "asterisk/astdb.h"
#include "asterisk/features.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/dsp.h"
Go to the source code of this file.
Data Structures | |
struct | mgcp_endpoint |
struct | mgcp_gateway |
struct | mgcp_message |
struct | mgcp_request |
struct | mgcp_response |
struct | mgcp_subchannel |
Defines | |
#define | CANREINVITE 1 |
#define | DEFAULT_EXPIRY 120 |
#define | DEFAULT_MGCP_CA_PORT 2727 |
#define | DEFAULT_MGCP_GW_PORT 2427 |
#define | DEFAULT_RETRANS 1000 |
#define | INADDR_NONE (in_addr_t)(-1) |
#define | IPTOS_MINCOST 0x02 |
#define | MAX_EXPIRY 3600 |
#define | MAX_RETRANS 5 |
#define | MAX_SUBS 2 |
#define | MGCP_CMD_AUCX 7 |
#define | MGCP_CMD_AUEP 6 |
#define | MGCP_CMD_CRCX 1 |
#define | MGCP_CMD_DLCX 3 |
#define | MGCP_CMD_EPCF 0 |
#define | MGCP_CMD_MDCX 2 |
#define | MGCP_CMD_NTFY 5 |
#define | MGCP_CMD_RQNT 4 |
#define | MGCP_CMD_RSIP 8 |
#define | MGCP_CX_CONF 3 |
#define | MGCP_CX_CONFERENCE 3 |
#define | MGCP_CX_INACTIVE 4 |
#define | MGCP_CX_MUTE 4 |
#define | MGCP_CX_RECVONLY 1 |
#define | MGCP_CX_SENDONLY 0 |
#define | MGCP_CX_SENDRECV 2 |
#define | MGCP_DTMF_HYBRID (1 << 2) |
#define | MGCP_DTMF_INBAND (1 << 1) |
#define | MGCP_DTMF_RFC2833 (1 << 0) |
#define | MGCP_MAX_HEADERS 64 |
#define | MGCP_MAX_LINES 64 |
#define | MGCP_MAX_PACKET 1500 |
#define | MGCP_OFFHOOK 2 |
#define | MGCP_ONHOOK 1 |
#define | MGCP_SUBCHANNEL_MAGIC "!978!" |
#define | MGCPDUMPER |
#define | RESPONSE_TIMEOUT 30 |
#define | SUB_ALT 1 |
#define | SUB_REAL 0 |
#define | TYPE_LINE 2 |
#define | TYPE_TRUNK 1 |
Functions | |
char * | __get_header (struct mgcp_request *req, char *name, int *start) |
int | __mgcp_xmit (struct mgcp_gateway *gw, char *data, int len) |
int | add_header (struct mgcp_request *req, char *var, char *value) |
int | add_line (struct mgcp_request *req, char *line) |
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) | |
int | attempt_transfer (struct mgcp_endpoint *p) |
mgcp_gateway * | build_gateway (char *cat, struct ast_variable *v) |
char * | control2str (int ind) |
char * | description () |
Provides a description of the module. | |
void | destroy_endpoint (struct mgcp_endpoint *e) |
void | destroy_gateway (struct mgcp_gateway *g) |
void * | do_monitor (void *data) |
void | dump_cmd_queues (struct mgcp_endpoint *p, struct mgcp_subchannel *sub) |
void | dump_queue (struct mgcp_gateway *gw, struct mgcp_endpoint *p) |
int | find_and_retrans (struct mgcp_subchannel *sub, struct mgcp_request *req) |
mgcp_request * | find_command (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request **queue, ast_mutex_t *l, int ident) |
mgcp_subchannel * | find_subchannel_and_lock (char *name, int msgid, struct sockaddr_in *sin) |
char * | get_csv (char *c, int *len, char **next) |
char * | get_header (struct mgcp_request *req, char *name) |
char * | get_sdp (struct mgcp_request *req, char *name) |
char * | get_sdp_by_line (char *line, char *name, int nameLen) |
char * | get_sdp_iterate (int *iterator, struct mgcp_request *req, char *name) |
void | handle_hd_hf (struct mgcp_subchannel *sub, char *ev) |
int | handle_request (struct mgcp_subchannel *sub, struct mgcp_request *req, struct sockaddr_in *sin) |
void | handle_response (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, int result, unsigned int ident, struct mgcp_request *resp) |
int | has_voicemail (struct mgcp_endpoint *p) |
int | init_req (struct mgcp_endpoint *p, struct mgcp_request *req, char *verb) |
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. | |
int | mgcp_answer (struct ast_channel *ast) |
int | mgcp_audit_endpoint (int fd, int argc, char *argv[]) |
int | mgcp_call (struct ast_channel *ast, char *dest, int timeout) |
int | mgcp_do_debug (int fd, int argc, char *argv[]) |
int | mgcp_do_reload (void) |
int | mgcp_fixup (struct ast_channel *oldchan, struct ast_channel *newchan) |
ast_rtp * | mgcp_get_rtp_peer (struct ast_channel *chan) |
int | mgcp_hangup (struct ast_channel *ast) |
int | mgcp_indicate (struct ast_channel *ast, int ind) |
ast_channel * | mgcp_new (struct mgcp_subchannel *sub, int state) |
int | mgcp_no_debug (int fd, int argc, char *argv[]) |
int | mgcp_postrequest (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, char *data, int len, unsigned int seqno) |
void | mgcp_queue_control (struct mgcp_subchannel *sub, int control) |
void | mgcp_queue_frame (struct mgcp_subchannel *sub, struct ast_frame *f) |
void | mgcp_queue_hangup (struct mgcp_subchannel *sub) |
ast_frame * | mgcp_read (struct ast_channel *ast) |
int | mgcp_reload (int fd, int argc, char *argv[]) |
ast_channel * | mgcp_request (const char *type, int format, void *data, int *cause) |
ast_frame * | mgcp_rtp_read (struct mgcp_subchannel *sub) |
int | mgcp_senddigit (struct ast_channel *ast, char digit) |
int | mgcp_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active) |
int | mgcp_show_endpoints (int fd, int argc, char *argv[]) |
void * | mgcp_ss (void *data) |
int | mgcp_write (struct ast_channel *ast, struct ast_frame *frame) |
int | mgcpsock_read (int *id, int fd, short events, void *ignore) |
void | parse (struct mgcp_request *req) |
int | process_sdp (struct mgcp_subchannel *sub, struct mgcp_request *req) |
void | prune_gateways (void) |
int | reload (void) |
Reload stuff. | |
int | reload_config (void) |
int | reqprep (struct mgcp_request *req, struct mgcp_endpoint *p, char *verb) |
int | resend_response (struct mgcp_subchannel *sub, struct mgcp_response *resp) |
int | respprep (struct mgcp_request *resp, struct mgcp_endpoint *p, char *msg, struct mgcp_request *req, char *msgrest) |
int | restart_monitor (void) |
int | retrans_pkt (void *data) |
void | sdpLineNum_iterator_init (int *iterator) |
int | send_request (struct mgcp_endpoint *p, struct mgcp_subchannel *sub, struct mgcp_request *req, unsigned int seqno) |
int | send_response (struct mgcp_subchannel *sub, struct mgcp_request *req) |
void | start_rtp (struct mgcp_subchannel *sub) |
int | transmit_audit_endpoint (struct mgcp_endpoint *p) |
int | transmit_connect_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp *rtp) |
int | transmit_connection_del (struct mgcp_subchannel *sub) |
int | transmit_connection_del_w_params (struct mgcp_endpoint *p, char *callid, char *cxident) |
int | transmit_modify_request (struct mgcp_subchannel *sub) |
int | transmit_modify_with_sdp (struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs) |
int | transmit_notify_request (struct mgcp_subchannel *sub, char *tone) |
int | transmit_notify_request_with_callerid (struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername) |
int | transmit_response (struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest) |
int | unalloc_sub (struct mgcp_subchannel *sub) |
int | unload_module () |
Cleanup all module structures, sockets, etc. | |
int | usecount () |
Provides a usecount. | |
Variables | |
in_addr | __ourip |
char | accountcode [AST_MAX_ACCOUNT_CODE] = "" |
int | adsi = 0 |
int | amaflags = 0 |
char | audit_endpoint_usage [] |
sockaddr_in | bindaddr |
int | callreturn = 0 |
int | callwaiting = 0 |
int | cancallforward = 0 |
int | canreinvite = CANREINVITE |
int | capability = AST_FORMAT_ULAW |
char | cid_name [AST_MAX_EXTENSION] = "" |
char | cid_num [AST_MAX_EXTENSION] = "" |
ast_cli_entry | cli_audit_endpoint |
ast_cli_entry | cli_debug |
ast_cli_entry | cli_mgcp_reload |
ast_cli_entry | cli_no_debug |
ast_cli_entry | cli_show_endpoints |
const char | config [] = "mgcp.conf" |
char | context [AST_MAX_EXTENSION] = "default" |
ast_group_t | cur_callergroup = 0 |
ast_group_t | cur_pickupgroup = 0 |
char | debug_usage [] |
const char | desc [] = "Media Gateway Control Protocol (MGCP)" |
int | dtmfmode = 0 |
int | firstdigittimeout = 16000 |
mgcp_gateway * | gateways |
int | gendigittimeout = 8000 |
int | immediate = 0 |
io_context * | io |
char | language [MAX_LANGUAGE] = "" |
char | mailbox [AST_MAX_EXTENSION] |
int | matchdigittimeout = 3000 |
char * | mgcp_cxmodes [] |
char | mgcp_reload_usage [] |
int | mgcp_reloading = 0 |
ast_rtp_protocol | mgcp_rtp |
const struct ast_channel_tech | mgcp_tech |
int | mgcpdebug = 0 |
int | mgcpsock = -1 |
int * | mgcpsock_read_id = NULL |
pthread_t | monitor_thread = AST_PTHREADT_NULL |
char | musicclass [MAX_MUSICCLASS] = "" |
int | nat = 0 |
char | no_debug_usage [] |
int | nonCodecCapability = AST_RTP_DTMF |
unsigned int | oseq |
char | ourhost [MAXHOSTNAMELEN] |
int | ourport |
sched_context * | sched |
char | show_endpoints_usage [] |
int | singlepath = 0 |
int | slowsequence = 0 |
const char | tdesc [] = "Media Gateway Control Protocol (MGCP)" |
int | threewaycalling = 0 |
int | tos = 0 |
int | transfer = 0 |
const char | type [] = "MGCP" |
int | usecnt = 0 |
Definition in file chan_mgcp.c.
|
Definition at line 130 of file chan_mgcp.c. |
|
Definition at line 128 of file chan_mgcp.c. |
|
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 mgcp_postrequest(). |
|
Definition at line 133 of file chan_mgcp.c. |
|
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. |
|
Definition at line 333 of file chan_mgcp.c. |
|
Definition at line 176 of file chan_mgcp.c. |
|
Definition at line 175 of file chan_mgcp.c. |
|
Definition at line 170 of file chan_mgcp.c. Referenced by send_request(). |
|
Definition at line 172 of file chan_mgcp.c. Referenced by send_request(). |
|
Definition at line 169 of file chan_mgcp.c. |
|
Definition at line 171 of file chan_mgcp.c. Referenced by send_request(). |
|
Definition at line 174 of file chan_mgcp.c. |
|
Definition at line 173 of file chan_mgcp.c. Referenced by send_request(). |
|
Definition at line 177 of file chan_mgcp.c. |
|
Definition at line 155 of file chan_mgcp.c. |
|
Definition at line 156 of file chan_mgcp.c. |
|
Definition at line 158 of file chan_mgcp.c. |
|
Definition at line 157 of file chan_mgcp.c. |
|
Definition at line 153 of file chan_mgcp.c. |
|
Definition at line 152 of file chan_mgcp.c. |
|
Definition at line 154 of file chan_mgcp.c. |
|
Definition at line 143 of file chan_mgcp.c. |
|
Definition at line 142 of file chan_mgcp.c. Referenced by mgcp_new(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 141 of file chan_mgcp.c. |
|
Definition at line 282 of file chan_mgcp.c. Referenced by parse(). |
|
Definition at line 283 of file chan_mgcp.c. Referenced by parse(). |
|
Definition at line 147 of file chan_mgcp.c. |
|
Definition at line 375 of file chan_mgcp.c. Referenced by mgcp_call(), transmit_modify_request(), transmit_notify_request(), and transmit_notify_request_with_callerid(). |
|
Definition at line 374 of file chan_mgcp.c. Referenced by mgcp_call(), 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. |
|
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. |
|
Definition at line 377 of file chan_mgcp.c. |
|
Definition at line 1495 of file chan_mgcp.c. References mgcp_request::header, mgcp_request::headers, and name. 01496 { 01497 int x; 01498 int len = strlen(name); 01499 char *r; 01500 for (x=*start;x<req->headers;x++) { 01501 if (!strncasecmp(req->header[x], name, len) && 01502 (req->header[x][len] == ':')) { 01503 r = req->header[x] + len + 1; 01504 while(*r && (*r < 33)) 01505 r++; 01506 *start = x+1; 01507 return r; 01508 } 01509 } 01510 /* Don't return NULL, so get_header is always a valid pointer */ 01511 return ""; 01512 }
|
|
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 1847 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_request::len, mgcp_request::lines, LOG_WARNING, and var. 01848 { 01849 if (req->len >= sizeof(req->data) - 4) { 01850 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 01851 return -1; 01852 } 01853 if (req->lines) { 01854 ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n"); 01855 return -1; 01856 } 01857 req->header[req->headers] = req->data + req->len; 01858 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s: %s\r\n", var, value); 01859 req->len += strlen(req->header[req->headers]); 01860 if (req->headers < MGCP_MAX_HEADERS) 01861 req->headers++; 01862 else { 01863 ast_log(LOG_WARNING, "Out of header space\n"); 01864 return -1; 01865 } 01866 return 0; 01867 }
|
|
Definition at line 1869 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::len, mgcp_request::line, mgcp_request::lines, and LOG_WARNING. 01870 { 01871 if (req->len >= sizeof(req->data) - 4) { 01872 ast_log(LOG_WARNING, "Out of space, can't add anymore\n"); 01873 return -1; 01874 } 01875 if (!req->lines) { 01876 /* Add extra empty return */ 01877 snprintf(req->data + req->len, sizeof(req->data) - req->len, "\r\n"); 01878 req->len += strlen(req->data + req->len); 01879 } 01880 req->line[req->lines] = req->data + req->len; 01881 snprintf(req->line[req->lines], sizeof(req->data) - req->len, "%s", line); 01882 req->len += strlen(req->line[req->lines]); 01883 if (req->lines < MGCP_MAX_LINES) 01884 req->lines++; 01885 else { 01886 ast_log(LOG_WARNING, "Out of line space\n"); 01887 return -1; 01888 } 01889 return 0; 01890 }
|
|
Definition at line 1971 of file chan_mgcp.c. References add_line(), ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_us(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_verbose(), mgcp_endpoint::capability, LOG_WARNING, mgcp_endpoint::nonCodecCapability, mgcp_gateway::ourip, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, s, and mgcp_subchannel::tmpdest. 01972 { 01973 int len; 01974 int codec; 01975 char costr[80]; 01976 struct sockaddr_in sin; 01977 char v[256]; 01978 char s[256]; 01979 char o[256]; 01980 char c[256]; 01981 char t[256]; 01982 char m[256] = ""; 01983 char a[1024] = ""; 01984 char iabuf[INET_ADDRSTRLEN]; 01985 int x; 01986 struct sockaddr_in dest; 01987 struct mgcp_endpoint *p = sub->parent; 01988 /* XXX We break with the "recommendation" and send our IP, in order that our 01989 peer doesn't have to ast_gethostbyname() us XXX */ 01990 len = 0; 01991 if (!sub->rtp) { 01992 ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n"); 01993 return -1; 01994 } 01995 ast_rtp_get_us(sub->rtp, &sin); 01996 if (rtp) { 01997 ast_rtp_get_peer(rtp, &dest); 01998 } else { 01999 if (sub->tmpdest.sin_addr.s_addr) { 02000 dest.sin_addr = sub->tmpdest.sin_addr; 02001 dest.sin_port = sub->tmpdest.sin_port; 02002 /* Reset temporary destination */ 02003 memset(&sub->tmpdest, 0, sizeof(sub->tmpdest)); 02004 } else { 02005 dest.sin_addr = p->parent->ourip; 02006 dest.sin_port = sin.sin_port; 02007 } 02008 } 02009 if (mgcpdebug) { 02010 ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->ourip), ntohs(sin.sin_port)); 02011 } 02012 snprintf(v, sizeof(v), "v=0\r\n"); 02013 snprintf(o, sizeof(o), "o=root %d %d IN IP4 %s\r\n", getpid(), getpid(), ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02014 snprintf(s, sizeof(s), "s=session\r\n"); 02015 snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), dest.sin_addr)); 02016 snprintf(t, sizeof(t), "t=0 0\r\n"); 02017 snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port)); 02018 for (x = 1; x <= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02019 if (p->capability & x) { 02020 if (mgcpdebug) { 02021 ast_verbose("Answering with capability %d\n", x); 02022 } 02023 codec = ast_rtp_lookup_code(sub->rtp, 1, x); 02024 if (codec > -1) { 02025 snprintf(costr, sizeof(costr), " %d", codec); 02026 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02027 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(1, x)); 02028 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02029 } 02030 } 02031 } 02032 for (x = 1; x <= AST_RTP_MAX; x <<= 1) { 02033 if (p->nonCodecCapability & x) { 02034 if (mgcpdebug) { 02035 ast_verbose("Answering with non-codec capability %d\n", x); 02036 } 02037 codec = ast_rtp_lookup_code(sub->rtp, 0, x); 02038 if (codec > -1) { 02039 snprintf(costr, sizeof(costr), " %d", codec); 02040 strncat(m, costr, sizeof(m) - strlen(m) - 1); 02041 snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype(0, x)); 02042 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02043 if (x == AST_RTP_DTMF) { 02044 /* Indicate we support DTMF... Not sure about 16, 02045 but MSN supports it so dang it, we will too... */ 02046 snprintf(costr, sizeof costr, "a=fmtp:%d 0-16\r\n", codec); 02047 strncat(a, costr, sizeof(a) - strlen(a) - 1); 02048 } 02049 } 02050 } 02051 } 02052 strncat(m, "\r\n", sizeof(m) - strlen(m) - 1); 02053 len = strlen(v) + strlen(s) + strlen(o) + strlen(c) + strlen(t) + strlen(m) + strlen(a); 02054 snprintf(costr, sizeof(costr), "%d", len); 02055 add_line(resp, v); 02056 add_line(resp, o); 02057 add_line(resp, s); 02058 add_line(resp, c); 02059 add_line(resp, t); 02060 add_line(resp, m); 02061 add_line(resp, a); 02062 return 0; 02063 }
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 2844 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_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. 02845 { 02846 /* ************************* 02847 * I hope this works. 02848 * Copied out of chan_zap 02849 * Cross your fingers 02850 * *************************/ 02851 02852 /* In order to transfer, we need at least one of the channels to 02853 actually be in a call bridge. We can't conference two applications 02854 together (but then, why would we want to?) */ 02855 if (ast_bridged_channel(p->sub->owner)) { 02856 /* The three-way person we're about to transfer to could still be in MOH, so 02857 stop if now if appropriate */ 02858 if (ast_bridged_channel(p->sub->next->owner)) 02859 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02860 if (p->sub->owner->_state == AST_STATE_RINGING) { 02861 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02862 } 02863 if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { 02864 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02865 ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); 02866 return -1; 02867 } 02868 /* Orphan the channel */ 02869 unalloc_sub(p->sub->next); 02870 } else if (ast_bridged_channel(p->sub->next->owner)) { 02871 if (p->sub->owner->_state == AST_STATE_RINGING) { 02872 ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); 02873 } 02874 ast_moh_stop(ast_bridged_channel(p->sub->next->owner)); 02875 if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { 02876 ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", 02877 ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); 02878 return -1; 02879 } 02880 /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ 02881 if (option_verbose > 2) { 02882 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); 02883 } 02884 p->sub = p->sub->next; 02885 unalloc_sub(p->sub->next); 02886 /* Tell the caller not to hangup */ 02887 return 1; 02888 } else { 02889 ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n", 02890 p->sub->owner->name, p->sub->next->owner->name); 02891 p->sub->next->owner->_softhangup |= AST_SOFTHANGUP_DEV; 02892 if (p->sub->next->owner) { 02893 p->sub->next->alreadygone = 1; 02894 mgcp_queue_hangup(p->sub->next); 02895 } 02896 } 02897 return 0; 02898 }
|
|
Definition at line 3554 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, mgcp_endpoint::capability, mgcp_endpoint::cid_name, cid_name, mgcp_endpoint::cid_num, cid_num, mgcp_endpoint::cmd_queue_lock, 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, mgcp_gateway::ha, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_endpoint::immediate, immediate, mgcp_gateway::isnamedottedip, mgcp_endpoint::language, language, ast_variable::lineno, mgcp_subchannel::lock, mgcp_endpoint::lock, LOG_WARNING, mgcp_subchannel::magic, mgcp_endpoint::mailbox, mailbox, malloc, MGCP_SUBCHANNEL_MAGIC, mgcp_gateway::msgs_lock, mgcp_endpoint::msgstate, mgcp_endpoint::musicclass, musicclass, mgcp_endpoint::name, ast_variable::name, mgcp_gateway::name, mgcp_subchannel::nat, nat, mgcp_endpoint::needaudit, 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_gateway::retransid, mgcp_endpoint::rqnt_ident, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, sched, 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, ast_variable::value, VERBOSE_PREFIX_3, and mgcp_gateway::wcardep. Referenced by reload_config(). 03555 { 03556 struct mgcp_gateway *gw; 03557 struct mgcp_endpoint *e; 03558 struct mgcp_subchannel *sub; 03559 /*char txident[80];*/ 03560 int i=0, y=0; 03561 int gw_reload = 0; 03562 int ep_reload = 0; 03563 canreinvite = CANREINVITE; 03564 03565 /* SC: locate existing gateway */ 03566 gw = gateways; 03567 while (gw) { 03568 if (!strcasecmp(cat, gw->name)) { 03569 /* gateway already exists */ 03570 gw->delme = 0; 03571 gw_reload = 1; 03572 break; 03573 } 03574 gw = gw->next; 03575 } 03576 03577 if (!gw) 03578 gw = malloc(sizeof(struct mgcp_gateway)); 03579 03580 if (gw) { 03581 if (!gw_reload) { 03582 memset(gw, 0, sizeof(struct mgcp_gateway)); 03583 gw->expire = -1; 03584 gw->retransid = -1; /* SC */ 03585 ast_mutex_init(&gw->msgs_lock); 03586 strncpy(gw->name, cat, sizeof(gw->name) - 1); 03587 /* SC: check if the name is numeric ip */ 03588 if ((strchr(gw->name, '.')) && inet_addr(gw->name) != INADDR_NONE) 03589 gw->isnamedottedip = 1; 03590 } 03591 while(v) { 03592 if (!strcasecmp(v->name, "host")) { 03593 if (!strcasecmp(v->value, "dynamic")) { 03594 /* They'll register with us */ 03595 gw->dynamic = 1; 03596 memset(&gw->addr.sin_addr, 0, 4); 03597 if (gw->addr.sin_port) { 03598 /* If we've already got a port, make it the default rather than absolute */ 03599 gw->defaddr.sin_port = gw->addr.sin_port; 03600 gw->addr.sin_port = 0; 03601 } 03602 } else { 03603 /* Non-dynamic. Make sure we become that way if we're not */ 03604 if (gw->expire > -1) 03605 ast_sched_del(sched, gw->expire); 03606 gw->expire = -1; 03607 gw->dynamic = 0; 03608 if (ast_get_ip(&gw->addr, v->value)) { 03609 if (!gw_reload) { 03610 ast_mutex_destroy(&gw->msgs_lock); 03611 free(gw); 03612 } 03613 return NULL; 03614 } 03615 } 03616 } else if (!strcasecmp(v->name, "defaultip")) { 03617 if (ast_get_ip(&gw->defaddr, v->value)) { 03618 if (!gw_reload) { 03619 ast_mutex_destroy(&gw->msgs_lock); 03620 free(gw); 03621 } 03622 return NULL; 03623 } 03624 } else if (!strcasecmp(v->name, "permit") || 03625 !strcasecmp(v->name, "deny")) { 03626 gw->ha = ast_append_ha(v->name, v->value, gw->ha); 03627 } else if (!strcasecmp(v->name, "port")) { 03628 gw->addr.sin_port = htons(atoi(v->value)); 03629 } else if (!strcasecmp(v->name, "context")) { 03630 strncpy(context, v->value, sizeof(context) - 1); 03631 } else if (!strcasecmp(v->name, "dtmfmode")) { 03632 if (!strcasecmp(v->value, "inband")) 03633 dtmfmode = MGCP_DTMF_INBAND; 03634 else if (!strcasecmp(v->value, "rfc2833")) 03635 dtmfmode = MGCP_DTMF_RFC2833; 03636 else if (!strcasecmp(v->value, "hybrid")) 03637 dtmfmode = MGCP_DTMF_HYBRID; 03638 else if (!strcasecmp(v->value, "none")) 03639 dtmfmode = 0; 03640 else 03641 ast_log(LOG_WARNING, "'%s' is not a valid DTMF mode at line %d\n", v->value, v->lineno); 03642 } else if (!strcasecmp(v->name, "nat")) { 03643 nat = ast_true(v->value); 03644 } else if (!strcasecmp(v->name, "callerid")) { 03645 if (!strcasecmp(v->value, "asreceived")) { 03646 cid_num[0] = '\0'; 03647 cid_name[0] = '\0'; 03648 } else { 03649 ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); 03650 } 03651 } else if (!strcasecmp(v->name, "language")) { 03652 strncpy(language, v->value, sizeof(language)-1); 03653 } else if (!strcasecmp(v->name, "accountcode")) { 03654 strncpy(accountcode, v->value, sizeof(accountcode)-1); 03655 } else if (!strcasecmp(v->name, "amaflags")) { 03656 y = ast_cdr_amaflags2int(v->value); 03657 if (y < 0) { 03658 ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n", v->value, v->lineno); 03659 } else { 03660 amaflags = y; 03661 } 03662 } else if (!strcasecmp(v->name, "musiconhold")) { 03663 strncpy(musicclass, v->value, sizeof(musicclass)-1); 03664 } else if (!strcasecmp(v->name, "callgroup")) { 03665 cur_callergroup = ast_get_group(v->value); 03666 } else if (!strcasecmp(v->name, "pickupgroup")) { 03667 cur_pickupgroup = ast_get_group(v->value); 03668 } else if (!strcasecmp(v->name, "immediate")) { 03669 immediate = ast_true(v->value); 03670 } else if (!strcasecmp(v->name, "cancallforward")) { 03671 cancallforward = ast_true(v->value); 03672 } else if (!strcasecmp(v->name, "singlepath")) { 03673 singlepath = ast_true(v->value); 03674 } else if (!strcasecmp(v->name, "canreinvite")) { 03675 canreinvite = ast_true(v->value); 03676 } else if (!strcasecmp(v->name, "mailbox")) { 03677 strncpy(mailbox, v->value, sizeof(mailbox) -1); 03678 } else if (!strcasecmp(v->name, "adsi")) { 03679 adsi = ast_true(v->value); 03680 } else if (!strcasecmp(v->name, "callreturn")) { 03681 callreturn = ast_true(v->value); 03682 } else if (!strcasecmp(v->name, "callwaiting")) { 03683 callwaiting = ast_true(v->value); 03684 } else if (!strcasecmp(v->name, "slowsequence")) { 03685 slowsequence = ast_true(v->value); 03686 } else if (!strcasecmp(v->name, "transfer")) { 03687 transfer = ast_true(v->value); 03688 } else if (!strcasecmp(v->name, "threewaycalling")) { 03689 threewaycalling = ast_true(v->value); 03690 } else if (!strcasecmp(v->name, "wcardep")) { 03691 /* SC: locate existing endpoint */ 03692 e = gw->endpoints; 03693 while (e) { 03694 if (!strcasecmp(v->value, e->name)) { 03695 /* endpoint already exists */ 03696 e->delme = 0; 03697 ep_reload = 1; 03698 break; 03699 } 03700 e = e->next; 03701 } 03702 03703 if (!e) { 03704 /* Allocate wildcard endpoint */ 03705 e = malloc(sizeof(struct mgcp_endpoint)); 03706 ep_reload = 0; 03707 } 03708 03709 if (e) { 03710 if (!ep_reload) { 03711 memset(e, 0, sizeof(struct mgcp_endpoint)); 03712 ast_mutex_init(&e->lock); 03713 ast_mutex_init(&e->rqnt_queue_lock); 03714 ast_mutex_init(&e->cmd_queue_lock); 03715 strncpy(e->name, v->value, sizeof(e->name) - 1); 03716 e->needaudit = 1; 03717 } 03718 strncpy(gw->wcardep, v->value, sizeof(gw->wcardep) - 1); 03719 /*strncpy(e->name, "aaln/" "*", sizeof(e->name) - 1);*/ 03720 /* XXX Should we really check for uniqueness?? XXX */ 03721 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03722 strncpy(e->context, context, sizeof(e->context) - 1); 03723 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03724 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03725 strncpy(e->language, language, sizeof(e->language) - 1); 03726 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03727 strncpy(e->mailbox, mailbox, sizeof(e->mailbox) - 1); 03728 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03729 e->msgstate = -1; 03730 e->amaflags = amaflags; 03731 e->capability = capability; 03732 e->parent = gw; 03733 e->dtmfmode = dtmfmode; 03734 if (!ep_reload && e->sub && e->sub->rtp) 03735 e->dtmfmode |= MGCP_DTMF_INBAND; 03736 e->adsi = adsi; 03737 e->type = TYPE_LINE; 03738 e->immediate = immediate; 03739 e->callgroup=cur_callergroup; 03740 e->pickupgroup=cur_pickupgroup; 03741 e->callreturn = callreturn; 03742 e->cancallforward = cancallforward; 03743 e->singlepath = singlepath; 03744 e->canreinvite = canreinvite; 03745 e->callwaiting = callwaiting; 03746 e->hascallwaiting = callwaiting; 03747 e->slowsequence = slowsequence; 03748 e->transfer = transfer; 03749 e->threewaycalling = threewaycalling; 03750 e->onhooktime = time(NULL); 03751 /* ASSUME we're onhook */ 03752 e->hookstate = MGCP_ONHOOK; 03753 if (!ep_reload) { 03754 /*snprintf(txident, sizeof(txident), "%08x", rand());*/ 03755 for (i = 0; i < MAX_SUBS; i++) { 03756 sub = malloc(sizeof(struct mgcp_subchannel)); 03757 if (sub) { 03758 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03759 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03760 ast_mutex_init(&sub->lock); 03761 ast_mutex_init(&sub->cx_queue_lock); 03762 sub->parent = e; 03763 sub->id = i; 03764 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03765 /*stnrcpy(sub->txident, txident, sizeof(sub->txident) - 1);*/ 03766 sub->cxmode = MGCP_CX_INACTIVE; 03767 sub->nat = nat; 03768 sub->next = e->sub; 03769 e->sub = sub; 03770 } else { 03771 /* XXX Should find a way to clean up our memory */ 03772 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03773 return NULL; 03774 } 03775 } 03776 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03777 sub = e->sub; 03778 /* find the end of the list */ 03779 while(sub->next){ 03780 sub = sub->next; 03781 } 03782 /* set the last sub->next to the first sub */ 03783 sub->next = e->sub; 03784 03785 e->next = gw->endpoints; 03786 gw->endpoints = e; 03787 } 03788 } 03789 } else if (!strcasecmp(v->name, "trunk") || 03790 !strcasecmp(v->name, "line")) { 03791 03792 /* SC: locate existing endpoint */ 03793 e = gw->endpoints; 03794 while (e) { 03795 if (!strcasecmp(v->value, e->name)) { 03796 /* endpoint already exists */ 03797 e->delme = 0; 03798 ep_reload = 1; 03799 break; 03800 } 03801 e = e->next; 03802 } 03803 03804 if (!e) { 03805 e = malloc(sizeof(struct mgcp_endpoint)); 03806 ep_reload = 0; 03807 } 03808 03809 if (e) { 03810 if (!ep_reload) { 03811 memset(e, 0, sizeof(struct mgcp_endpoint)); 03812 ast_mutex_init(&e->lock); 03813 ast_mutex_init(&e->rqnt_queue_lock); 03814 ast_mutex_init(&e->cmd_queue_lock); 03815 strncpy(e->name, v->value, sizeof(e->name) - 1); 03816 e->needaudit = 1; 03817 } 03818 /* XXX Should we really check for uniqueness?? XXX */ 03819 strncpy(e->accountcode, accountcode, sizeof(e->accountcode) - 1); 03820 strncpy(e->context, context, sizeof(e->context) - 1); 03821 strncpy(e->cid_num, cid_num, sizeof(e->cid_num) - 1); 03822 strncpy(e->cid_name, cid_name, sizeof(e->cid_name) - 1); 03823 strncpy(e->language, language, sizeof(e->language) - 1); 03824 strncpy(e->musicclass, musicclass, sizeof(e->musicclass) - 1); 03825 strncpy(e->mailbox, mailbox, sizeof(e->mailbox)-1); 03826 if (!ast_strlen_zero(mailbox)) { 03827 ast_verbose(VERBOSE_PREFIX_3 "Setting mailbox '%s' on %s@%s\n", mailbox, gw->name, e->name); 03828 } 03829 if (!ep_reload) { 03830 /* XXX SC: potential issue due to reload */ 03831 e->msgstate = -1; 03832 e->parent = gw; 03833 } 03834 e->amaflags = amaflags; 03835 e->capability = capability; 03836 e->dtmfmode = dtmfmode; 03837 e->adsi = adsi; 03838 if (!strcasecmp(v->name, "trunk")) 03839 e->type = TYPE_TRUNK; 03840 else 03841 e->type = TYPE_LINE; 03842 03843 e->immediate = immediate; 03844 e->callgroup=cur_callergroup; 03845 e->pickupgroup=cur_pickupgroup; 03846 e->callreturn = callreturn; 03847 e->cancallforward = cancallforward; 03848 e->canreinvite = canreinvite; 03849 e->singlepath = singlepath; 03850 e->callwaiting = callwaiting; 03851 e->hascallwaiting = callwaiting; 03852 e->slowsequence = slowsequence; 03853 e->transfer = transfer; 03854 e->threewaycalling = threewaycalling; 03855 if (!ep_reload) { 03856 e->onhooktime = time(NULL); 03857 /* ASSUME we're onhook */ 03858 e->hookstate = MGCP_ONHOOK; 03859 snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08x", rand()); 03860 } 03861 03862 for (i = 0, sub = NULL; i < MAX_SUBS; i++) { 03863 if (!ep_reload) { 03864 sub = malloc(sizeof(struct mgcp_subchannel)); 03865 } else { 03866 if (!sub) 03867 sub = e->sub; 03868 else 03869 sub = sub->next; 03870 } 03871 03872 if (sub) { 03873 if (!ep_reload) { 03874 ast_verbose(VERBOSE_PREFIX_3 "Allocating subchannel '%d' on %s@%s\n", i, e->name, gw->name); 03875 memset(sub, 0, sizeof(struct mgcp_subchannel)); 03876 ast_mutex_init(&sub->lock); 03877 ast_mutex_init(&sub->cx_queue_lock); 03878 strncpy(sub->magic, MGCP_SUBCHANNEL_MAGIC, sizeof(sub->magic) - 1); 03879 sub->parent = e; 03880 sub->id = i; 03881 snprintf(sub->txident, sizeof(sub->txident), "%08x", rand()); 03882 sub->cxmode = MGCP_CX_INACTIVE; 03883 sub->next = e->sub; 03884 e->sub = sub; 03885 } 03886 sub->nat = nat; 03887 } else { 03888 /* XXX Should find a way to clean up our memory */ 03889 ast_log(LOG_WARNING, "Out of memory allocating subchannel"); 03890 return NULL; 03891 } 03892 } 03893 if (!ep_reload) { 03894 /* Make out subs a circular linked list so we can always sping through the whole bunch */ 03895 sub = e->sub; 03896 /* find the end of the list */ 03897 while (sub->next) { 03898 sub = sub->next; 03899 } 03900 /* set the last sub->next to the first sub */ 03901 sub->next = e->sub; 03902 03903 e->next = gw->endpoints; 03904 gw->endpoints = e; 03905 } 03906 } 03907 } else 03908 ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno); 03909 v = v->next; 03910 } 03911 } 03912 if (!ntohl(gw->addr.sin_addr.s_addr) && !gw->dynamic) { 03913 ast_log(LOG_WARNING, "Gateway '%s' lacks IP address and isn't dynamic\n", gw->name); 03914 if (!gw_reload) { 03915 ast_mutex_destroy(&gw->msgs_lock); 03916 free(gw); 03917 } 03918 return NULL; 03919 } 03920 gw->defaddr.sin_family = AF_INET; 03921 gw->addr.sin_family = AF_INET; 03922 if (gw->defaddr.sin_addr.s_addr && !ntohs(gw->defaddr.sin_port)) 03923 gw->defaddr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03924 if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port)) 03925 gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT); 03926 if (gw->addr.sin_addr.s_addr) 03927 if (ast_ouraddrfor(&gw->addr.sin_addr, &gw->ourip)) 03928 memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip)); 03929 03930 return (gw_reload ? NULL : gw); 03931 }
|
|
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. 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 4406 of file chan_mgcp.c. 04407 { 04408 return (char *) desc; 04409 }
|
|
|
Definition at line 4040 of file chan_mgcp.c. References ast_free_ha(), dump_queue(), free, and mgcp_gateway::ha. Referenced by prune_gateways(). 04041 { 04042 if (g->ha) 04043 ast_free_ha(g->ha); 04044 04045 dump_queue(g, NULL); 04046 04047 free (g); 04048 }
|
|
Definition at line 3384 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(), has_voicemail(), io, mgcp_do_reload(), mgcp_reloading, mgcpsock, mgcpsock_read(), mgcpsock_read_id, mgcp_subchannel::next, option_verbose, sched, transmit_notify_request(), and VERBOSE_PREFIX_1. Referenced by restart_monitor(). 03385 { 03386 int res; 03387 int reloading; 03388 /*struct mgcp_gateway *g;*/ 03389 /*struct mgcp_endpoint *e;*/ 03390 /*time_t thispass = 0, lastpass = 0;*/ 03391 03392 /* Add an I/O event to our UDP socket */ 03393 if (mgcpsock > -1) 03394 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03395 03396 /* This thread monitors all the frame relay interfaces which are not yet in use 03397 (and thus do not have a separate thread) indefinitely */ 03398 /* From here on out, we die whenever asked */ 03399 for(;;) { 03400 /* Check for a reload request */ 03401 ast_mutex_lock(&mgcp_reload_lock); 03402 reloading = mgcp_reloading; 03403 mgcp_reloading = 0; 03404 ast_mutex_unlock(&mgcp_reload_lock); 03405 if (reloading) { 03406 if (option_verbose > 0) 03407 ast_verbose(VERBOSE_PREFIX_1 "Reloading MGCP\n"); 03408 mgcp_do_reload(); 03409 /* Add an I/O event to our UDP socket */ 03410 if (mgcpsock > -1) 03411 mgcpsock_read_id = ast_io_add(io, mgcpsock, mgcpsock_read, AST_IO_IN, NULL); 03412 } 03413 03414 /* Check for interfaces needing to be killed */ 03415 /* Don't let anybody kill us right away. Nobody should lock the interface list 03416 and wait for the monitor list, but the other way around is okay. */ 03417 ast_mutex_lock(&monlock); 03418 /* Lock the network interface */ 03419 ast_mutex_lock(&netlock); 03420 03421 #if 0 03422 /* XXX THIS IS COMPLETELY HOSED */ 03423 /* The gateway goes into a state of panic */ 03424 /* If the vmwi indicator is sent while it is reseting interfaces */ 03425 lastpass = thispass; 03426 thispass = time(NULL); 03427 g = gateways; 03428 while(g) { 03429 if (thispass != lastpass) { 03430 e = g->endpoints; 03431 while(e) { 03432 if (e->type == TYPE_LINE) { 03433 res = has_voicemail(e); 03434 if ((e->msgstate != res) && (e->hookstate == MGCP_ONHOOK) && (!e->rtp)){ 03435 if (res) { 03436 transmit_notify_request(e, "L/vmwi(+)"); 03437 } else { 03438 transmit_notify_request(e, "L/vmwi(-)"); 03439 } 03440 e->msgstate = res; 03441 e->onhooktime = thispass; 03442 } 03443 } 03444 e = e->next; 03445 } 03446 } 03447 g = g->next; 03448 } 03449 #endif 03450 /* Okay, now that we know what to do, release the network lock */ 03451 ast_mutex_unlock(&netlock); 03452 /* And from now on, we're okay to be killed, so release the monitor lock as well */ 03453 ast_mutex_unlock(&monlock); 03454 pthread_testcancel(); 03455 /* Wait for sched or io */ 03456 res = ast_sched_wait(sched); 03457 /* SC: copied from chan_sip.c */ 03458 if ((res < 0) || (res > 1000)) 03459 res = 1000; 03460 res = ast_io_wait(io, res); 03461 ast_mutex_lock(&monlock); 03462 if (res >= 0) 03463 ast_sched_runq(sched); 03464 ast_mutex_unlock(&monlock); 03465 } 03466 /* Never reached */ 03467 return NULL; 03468 }
|
|
|
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 3261 of file chan_mgcp.c. References free, mgcp_request::identifier, mgcp_response::next, mgcp_endpoint::parent, mgcp_subchannel::parent, resend_response(), and mgcp_gateway::responses. Referenced by mgcpsock_read(). 03262 { 03263 int seqno=0; 03264 time_t now; 03265 struct mgcp_response *prev = NULL, *cur, *next, *answer=NULL; 03266 time(&now); 03267 if (sscanf(req->identifier, "%d", &seqno) != 1) 03268 seqno = 0; 03269 cur = sub->parent->parent->responses; 03270 while(cur) { 03271 next = cur->next; 03272 if (now - cur->whensent > RESPONSE_TIMEOUT) { 03273 /* Delete this entry */ 03274 if (prev) 03275 prev->next = next; 03276 else 03277 sub->parent->parent->responses = next; 03278 free(cur); 03279 } else { 03280 if (seqno == cur->seqno) 03281 answer = cur; 03282 prev = cur; 03283 } 03284 cur = next; 03285 } 03286 if (answer) { 03287 resend_response(sub, answer); 03288 return 1; 03289 } 03290 return 0; 03291 }
|
|
Definition at line 2344 of file chan_mgcp.c. References mgcp_gateway::addr, ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), mgcp_postrequest(), mgcp_request::next, and mgcp_endpoint::parent. 02346 { 02347 struct mgcp_request *prev, *req; 02348 char iabuf[INET_ADDRSTRLEN]; 02349 02350 ast_mutex_lock(l); 02351 for (prev = NULL, req = *queue; req; prev = req, req = req->next) { 02352 if (req->trid == ident) { 02353 /* remove from queue */ 02354 if (!prev) 02355 *queue = req->next; 02356 else 02357 prev->next = req->next; 02358 02359 /* send next pending command */ 02360 if (*queue) { 02361 if (mgcpdebug) { 02362 ast_verbose("Posting Queued Request:\n%s to %s:%d\n", (*queue)->data, 02363 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 02364 } 02365 02366 mgcp_postrequest(p, sub, (*queue)->data, (*queue)->len, (*queue)->trid); 02367 } 02368 break; 02369 } 02370 } 02371 ast_mutex_unlock(l); 02372 return req; 02373 }
|
|
Definition at line 1542 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, mgcp_subchannel::id, mgcp_subchannel::lock, LOG_DEBUG, LOG_NOTICE, mgcp_endpoint::name, mgcp_gateway::name, name, mgcp_endpoint::next, mgcp_subchannel::next, mgcp_gateway::next, option_verbose, mgcp_gateway::ourip, mgcp_endpoint::sub, and VERBOSE_PREFIX_3. Referenced by mgcp_request(), and mgcpsock_read(). 01543 { 01544 struct mgcp_endpoint *p = NULL; 01545 struct mgcp_subchannel *sub = NULL; 01546 struct mgcp_gateway *g; 01547 char iabuf[INET_ADDRSTRLEN]; 01548 char tmp[256] = ""; 01549 char *at = NULL, *c; 01550 int found = 0; 01551 if (name) { 01552 strncpy(tmp, name, sizeof(tmp) - 1); 01553 at = strchr(tmp, '@'); 01554 if (!at) { 01555 ast_log(LOG_NOTICE, "Endpoint '%s' has no at sign!\n", name); 01556 return NULL; 01557 } 01558 *at = '\0'; 01559 at++; 01560 } 01561 ast_mutex_lock(&gatelock); 01562 if (at && (at[0] == '[')) { 01563 at++; 01564 c = strrchr(at, ']'); 01565 if (c) 01566 *c = '\0'; 01567 } 01568 g = gateways; 01569 while(g) { 01570 if ((!name || !strcasecmp(g->name, at)) && 01571 (sin || g->addr.sin_addr.s_addr || g->defaddr.sin_addr.s_addr)) { 01572 /* Found the gateway. If it's dynamic, save it's address -- now for the endpoint */ 01573 if (sin && g->dynamic && name) { 01574 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01575 (g->addr.sin_port != sin->sin_port)) { 01576 memcpy(&g->addr, sin, sizeof(g->addr)); 01577 if (ast_ouraddrfor(&g->addr.sin_addr, &g->ourip)) 01578 memcpy(&g->ourip, &__ourip, sizeof(g->ourip)); 01579 if (option_verbose > 2) 01580 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)); 01581 } 01582 } 01583 /* SC: not dynamic, check if the name matches */ 01584 else if (name) { 01585 if (strcasecmp(g->name, at)) { 01586 g = g->next; 01587 continue; 01588 } 01589 } 01590 /* SC: not dynamic, no name, check if the addr matches */ 01591 else if (!name && sin) { 01592 if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || 01593 (g->addr.sin_port != sin->sin_port)) { 01594 g = g->next; 01595 continue; 01596 } 01597 } else { 01598 g = g->next; 01599 continue; 01600 } 01601 /* SC */ 01602 p = g->endpoints; 01603 while(p) { 01604 if (option_debug) 01605 ast_log(LOG_DEBUG, "Searching on %s@%s for subchannel\n", 01606 p->name, g->name); 01607 if (msgid) { 01608 #if 0 /* SC: new transport mech */ 01609 sub = p->sub; 01610 do { 01611 if (option_debug) 01612 ast_log(LOG_DEBUG, "Searching on %s@%s-%d for subchannel with lastout: %d\n", 01613 p->name, g->name, sub->id, msgid); 01614 if (sub->lastout == msgid) { 01615 if (option_debug) 01616 ast_log(LOG_DEBUG, "Found subchannel sub%d to handle request %d sub->lastout: %d\n", 01617 sub->id, msgid, sub->lastout); 01618 found = 1; 01619 break; 01620 } 01621 sub = sub->next; 01622 } while (sub != p->sub); 01623 if (found) { 01624 break; 01625 } 01626 #endif 01627 /* SC */ 01628 sub = p->sub; 01629 found = 1; 01630 /* SC */ 01631 break; 01632 } else if (name && !strcasecmp(p->name, tmp)) { 01633 ast_log(LOG_DEBUG, "Coundn't determine subchannel, assuming current master %s@%s-%d\n", 01634 p->name, g->name, p->sub->id); 01635 sub = p->sub; 01636 found = 1; 01637 break; 01638 } 01639 p = p->next; 01640 } 01641 if (sub && found) { 01642 ast_mutex_lock(&sub->lock); 01643 break; 01644 } 01645 } 01646 g = g->next; 01647 } 01648 ast_mutex_unlock(&gatelock); 01649 if (!sub) { 01650 if (name) { 01651 if (g) 01652 ast_log(LOG_NOTICE, "Endpoint '%s' not found on gateway '%s'\n", tmp, at); 01653 else 01654 ast_log(LOG_NOTICE, "Gateway '%s' (and thus its endpoint '%s') does not exist\n", at, tmp); 01655 } 01656 } 01657 return sub; 01658 }
|
|
Definition at line 1521 of file chan_mgcp.c. References s. Referenced by handle_response(). 01522 { 01523 char *s; 01524 01525 *next = NULL, *len = 0; 01526 if (!c) return NULL; 01527 01528 while (*c && (*c < 33 || *c == ',')) 01529 c++; 01530 01531 s = c; 01532 while (*c && (*c >= 33 && *c != ',')) 01533 c++, (*len)++; 01534 *next = c; 01535 01536 if (*len == 0) 01537 s = NULL, *next = NULL; 01538 01539 return s; 01540 }
|
|
Definition at line 1514 of file chan_mgcp.c. References __get_header(), and name. 01515 { 01516 int start = 0; 01517 return __get_header(req, name, &start); 01518 }
|
|
Definition at line 1466 of file chan_mgcp.c. References get_sdp_by_line(), mgcp_request::line, mgcp_request::lines, and name. 01467 { 01468 int x; 01469 int len = strlen(name); 01470 char *r; 01471 01472 for (x=0; x<req->lines; x++) { 01473 r = get_sdp_by_line(req->line[x], name, len); 01474 if (r[0] != '\0') return r; 01475 } 01476 return ""; 01477 }
|
|
Definition at line 1456 of file chan_mgcp.c. References name. 01457 { 01458 if (strncasecmp(line, name, nameLen) == 0 && line[nameLen] == '=') { 01459 char* r = line + nameLen + 1; 01460 while (*r && (*r < 33)) ++r; 01461 return r; 01462 } 01463 return ""; 01464 }
|
|
Definition at line 1484 of file chan_mgcp.c. References get_sdp_by_line(), mgcp_request::line, mgcp_request::lines, and name. 01485 { 01486 int len = strlen(name); 01487 char *r; 01488 while (*iterator < req->lines) { 01489 r = get_sdp_by_line(req->line[(*iterator)++], name, len); 01490 if (r[0] != '\0') return r; 01491 } 01492 return ""; 01493 }
|
|
Definition at line 2900 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_new(), 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(), transmit_modify_request(), and transmit_notify_request(). Referenced by handle_request(). 02901 { 02902 struct mgcp_endpoint *p = sub->parent; 02903 struct ast_channel *c; 02904 pthread_t t; 02905 pthread_attr_t attr; 02906 pthread_attr_init(&attr); 02907 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 02908 02909 /* Off hook / answer */ 02910 if (sub->outgoing) { 02911 /* Answered */ 02912 if (sub->owner) { 02913 if (ast_bridged_channel(sub->owner)) { 02914 ast_moh_stop(ast_bridged_channel(sub->owner)); 02915 } 02916 sub->cxmode = MGCP_CX_SENDRECV; 02917 if (!sub->rtp) { 02918 start_rtp(sub); 02919 } else { 02920 transmit_modify_request(sub); 02921 } 02922 /*transmit_notify_request(sub, "aw");*/ 02923 transmit_notify_request(sub, ""); 02924 mgcp_queue_control(sub, AST_CONTROL_ANSWER); 02925 } 02926 } else { 02927 /* Start switch */ 02928 /*sub->cxmode = MGCP_CX_SENDRECV;*/ 02929 if (!sub->owner) { 02930 if (!sub->rtp) { 02931 start_rtp(sub); 02932 } else { 02933 transmit_modify_request(sub); 02934 } 02935 if (p->immediate) { 02936 /* The channel is immediately up. Start right away */ 02937 #ifdef DLINK_BUGGY_FIRMWARE 02938 transmit_notify_request(sub, "rt"); 02939 #else 02940 transmit_notify_request(sub, "G/rt"); 02941 #endif 02942 c = mgcp_new(sub, AST_STATE_RING); 02943 if (!c) { 02944 ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name); 02945 transmit_notify_request(sub, "G/cg"); 02946 ast_hangup(c); 02947 } 02948 } else { 02949 if (has_voicemail(p)) { 02950 transmit_notify_request(sub, "L/sl"); 02951 } else { 02952 transmit_notify_request(sub, "L/dl"); 02953 } 02954 c = mgcp_new(sub, AST_STATE_DOWN); 02955 if (c) { 02956 if (ast_pthread_create(&t, &attr, mgcp_ss, c)) { 02957 ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno)); 02958 ast_hangup(c); 02959 } 02960 } else { 02961 ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", p->name, p->parent->name); 02962 } 02963 } 02964 } else { 02965 if (p->hookstate == MGCP_OFFHOOK) { 02966 ast_log(LOG_WARNING, "Off hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02967 } else { 02968 ast_log(LOG_WARNING, "On hook, but already have owner on %s@%s\n", p->name, p->parent->name); 02969 ast_log(LOG_WARNING, "If we're onhook why are we here trying to handle a hd or hf?"); 02970 } 02971 if (ast_bridged_channel(sub->owner)) { 02972 ast_moh_stop(ast_bridged_channel(sub->owner)); 02973 } 02974 sub->cxmode = MGCP_CX_SENDRECV; 02975 if (!sub->rtp) { 02976 start_rtp(sub); 02977 } else { 02978 transmit_modify_request(sub); 02979 } 02980 /*transmit_notify_request(sub, "aw");*/ 02981 transmit_notify_request(sub, ""); 02982 /*ast_queue_control(sub->owner, AST_CONTROL_ANSWER);*/ 02983 } 02984 } 02985 }
|
|
Definition at line 2987 of file chan_mgcp.c. References ast_channel::_state, mgcp_subchannel::alreadygone, ast_bridged_channel(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, 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_queue_frame(), mgcp_queue_hangup(), mgcp_gateway::name, mgcp_endpoint::name, mgcp_endpoint::next, mgcp_subchannel::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. 02988 { 02989 char *ev, *s; 02990 struct ast_frame f = { 0, }; 02991 struct mgcp_endpoint *p = sub->parent; 02992 struct mgcp_gateway *g = NULL; 02993 char iabuf[INET_ADDRSTRLEN]; 02994 int res; 02995 02996 if (mgcpdebug) { 02997 ast_verbose("Handling request '%s' on %s@%s\n", req->verb, p->name, p->parent->name); 02998 } 02999 /* Clear out potential response */ 03000 if (!strcasecmp(req->verb, "RSIP")) { 03001 /* Test if this RSIP request is just a keepalive */ 03002 if(!strcasecmp( get_header(req, "RM"), "X-keepalive")) { 03003 if (option_verbose > 2) 03004 ast_verbose(VERBOSE_PREFIX_3 "Received keepalive request from %s@%s\n", p->name, p->parent->name); 03005 transmit_response(sub, "200", req, "OK"); 03006 } else { 03007 dump_queue(p->parent, p); 03008 dump_cmd_queues(p, NULL); 03009 03010 if (option_verbose > 2 && (strcmp(p->name, p->parent->wcardep) != 0)) { 03011 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", p->name, p->parent->name); 03012 } 03013 /* JS: For RSIP on wildcard we reset all endpoints */ 03014 if (!strcmp(p->name, p->parent->wcardep)) { 03015 /* Reset all endpoints */ 03016 struct mgcp_endpoint *tmp_ep; 03017 03018 g = p->parent; 03019 tmp_ep = g->endpoints; 03020 while (tmp_ep) { 03021 /*if ((strcmp(tmp_ep->name, "*") != 0) && (strcmp(tmp_ep->name, "aaln/" "*") != 0)) {*/ 03022 if (strcmp(tmp_ep->name, g->wcardep) != 0) { 03023 struct mgcp_subchannel *tmp_sub, *first_sub; 03024 if (option_verbose > 2) { 03025 ast_verbose(VERBOSE_PREFIX_3 "Resetting interface %s@%s\n", tmp_ep->name, p->parent->name); 03026 } 03027 03028 first_sub = tmp_ep->sub; 03029 tmp_sub = tmp_ep->sub; 03030 while (tmp_sub) { 03031 mgcp_queue_hangup(tmp_sub); 03032 tmp_sub = tmp_sub->next; 03033 if (tmp_sub == first_sub) 03034 break; 03035 } 03036 } 03037 tmp_ep = tmp_ep->next; 03038 } 03039 } else if (sub->owner) { 03040 mgcp_queue_hangup(sub); 03041 } 03042 transmit_response(sub, "200", req, "OK"); 03043 /* JS: We dont send NTFY or AUEP to wildcard ep */ 03044 if (strcmp(p->name, p->parent->wcardep) != 0) { 03045 transmit_notify_request(sub, ""); 03046 /* SC: Audit endpoint. 03047 Idea is to prevent lost lines due to race conditions 03048 */ 03049 transmit_audit_endpoint(p); 03050 } 03051 } 03052 } else if (!strcasecmp(req->verb, "NTFY")) { 03053 /* Acknowledge and be sure we keep looking for the same things */ 03054 transmit_response(sub, "200", req, "OK"); 03055 /* Notified of an event */ 03056 ev = get_header(req, "O"); 03057 s = strchr(ev, '/'); 03058 if (s) ev = s + 1; 03059 ast_log(LOG_DEBUG, "Endpoint '%s@%s-%d' observed '%s'\n", p->name, p->parent->name, sub->id, ev); 03060 /* Keep looking for events unless this was a hangup */ 03061 if (strcasecmp(ev, "hu") && strcasecmp(ev, "hd") && strcasecmp(ev, "ping")) { 03062 transmit_notify_request(sub, p->curtone); 03063 } 03064 if (!strcasecmp(ev, "hd")) { 03065 p->hookstate = MGCP_OFFHOOK; 03066 sub->cxmode = MGCP_CX_SENDRECV; 03067 handle_hd_hf(sub, ev); 03068 } else if (!strcasecmp(ev, "hf")) { 03069 /* We can assume we are offhook if we received a hookflash */ 03070 /* First let's just do call wait and ignore threeway */ 03071 /* We're currently in charge */ 03072 if (p->hookstate != MGCP_OFFHOOK) { 03073 /* Cisco c7940 sends hf even if the phone is onhook */ 03074 /* Thanks to point on IRC for pointing this out */ 03075 return -1; 03076 } 03077 /* do not let * conference two down channels */ 03078 if (sub->owner && sub->owner->_state == AST_STATE_DOWN && !sub->next->owner) 03079 return -1; 03080 03081 if (p->callwaiting || p->transfer || p->threewaycalling) { 03082 if (option_verbose > 2) { 03083 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); 03084 } 03085 p->sub = p->sub->next; 03086 03087 /* transfer control to our next subchannel */ 03088 if (!sub->next->owner) { 03089 /* plave the first call on hold and start up a new call */ 03090 sub->cxmode = MGCP_CX_MUTE; 03091 if (option_verbose > 2) { 03092 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03093 } 03094 transmit_modify_request(sub); 03095 if (sub->owner && ast_bridged_channel(sub->owner)) { 03096 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03097 } 03098 sub->next->cxmode = MGCP_CX_RECVONLY; 03099 handle_hd_hf(sub->next, ev); 03100 } else if (sub->owner && sub->next->owner) { 03101 /* We've got two active calls lets decide whether or not to conference or just flip flop */ 03102 if ((!sub->outgoing) && (!sub->next->outgoing)) { 03103 /* We made both calls lets conferenct */ 03104 if (option_verbose > 2) { 03105 ast_verbose(VERBOSE_PREFIX_3 "MGCP Conferencing %d and %d on %s@%s\n", 03106 sub->id, sub->next->id, p->name, p->parent->name); 03107 } 03108 sub->cxmode = MGCP_CX_CONF; 03109 sub->next->cxmode = MGCP_CX_CONF; 03110 if (ast_bridged_channel(sub->next->owner)) 03111 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03112 transmit_modify_request(sub); 03113 transmit_modify_request(sub->next); 03114 } else { 03115 /* Let's flipflop between calls */ 03116 /* XXX Need to check for state up ??? */ 03117 /* XXX Need a way to indicate the current call, or maybe the call that's waiting */ 03118 if (option_verbose > 2) { 03119 ast_verbose(VERBOSE_PREFIX_3 "We didn't make one of the calls FLIPFLOP %d and %d on %s@%s\n", 03120 sub->id, sub->next->id, p->name, p->parent->name); 03121 } 03122 sub->cxmode = MGCP_CX_MUTE; 03123 if (option_verbose > 2) { 03124 ast_verbose(VERBOSE_PREFIX_3 "MGCP Muting %d on %s@%s\n", sub->id, p->name, p->parent->name); 03125 } 03126 transmit_modify_request(sub); 03127 if (ast_bridged_channel(sub->owner)) 03128 ast_moh_start(ast_bridged_channel(sub->owner), NULL); 03129 03130 if (ast_bridged_channel(sub->next->owner)) 03131 ast_moh_stop(ast_bridged_channel(sub->next->owner)); 03132 03133 handle_hd_hf(sub->next, ev); 03134 #if 0 03135 if (sub->next->owner && (sub->next->owner->_state != AST_STATE_UP)) { 03136 handle_hd_hf(sub->next, ev); 03137 } else { 03138 ast_verbose(VERBOSE_PREFIX_3 "MGCP Unmuting %d on %s@%s\n", sub->next->id, p->name, p->parent->name); 03139 sub->next->cxmode = MGCP_CX_SENDRECV; 03140 transmit_modify_request(sub->next); 03141 } 03142 #endif 03143 } 03144 } else { 03145 /* We've most likely lost one of our calls find an active call and bring it up */ 03146 if (sub->owner) { 03147 p->sub = sub; 03148 } else if (sub->next->owner) { 03149 p->sub = sub->next; 03150 } else { 03151 /* We seem to have lost both our calls */ 03152 /* XXX - What do we do now? */ 03153 return -1; 03154 } 03155 if (ast_bridged_channel(p->sub->owner)) { 03156 ast_moh_stop(ast_bridged_channel(p->sub->owner)); 03157 } 03158 p->sub->cxmode = MGCP_CX_SENDRECV; 03159 transmit_modify_request(p->sub); 03160 } 03161 } else { 03162 ast_log(LOG_WARNING, "Callwaiting, call transfer or threeway calling not enabled on endpoint %s@%s\n", 03163 p->name, p->parent->name); 03164 } 03165 /*ast_moh_stop(sub->owner->bridge);*/ 03166 } else if (!strcasecmp(ev, "hu")) { 03167 p->hookstate = MGCP_ONHOOK; 03168 sub->cxmode = MGCP_CX_RECVONLY; 03169 ast_log(LOG_DEBUG, "MGCP %s@%s Went on hook\n", p->name, p->parent->name); 03170 /* JS: Do we need to send MDCX before a DLCX ? 03171 if (sub->rtp) { 03172 transmit_modify_request(sub); 03173 } 03174 */ 03175 if (p->transfer && (sub->owner && sub->next->owner) && ((!sub->outgoing) || (!sub->next->outgoing))) { 03176 /* We're allowed to transfer, we have two avtive calls and */ 03177 /* we made at least one of the calls. Let's try and transfer */ 03178 ast_mutex_lock(&p->sub->next->lock); 03179 res = attempt_transfer(p); 03180 if (res < 0) { 03181 if (p->sub->next->owner) { 03182 sub->next->alreadygone = 1; 03183 mgcp_queue_hangup(sub->next); 03184 } 03185 } else if (res) { 03186 ast_log(LOG_WARNING, "Transfer attempt failed\n"); 03187 ast_mutex_unlock(&p->sub->next->lock); 03188 return -1; 03189 } 03190 ast_mutex_unlock(&p->sub->next->lock); 03191 } else { 03192 /* Hangup the current call */ 03193 /* If there is another active call, mgcp_hangup will ring the phone with the other call */ 03194 if (sub->owner) { 03195 sub->alreadygone = 1; 03196 mgcp_queue_hangup(sub); 03197 } else { 03198 /* SC: verbose level check */ 03199 if (option_verbose > 2) { 03200 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s-%d) ast_channel already destroyed, resending DLCX.\n", 03201 p->name, p->parent->name, sub->id); 03202 } 03203 /* Instruct the other side to remove the connection since it apparently * 03204 * still thinks the channel is active. * 03205 * For Cisco IAD2421 /BAK/ */ 03206 transmit_connection_del(sub); 03207 } 03208 } 03209 if ((p->hookstate == MGCP_ONHOOK) && (!sub->rtp) && (!sub->next->rtp)) { 03210 p->hidecallerid = 0; 03211 if (p->hascallwaiting && !p->callwaiting) { 03212 if (option_verbose > 2) 03213 ast_verbose(VERBOSE_PREFIX_3 "Enabling call waiting on MGCP/%s@%s-%d\n", p->name, p->parent->name, sub->id); 03214 p->callwaiting = -1; 03215 } 03216 if (has_voicemail(p)) { 03217 if (option_verbose > 2) { 03218 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(+)\n", p->name, p->parent->name); 03219 } 03220 transmit_notify_request(sub, "L/vmwi(+)"); 03221 } else { 03222 if (option_verbose > 2) { 03223 ast_verbose(VERBOSE_PREFIX_3 "MGCP handle_request(%s@%s) set vmwi(-)\n", p->name, p->parent->name); 03224 } 03225 transmit_notify_request(sub, "L/vmwi(-)"); 03226 } 03227 } 03228 } else if ((strlen(ev) == 1) && 03229 (((ev[0] >= '0') && (ev[0] <= '9')) || 03230 ((ev[0] >= 'A') && (ev[0] <= 'D')) || 03231 (ev[0] == '*') || (ev[0] == '#'))) { 03232 f.frametype = AST_FRAME_DTMF; 03233 f.subclass = ev[0]; 03234 f.src = "mgcp"; 03235 if (sub->owner) { 03236 /* XXX MUST queue this frame to all subs in threeway call if threeway call is active */ 03237 mgcp_queue_frame(sub, &f); 03238 ast_mutex_lock(&sub->next->lock); 03239 if (sub->next->owner) { 03240 mgcp_queue_frame(sub->next, &f); 03241 } 03242 ast_mutex_unlock(&sub->next->lock); 03243 } 03244 if (strstr(p->curtone, "wt") && (ev[0] == 'A')) { 03245 memset(p->curtone, 0, sizeof(p->curtone)); 03246 } 03247 } else if (!strcasecmp(ev, "T")) { 03248 /* Digit timeout -- unimportant */ 03249 } else if (!strcasecmp(ev, "ping")) { 03250 /* ping -- unimportant */ 03251 } else { 03252 ast_log(LOG_NOTICE, "Received unknown event '%s' from %s@%s\n", ev, p->name, p->parent->name); 03253 } 03254 } else { 03255 ast_log(LOG_WARNING, "Unknown verb '%s' received from %s\n", req->verb, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr)); 03256 transmit_response(sub, "510", req, "Unknown verb"); 03257 } 03258 return 0; 03259 }
|
|
Definition at line 2376 of file chan_mgcp.c. References ast_log(), ast_strlen_zero(), ast_verbose(), mgcp_request::cmd, mgcp_endpoint::cmd_queue, mgcp_endpoint::cmd_queue_lock, mgcp_subchannel::cx_queue, mgcp_subchannel::cx_queue_lock, mgcp_subchannel::cxident, dump_cmd_queues(), find_command(), free, get_csv(), get_header(), mgcp_endpoint::hookstate, mgcp_subchannel::id, mgcp_request::lines, LOG_NOTICE, LOG_WARNING, mgcp_queue_hangup(), mgcp_endpoint::name, mgcp_gateway::name, mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_endpoint::parent, process_sdp(), result, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, mgcp_subchannel::rtp, mgcp_endpoint::slowsequence, start_rtp(), mgcp_endpoint::sub, mgcp_subchannel::tmpdest, transmit_connection_del(), transmit_connection_del_w_params(), transmit_modify_with_sdp(), transmit_notify_request(), and VERBOSE_PREFIX_3. 02378 { 02379 char *c; 02380 struct mgcp_request *req; 02381 struct mgcp_gateway *gw = p->parent; 02382 02383 if (result < 200) { 02384 /* provisional response */ 02385 return; 02386 } 02387 02388 if (p->slowsequence) 02389 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02390 else if (sub) 02391 req = find_command(p, sub, &sub->cx_queue, &sub->cx_queue_lock, ident); 02392 else if (!(req = find_command(p, sub, &p->rqnt_queue, &p->rqnt_queue_lock, ident))) 02393 req = find_command(p, sub, &p->cmd_queue, &p->cmd_queue_lock, ident); 02394 02395 if (!req) { 02396 if (option_verbose > 2) { 02397 ast_verbose(VERBOSE_PREFIX_3 "No command found on [%s] for transaction %d. Ignoring...\n", 02398 gw->name, ident); 02399 } 02400 return; 02401 } 02402 02403 if (p && (result >= 400) && (result <= 599)) { 02404 switch (result) { 02405 case 401: 02406 p->hookstate = MGCP_OFFHOOK; 02407 break; 02408 case 402: 02409 p->hookstate = MGCP_ONHOOK; 02410 break; 02411 case 406: 02412 ast_log(LOG_NOTICE, "Transaction %d timed out\n", ident); 02413 break; 02414 case 407: 02415 ast_log(LOG_NOTICE, "Transaction %d aborted\n", ident); 02416 break; 02417 } 02418 if (sub) { 02419 if (sub->owner) { 02420 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02421 result, p->name, p->parent->name, sub ? sub->id:-1); 02422 mgcp_queue_hangup(sub); 02423 } 02424 } else { 02425 if (p->sub->next->owner) { 02426 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02427 result, p->name, p->parent->name, sub ? sub->id:-1); 02428 mgcp_queue_hangup(p->sub); 02429 } 02430 02431 if (p->sub->owner) { 02432 ast_log(LOG_NOTICE, "Terminating on result %d from %s@%s-%d\n", 02433 result, p->name, p->parent->name, sub ? sub->id:-1); 02434 mgcp_queue_hangup(p->sub); 02435 } 02436 02437 dump_cmd_queues(p, NULL); 02438 } 02439 } 02440 02441 if (resp) { 02442 if (req->cmd == MGCP_CMD_CRCX) { 02443 if ((c = get_header(resp, "I"))) { 02444 if (!ast_strlen_zero(c) && sub) { 02445 /* SC: if we are hanging up do not process this conn. */ 02446 if (sub->owner) { 02447 if (!ast_strlen_zero(sub->cxident)) { 02448 if (strcasecmp(c, sub->cxident)) { 02449 ast_log(LOG_WARNING, "Subchannel already has a cxident. sub->cxident: %s requested %s\n", sub->cxident, c); 02450 } 02451 } 02452 strncpy(sub->cxident, c, sizeof(sub->cxident) - 1); 02453 if (sub->tmpdest.sin_addr.s_addr) { 02454 transmit_modify_with_sdp(sub, NULL, 0); 02455 } 02456 } else { 02457 /* XXX SC: delete this one 02458 callid and conn id may already be lost. 02459 so the following del conn may have a side effect of 02460 cleaning up the next subchannel */ 02461 transmit_connection_del(sub); 02462 } 02463 } 02464 } 02465 } 02466 02467 if (req->cmd == MGCP_CMD_AUEP) { 02468 /* SC: check stale connection ids */ 02469 if ((c = get_header(resp, "I"))) { 02470 char *v, *n; 02471 int len; 02472 while ((v = get_csv(c, &len, &n))) { 02473 if (len) { 02474 if (strncasecmp(v, p->sub->cxident, len) && 02475 strncasecmp(v, p->sub->next->cxident, len)) { 02476 /* connection id not found. delete it */ 02477 char cxident[80]; 02478 memcpy(cxident, v, len); 02479 cxident[len] = '\0'; 02480 if (option_verbose > 2) { 02481 ast_verbose(VERBOSE_PREFIX_3 "Non existing connection id %s on %s@%s \n", 02482 cxident, p->name, gw->name); 02483 } 02484 transmit_connection_del_w_params(p, NULL, cxident); 02485 } 02486 } 02487 c = n; 02488 } 02489 } 02490 02491 /* Try to determine the hookstate returned from an audit endpoint command */ 02492 if ((c = get_header(resp, "ES"))) { 02493 if (!ast_strlen_zero(c)) { 02494 if (strstr(c, "hu")) { 02495 if (p->hookstate != MGCP_ONHOOK) { 02496 /* SC: XXX cleanup if we think we are offhook XXX */ 02497 if ((p->sub->owner || p->sub->next->owner ) && 02498 p->hookstate == MGCP_OFFHOOK) 02499 mgcp_queue_hangup(sub); 02500 p->hookstate = MGCP_ONHOOK; 02501 02502 /* SC: update the requested events according to the new hookstate */ 02503 transmit_notify_request(p->sub, ""); 02504 02505 /* SC: verbose level check */ 02506 if (option_verbose > 2) { 02507 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to ONHOOK\n", p->name, gw->name); 02508 } 02509 } 02510 } else if (strstr(c, "hd")) { 02511 if (p->hookstate != MGCP_OFFHOOK) { 02512 p->hookstate = MGCP_OFFHOOK; 02513 02514 /* SC: update the requested events according to the new hookstate */ 02515 transmit_notify_request(p->sub, ""); 02516 02517 /* SC: verbose level check */ 02518 if (option_verbose > 2) { 02519 ast_verbose(VERBOSE_PREFIX_3 "Setting hookstate of %s@%s to OFFHOOK\n", p->name, gw->name); 02520 } 02521 } 02522 } 02523 } 02524 } 02525 } 02526 02527 if (resp && resp->lines) { 02528 /* SC: do not process sdp if we are hanging up. this may be a late response */ 02529 if (sub && sub->owner) { 02530 if (!sub->rtp) 02531 start_rtp(sub); 02532 if (sub->rtp) 02533 process_sdp(sub, resp); 02534 } 02535 } 02536 } 02537 02538 free(req); 02539 }
|
|
Definition at line 517 of file chan_mgcp.c. References ast_app_has_voicemail(), and mgcp_endpoint::mailbox. 00518 { 00519 return ast_app_has_voicemail(p->mailbox, NULL); 00520 }
|
|
Definition at line 1909 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_gateway::name, mgcp_endpoint::name, oseq, and mgcp_endpoint::parent. 01910 { 01911 /* Initialize a response */ 01912 if (req->headers || req->len) { 01913 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01914 return -1; 01915 } 01916 req->header[req->headers] = req->data + req->len; 01917 /* SC: check if we need brackets around the gw name */ 01918 if (p->parent->isnamedottedip) 01919 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); 01920 else 01921 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %d %s@%s MGCP 1.0\r\n", verb, oseq, p->name, p->parent->name); 01922 req->len += strlen(req->header[req->headers]); 01923 if (req->headers < MGCP_MAX_HEADERS) 01924 req->headers++; 01925 else 01926 ast_log(LOG_WARNING, "Out of header space\n"); 01927 return 0; 01928 }
|
|
Definition at line 1892 of file chan_mgcp.c. References ast_log(), mgcp_request::data, mgcp_request::header, mgcp_request::headers, mgcp_request::identifier, mgcp_request::len, and LOG_WARNING. 01893 { 01894 /* Initialize a response */ 01895 if (req->headers || req->len) { 01896 ast_log(LOG_WARNING, "Request already initialized?!?\n"); 01897 return -1; 01898 } 01899 req->header[req->headers] = req->data + req->len; 01900 snprintf(req->header[req->headers], sizeof(req->data) - req->len, "%s %s %s\r\n", resp, orig->identifier, resprest); 01901 req->len += strlen(req->header[req->headers]); 01902 if (req->headers < MGCP_MAX_HEADERS) 01903 req->headers++; 01904 else 01905 ast_log(LOG_WARNING, "Out of header space\n"); 01906 return 0; 01907 }
|
|
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 4401 of file chan_mgcp.c. 04402 {
04403 return ASTERISK_GPL_KEY;
04404 }
|
|
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 4265 of file chan_mgcp.c. References ast_channel_register(), ast_cli_register(), ast_log(), ast_rtp_proto_register(), cli_audit_endpoint, cli_debug, cli_mgcp_reload, cli_no_debug, cli_show_endpoints, io, io_context_create(), LOG_ERROR, LOG_WARNING, mgcp_rtp, mgcp_tech, reload_config(), restart_monitor(), sched, sched_context_create(), and type. 04266 { 04267 int res; 04268 04269 sched = sched_context_create(); 04270 if (!sched) { 04271 ast_log(LOG_WARNING, "Unable to create schedule context\n"); 04272 return -1; 04273 } 04274 io = io_context_create(); 04275 if (!io) { 04276 ast_log(LOG_WARNING, "Unable to create I/O context\n"); 04277 return -1; 04278 } 04279 04280 if (!(res = reload_config())) { 04281 /* Make sure we can register our mgcp channel type */ 04282 if (ast_channel_register(&mgcp_tech)) { 04283 ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); 04284 return -1; 04285 } 04286 ast_rtp_proto_register(&mgcp_rtp); 04287 ast_cli_register(&cli_show_endpoints); 04288 ast_cli_register(&cli_audit_endpoint); 04289 ast_cli_register(&cli_debug); 04290 ast_cli_register(&cli_no_debug); 04291 ast_cli_register(&cli_mgcp_reload); 04292 04293 /* And start the monitor for the first time */ 04294 restart_monitor(); 04295 } 04296 04297 return res; 04298 }
|
|
Definition at line 1183 of file chan_mgcp.c. References ast_channel::_state, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_setstate(), AST_STATE_UP, ast_verbose(), mgcp_subchannel::cxmode, mgcp_subchannel::id, mgcp_subchannel::lock, LOG_DEBUG, mgcp_gateway::name, mgcp_endpoint::name, ast_channel::name, option_verbose, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, start_rtp(), ast_channel::tech_pvt, transmit_modify_request(), transmit_notify_request(), and VERBOSE_PREFIX_3. 01184 { 01185 int res = 0; 01186 struct mgcp_subchannel *sub = ast->tech_pvt; 01187 struct mgcp_endpoint *p = sub->parent; 01188 01189 ast_mutex_lock(&sub->lock); 01190 sub->cxmode = MGCP_CX_SENDRECV; 01191 if (!sub->rtp) { 01192 start_rtp(sub); 01193 } else { 01194 transmit_modify_request(sub); 01195 } 01196 /* SC: verbose level check */ 01197 if (option_verbose > 2) { 01198 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_answer(%s) on %s@%s-%d\n", 01199 ast->name, p->name, p->parent->name, sub->id); 01200 } 01201 if (ast->_state != AST_STATE_UP) { 01202 ast_setstate(ast, AST_STATE_UP); 01203 if (option_debug) 01204 ast_log(LOG_DEBUG, "mgcp_answer(%s)\n", ast->name); 01205 transmit_notify_request(sub, ""); 01206 transmit_modify_request(sub); 01207 } 01208 ast_mutex_unlock(&sub->lock); 01209 return res; 01210 }
|
|
Definition at line 1122 of file chan_mgcp.c. References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), mgcp_gateway::endpoints, mgcp_endpoint::name, mgcp_gateway::name, mgcp_gateway::next, mgcp_endpoint::next, 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_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_OFFHOOK, MGCP_ONHOOK, 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, 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 3960 of file chan_mgcp.c. References ast_cli(), and mgcpdebug. 03961 { 03962 if (argc != 2) 03963 return RESULT_SHOWUSAGE; 03964 mgcpdebug = 1; 03965 ast_cli(fd, "MGCP Debugging Enabled\n"); 03966 return RESULT_SUCCESS; 03967 }
|
|
Definition at line 4300 of file chan_mgcp.c. References reload_config(). Referenced by do_monitor(). 04301 { 04302 reload_config(); 04303 return 0; 04304 }
|
|
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 3933 of file chan_mgcp.c. References mgcp_endpoint::canreinvite, mgcp_subchannel::parent, mgcp_subchannel::rtp, and ast_channel::tech_pvt. 03934 { 03935 struct mgcp_subchannel *sub; 03936 sub = chan->tech_pvt; 03937 if (sub && sub->rtp && sub->parent->canreinvite) 03938 return sub->rtp; 03939 return NULL; 03940 }
|
|
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, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, 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_SUBCHANNEL_MAGIC, mgcp_gateway::name, mgcp_endpoint::name, ast_channel::name, mgcp_subchannel::next, 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, 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, ast_channel::name, ast_channel::tech_pvt, transmit_notify_request(), and VERBOSE_PREFIX_3. 01348 { 01349 struct mgcp_subchannel *sub = ast->tech_pvt; 01350 int res = 0; 01351 01352 if (mgcpdebug) { 01353 ast_verbose(VERBOSE_PREFIX_3 "MGCP asked to indicate %d '%s' condition on channel %s\n", 01354 ind, control2str(ind), ast->name); 01355 } 01356 ast_mutex_lock(&sub->lock); 01357 switch(ind) { 01358 case AST_CONTROL_RINGING: 01359 #ifdef DLINK_BUGGY_FIRMWARE 01360 transmit_notify_request(sub, "rt"); 01361 #else 01362 transmit_notify_request(sub, "G/rt"); 01363 #endif 01364 break; 01365 case AST_CONTROL_BUSY: 01366 transmit_notify_request(sub, "L/bz"); 01367 break; 01368 case AST_CONTROL_CONGESTION: 01369 transmit_notify_request(sub, "G/cg"); 01370 break; 01371 case -1: 01372 transmit_notify_request(sub, ""); 01373 break; 01374 default: 01375 ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", ind); 01376 res = -1; 01377 } 01378 ast_mutex_unlock(&sub->lock); 01379 return res; 01380 }
|
|
|
Definition at line 3969 of file chan_mgcp.c. References ast_cli(), and mgcpdebug. 03970 { 03971 if (argc != 3) 03972 return RESULT_SHOWUSAGE; 03973 mgcpdebug = 0; 03974 ast_cli(fd, "MGCP Debugging Disabled\n"); 03975 return RESULT_SUCCESS; 03976 }
|
|
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, sched, mgcp_message::seqno, and tv. 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 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 4306 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(). 04307 { 04308 ast_mutex_lock(&mgcp_reload_lock); 04309 if (mgcp_reloading) { 04310 ast_verbose("Previous mgcp reload not yet done\n"); 04311 } else 04312 mgcp_reloading = 1; 04313 ast_mutex_unlock(&mgcp_reload_lock); 04314 restart_monitor(); 04315 return 0; 04316 }
|
|
Definition at line 3499 of file chan_mgcp.c. References ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strlen_zero(), ast_verbose(), mgcp_endpoint::call_forward, mgcp_endpoint::callwaiting, mgcp_endpoint::dnd, find_subchannel_and_lock(), has_voicemail(), mgcp_endpoint::hookstate, mgcp_subchannel::lock, LOG_NOTICE, LOG_WARNING, mgcp_new(), mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_subchannel::parent, restart_monitor(), transmit_notify_request(), and VERBOSE_PREFIX_3. Referenced by send_request(). 03500 { 03501 int oldformat; 03502 struct mgcp_subchannel *sub; 03503 struct ast_channel *tmpc = NULL; 03504 char tmp[256]; 03505 char *dest = data; 03506 03507 oldformat = format; 03508 format &= capability; 03509 if (!format) { 03510 ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", format); 03511 return NULL; 03512 } 03513 strncpy(tmp, dest, sizeof(tmp) - 1); 03514 if (ast_strlen_zero(tmp)) { 03515 ast_log(LOG_NOTICE, "MGCP Channels require an endpoint\n"); 03516 return NULL; 03517 } 03518 sub = find_subchannel_and_lock(tmp, 0, NULL); 03519 if (!sub) { 03520 ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp); 03521 *cause = AST_CAUSE_UNREGISTERED; 03522 return NULL; 03523 } 03524 03525 if (option_verbose > 2) { 03526 ast_verbose(VERBOSE_PREFIX_3 "MGCP mgcp_request(%s)\n", tmp); 03527 ast_verbose(VERBOSE_PREFIX_3 "MGCP cw: %d, dnd: %d, so: %d, sno: %d\n", 03528 sub->parent->callwaiting, sub->parent->dnd, sub->owner ? 1 : 0, sub->next->owner ? 1: 0); 03529 } 03530 /* Must be busy */ 03531 if (((sub->parent->callwaiting) && ((sub->owner) && (sub->next->owner))) || 03532 ((!sub->parent->callwaiting) && (sub->owner)) || 03533 (sub->parent->dnd && (ast_strlen_zero(sub->parent->call_forward)))) { 03534 if (sub->parent->hookstate == MGCP_ONHOOK) { 03535 if (has_voicemail(sub->parent)) { 03536 transmit_notify_request(sub,"L/vmwi(+)"); 03537 } else { 03538 transmit_notify_request(sub,"L/vmwi(-)"); 03539 } 03540 } 03541 *cause = AST_CAUSE_BUSY; 03542 ast_mutex_unlock(&sub->lock); 03543 return NULL; 03544 } 03545 tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN); 03546 ast_mutex_unlock(&sub->lock); 03547 if (!tmpc) 03548 ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp); 03549 restart_monitor(); 03550 return tmpc; 03551 }
|
|
Definition at line 1212 of file chan_mgcp.c. References ast_dsp_process(), 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, 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 3942 of file chan_mgcp.c. References ast_channel::tech_pvt, and transmit_modify_with_sdp(). 03943 { 03944 /* XXX Is there such thing as video support with MGCP? XXX */ 03945 struct mgcp_subchannel *sub; 03946 sub = chan->tech_pvt; 03947 if (sub) { 03948 transmit_modify_with_sdp(sub, rtp, codecs); 03949 return 0; 03950 } 03951 return -1; 03952 }
|
|
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, mgcp_endpoint::name, mgcp_gateway::name, mgcp_gateway::next, mgcp_endpoint::next, mgcp_subchannel::owner, 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 2566 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_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_name, ast_callerid::cid_num, mgcp_endpoint::cid_num, ast_channel::context, mgcp_endpoint::dnd, mgcp_endpoint::dtmfmode, ast_channel::exten, free, mgcp_endpoint::hascallwaiting, mgcp_endpoint::hidecallerid, ast_channel::language, mgcp_endpoint::lastcallerid, LOG_DEBUG, LOG_WARNING, ast_channel::name, mgcp_subchannel::next, option_verbose, mgcp_subchannel::owner, mgcp_subchannel::parent, ast_channel::rings, start_rtp(), strdup, ast_channel::tech_pvt, transmit_notify_request(), and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(). 02567 { 02568 struct ast_channel *chan = data; 02569 struct mgcp_subchannel *sub = chan->tech_pvt; 02570 struct mgcp_endpoint *p = sub->parent; 02571 char exten[AST_MAX_EXTENSION] = ""; 02572 int len = 0; 02573 int timeout = firstdigittimeout; 02574 int res; 02575 int getforward = 0; 02576 02577 while(len < AST_MAX_EXTENSION-1) { 02578 res = ast_waitfordigit(chan, timeout); 02579 timeout = 0; 02580 if (res < 0) { 02581 ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n"); 02582 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02583 ast_indicate(chan, -1); 02584 ast_hangup(chan); 02585 return NULL; 02586 } else if (res) { 02587 exten[len++]=res; 02588 exten[len] = '\0'; 02589 } 02590 if (!ast_ignore_pattern(chan->context, exten)) { 02591 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02592 ast_indicate(chan, -1); 02593 } else { 02594 /* XXX Redundant? We should already be playing dialtone */ 02595 /*tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02596 transmit_notify_request(sub, "L/dl"); 02597 } 02598 if (ast_exists_extension(chan, chan->context, exten, 1, p->cid_num)) { 02599 if (!res || !ast_matchmore_extension(chan, chan->context, exten, 1, p->cid_num)) { 02600 if (getforward) { 02601 /* Record this as the forwarding extension */ 02602 strncpy(p->call_forward, exten, sizeof(p->call_forward) - 1); 02603 if (option_verbose > 2) { 02604 ast_verbose(VERBOSE_PREFIX_3 "Setting call forward to '%s' on channel %s\n", 02605 p->call_forward, chan->name); 02606 } 02607 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02608 transmit_notify_request(sub, "L/sl"); 02609 if (res) 02610 break; 02611 usleep(500000); 02612 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02613 ast_indicate(chan, -1); 02614 sleep(1); 02615 memset(exten, 0, sizeof(exten)); 02616 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALTONE);*/ 02617 transmit_notify_request(sub, "L/dl"); 02618 len = 0; 02619 getforward = 0; 02620 } else { 02621 /*res = tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02622 ast_indicate(chan, -1); 02623 strncpy(chan->exten, exten, sizeof(chan->exten)-1); 02624 if (!ast_strlen_zero(p->cid_num)) { 02625 if (!p->hidecallerid) { 02626 /* SC: free existing chan->callerid */ 02627 if (chan->cid.cid_num) 02628 free(chan->cid.cid_num); 02629 chan->cid.cid_num = strdup(p->cid_num); 02630 /* SC: free existing chan->callerid */ 02631 if (chan->cid.cid_name) 02632 free(chan->cid.cid_name); 02633 chan->cid.cid_name = strdup(p->cid_name); 02634 } 02635 if (chan->cid.cid_ani) 02636 free(chan->cid.cid_ani); 02637 chan->cid.cid_ani = strdup(p->cid_num); 02638 } 02639 ast_setstate(chan, AST_STATE_RING); 02640 /*zt_enable_ec(p);*/ 02641 if (p->dtmfmode & MGCP_DTMF_HYBRID) { 02642 p->dtmfmode |= MGCP_DTMF_INBAND; 02643 ast_indicate(chan, -1); 02644 } 02645 res = ast_pbx_run(chan); 02646 if (res) { 02647 ast_log(LOG_WARNING, "PBX exited non-zero\n"); 02648 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02649 /*transmit_notify_request(p, "nbz", 1);*/ 02650 transmit_notify_request(sub, "G/cg"); 02651 } 02652 return NULL; 02653 } 02654 } else { 02655 /* It's a match, but they just typed a digit, and there is an ambiguous match, 02656 so just set the timeout to matchdigittimeout and wait some more */ 02657 timeout = matchdigittimeout; 02658 } 02659 } else if (res == 0) { 02660 ast_log(LOG_DEBUG, "not enough digits (and no ambiguous match)...\n"); 02661 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02662 transmit_notify_request(sub, "G/cg"); 02663 /*zt_wait_event(p->subs[index].zfd);*/ 02664 ast_hangup(chan); 02665 return NULL; 02666 } else if (p->hascallwaiting && p->callwaiting && !strcmp(exten, "*70")) { 02667 if (option_verbose > 2) { 02668 ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name); 02669 } 02670 /* Disable call waiting if enabled */ 02671 p->callwaiting = 0; 02672 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02673 transmit_notify_request(sub, "L/sl"); 02674 len = 0; 02675 memset(exten, 0, sizeof(exten)); 02676 timeout = firstdigittimeout; 02677 } else if (!strcmp(exten,ast_pickup_ext())) { 02678 /* Scan all channels and see if any there 02679 * ringing channqels with that have call groups 02680 * that equal this channels pickup group 02681 */ 02682 if (ast_pickup_call(chan)) { 02683 ast_log(LOG_WARNING, "No call pickup possible...\n"); 02684 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_CONGESTION);*/ 02685 transmit_notify_request(sub, "G/cg"); 02686 } 02687 ast_hangup(chan); 02688 return NULL; 02689 } else if (!p->hidecallerid && !strcmp(exten, "*67")) { 02690 if (option_verbose > 2) { 02691 ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name); 02692 } 02693 /* Disable Caller*ID if enabled */ 02694 p->hidecallerid = 1; 02695 if (chan->cid.cid_num) 02696 free(chan->cid.cid_num); 02697 chan->cid.cid_num = NULL; 02698 if (chan->cid.cid_name) 02699 free(chan->cid.cid_name); 02700 chan->cid.cid_name = NULL; 02701 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02702 transmit_notify_request(sub, "L/sl"); 02703 len = 0; 02704 memset(exten, 0, sizeof(exten)); 02705 timeout = firstdigittimeout; 02706 } else if (p->callreturn && !strcmp(exten, "*69")) { 02707 res = 0; 02708 if (!ast_strlen_zero(p->lastcallerid)) { 02709 res = ast_say_digit_str(chan, p->lastcallerid, "", chan->language); 02710 } 02711 if (!res) 02712 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02713 transmit_notify_request(sub, "L/sl"); 02714 break; 02715 } else if (!strcmp(exten, "*78")) { 02716 /* Do not disturb */ 02717 if (option_verbose > 2) { 02718 ast_verbose(VERBOSE_PREFIX_3 "Enabled DND on channel %s\n", chan->name); 02719 } 02720 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02721 transmit_notify_request(sub, "L/sl"); 02722 p->dnd = 1; 02723 getforward = 0; 02724 memset(exten, 0, sizeof(exten)); 02725 len = 0; 02726 } else if (!strcmp(exten, "*79")) { 02727 /* Do not disturb */ 02728 if (option_verbose > 2) { 02729 ast_verbose(VERBOSE_PREFIX_3 "Disabled DND on channel %s\n", chan->name); 02730 } 02731 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02732 transmit_notify_request(sub, "L/sl"); 02733 p->dnd = 0; 02734 getforward = 0; 02735 memset(exten, 0, sizeof(exten)); 02736 len = 0; 02737 } else if (p->cancallforward && !strcmp(exten, "*72")) { 02738 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02739 transmit_notify_request(sub, "L/sl"); 02740 getforward = 1; 02741 memset(exten, 0, sizeof(exten)); 02742 len = 0; 02743 } else if (p->cancallforward && !strcmp(exten, "*73")) { 02744 if (option_verbose > 2) { 02745 ast_verbose(VERBOSE_PREFIX_3 "Cancelling call forwarding on channel %s\n", chan->name); 02746 } 02747 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02748 transmit_notify_request(sub, "L/sl"); 02749 memset(p->call_forward, 0, sizeof(p->call_forward)); 02750 getforward = 0; 02751 memset(exten, 0, sizeof(exten)); 02752 len = 0; 02753 } else if (!strcmp(exten, ast_parking_ext()) && 02754 sub->next->owner && ast_bridged_channel(sub->next->owner)) { 02755 /* This is a three way call, the main call being a real channel, 02756 and we're parking the first call. */ 02757 ast_masq_park_call(ast_bridged_channel(sub->next->owner), chan, 0, NULL); 02758 if (option_verbose > 2) { 02759 ast_verbose(VERBOSE_PREFIX_3 "Parking call to '%s'\n", chan->name); 02760 } 02761 break; 02762 } else if (!ast_strlen_zero(p->lastcallerid) && !strcmp(exten, "*60")) { 02763 if (option_verbose > 2) { 02764 ast_verbose(VERBOSE_PREFIX_3 "Blacklisting number %s\n", p->lastcallerid); 02765 } 02766 res = ast_db_put("blacklist", p->lastcallerid, "1"); 02767 if (!res) { 02768 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02769 transmit_notify_request(sub, "L/sl"); 02770 memset(exten, 0, sizeof(exten)); 02771 len = 0; 02772 } 02773 } else if (p->hidecallerid && !strcmp(exten, "*82")) { 02774 if (option_verbose > 2) { 02775 ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name); 02776 } 02777 /* Enable Caller*ID if enabled */ 02778 p->hidecallerid = 0; 02779 if (chan->cid.cid_num) 02780 free(chan->cid.cid_num); 02781 if (!ast_strlen_zero(p->cid_num)) 02782 chan->cid.cid_num = strdup(p->cid_num); 02783 if (chan->cid.cid_name) 02784 free(chan->cid.cid_name); 02785 if (!ast_strlen_zero(p->cid_name)) 02786 chan->cid.cid_name = strdup(p->cid_name); 02787 /*res = tone_zone_play_tone(p->subs[index].zfd, ZT_TONE_DIALRECALL);*/ 02788 transmit_notify_request(sub, "L/sl"); 02789 len = 0; 02790 memset(exten, 0, sizeof(exten)); 02791 timeout = firstdigittimeout; 02792 } else if (!ast_canmatch_extension(chan, chan->context, exten, 1, chan->cid.cid_num) && 02793 ((exten[0] != '*') || (strlen(exten) > 2))) { 02794 if (option_debug) 02795 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); 02796 break; 02797 } 02798 if (!timeout) 02799 timeout = gendigittimeout; 02800 if (len && !ast_ignore_pattern(chan->context, exten)) 02801 /*tone_zone_play_tone(p->subs[index].zfd, -1);*/ 02802 ast_indicate(chan, -1); 02803 } 02804 #if 0 02805 for (;;) { 02806 res = ast_waitfordigit(chan, to); 02807 if (!res) { 02808 ast_log(LOG_DEBUG, "Timeout...\n"); 02809 break; 02810 } 02811 if (res < 0) { 02812 ast_log(LOG_DEBUG, "Got hangup...\n"); 02813 ast_hangup(chan); 02814 break; 02815 } 02816 exten[pos++] = res; 02817 if (!ast_ignore_pattern(chan->context, exten)) 02818 ast_indicate(chan, -1); 02819 if (ast_matchmore_extension(chan, chan->context, exten, 1, chan->callerid)) { 02820 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) 02821 to = 3000; 02822 else 02823 to = 8000; 02824 } else 02825 break; 02826 } 02827 if (ast_exists_extension(chan, chan->context, exten, 1, chan->callerid)) { 02828 strncpy(chan->exten, exten, sizeof(chan->exten) - 1); 02829 if (!p->rtp) { 02830 start_rtp(p); 02831 } 02832 ast_setstate(chan, AST_STATE_RING); 02833 chan->rings = 1; 02834 if (ast_pbx_run(chan)) { 02835 ast_log(LOG_WARNING, "Unable to launch PBX on %s\n", chan->name); 02836 } else 02837 return NULL; 02838 } 02839 #endif 02840 ast_hangup(chan); 02841 return NULL; 02842 }
|
|
Definition at line 1254 of file chan_mgcp.c. References 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 3293 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(), mgcp_request::data, find_and_retrans(), find_subchannel_and_lock(), free, handle_request(), handle_response(), mgcp_request::len, mgcp_subchannel::lock, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, mgcpsock, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_endpoint::parent, mgcp_subchannel::parent, parse(), result, mgcp_gateway::retransid, and sched. Referenced by do_monitor(). 03294 { 03295 struct mgcp_request req; 03296 struct sockaddr_in sin; 03297 struct mgcp_subchannel *sub; 03298 int res; 03299 socklen_t len; 03300 int result; 03301 int ident; 03302 char iabuf[INET_ADDRSTRLEN]; 03303 len = sizeof(sin); 03304 memset(&req, 0, sizeof(req)); 03305 res = recvfrom(mgcpsock, req.data, sizeof(req.data) - 1, 0, (struct sockaddr *)&sin, &len); 03306 if (res < 0) { 03307 if (errno != ECONNREFUSED) 03308 ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno)); 03309 return 1; 03310 } 03311 req.data[res] = '\0'; 03312 req.len = res; 03313 if (mgcpdebug) { 03314 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)); 03315 } 03316 parse(&req); 03317 if (req.headers < 1) { 03318 /* Must have at least one header */ 03319 return 1; 03320 } 03321 if (ast_strlen_zero(req.identifier)) { 03322 ast_log(LOG_NOTICE, "Message from %s missing identifier\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)); 03323 return 1; 03324 } 03325 03326 if (sscanf(req.verb, "%d", &result) && sscanf(req.identifier, "%d", &ident)) { 03327 /* Try to find who this message is for, if it's important */ 03328 sub = find_subchannel_and_lock(NULL, ident, &sin); 03329 if (sub) { 03330 struct mgcp_gateway *gw = sub->parent->parent; 03331 struct mgcp_message *cur, *prev; 03332 03333 ast_mutex_unlock(&sub->lock); 03334 ast_mutex_lock(&gw->msgs_lock); 03335 for (prev = NULL, cur = gw->msgs; cur; prev = cur, cur = cur->next) { 03336 if (cur->seqno == ident) { 03337 ast_log(LOG_DEBUG, "Got response back on transaction %d\n", ident); 03338 if (prev) 03339 prev->next = cur->next; 03340 else 03341 gw->msgs = cur->next; 03342 break; 03343 } 03344 } 03345 03346 /* stop retrans timer if the queue is empty */ 03347 if (!gw->msgs && (gw->retransid != -1)) { 03348 ast_sched_del(sched, gw->retransid); 03349 gw->retransid = -1; 03350 } 03351 03352 ast_mutex_unlock(&gw->msgs_lock); 03353 if (cur) { 03354 handle_response(cur->owner_ep, cur->owner_sub, result, ident, &req); 03355 free(cur); 03356 return 1; 03357 } 03358 03359 ast_log(LOG_NOTICE, "Got response back on [%s] for transaction %d we aren't sending?\n", 03360 gw->name, ident); 03361 } 03362 } else { 03363 if (ast_strlen_zero(req.endpoint) || 03364 ast_strlen_zero(req.version) || 03365 ast_strlen_zero(req.verb)) { 03366 ast_log(LOG_NOTICE, "Message must have a verb, an idenitifier, version, and endpoint\n"); 03367 return 1; 03368 } 03369 /* Process request, with iflock held */ 03370 sub = find_subchannel_and_lock(req.endpoint, 0, &sin); 03371 if (sub) { 03372 /* look first to find a matching response in the queue */ 03373 if (!find_and_retrans(sub, &req)) 03374 /* pass the request off to the currently mastering subchannel */ 03375 handle_request(sub, &req, &sin); 03376 ast_mutex_unlock(&sub->lock); 03377 } 03378 } 03379 return 1; 03380 }
|
|
Definition at line 1660 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, mgcp_request::verb, and mgcp_request::version. Referenced by mgcpsock_read(). 01661 { 01662 /* Divide fields by NULL's */ 01663 char *c; 01664 int f = 0; 01665 c = req->data; 01666 01667 /* First header starts immediately */ 01668 req->header[f] = c; 01669 while(*c) { 01670 if (*c == '\n') { 01671 /* We've got a new header */ 01672 *c = 0; 01673 #if 0 01674 printf("Header: %s (%d)\n", req->header[f], strlen(req->header[f])); 01675 #endif 01676 if (ast_strlen_zero(req->header[f])) { 01677 /* Line by itself means we're now in content */ 01678 c++; 01679 break; 01680 } 01681 if (f >= MGCP_MAX_HEADERS - 1) { 01682 ast_log(LOG_WARNING, "Too many MGCP headers...\n"); 01683 } else 01684 f++; 01685 req->header[f] = c + 1; 01686 } else if (*c == '\r') { 01687 /* Ignore but eliminate \r's */ 01688 *c = 0; 01689 } 01690 c++; 01691 } 01692 /* Check for last header */ 01693 if (!ast_strlen_zero(req->header[f])) 01694 f++; 01695 req->headers = f; 01696 /* Now we process any mime content */ 01697 f = 0; 01698 req->line[f] = c; 01699 while(*c) { 01700 if (*c == '\n') { 01701 /* We've got a new line */ 01702 *c = 0; 01703 #if 0 01704 printf("Line: %s (%d)\n", req->line[f], strlen(req->line[f])); 01705 #endif 01706 if (f >= MGCP_MAX_LINES - 1) { 01707 ast_log(LOG_WARNING, "Too many SDP lines...\n"); 01708 } else 01709 f++; 01710 req->line[f] = c + 1; 01711 } else if (*c == '\r') { 01712 /* Ignore and eliminate \r's */ 01713 *c = 0; 01714 } 01715 c++; 01716 } 01717 /* Check for last line */ 01718 if (!ast_strlen_zero(req->line[f])) 01719 f++; 01720 req->lines = f; 01721 /* Parse up the initial header */ 01722 c = req->header[0]; 01723 while(*c && *c < 33) c++; 01724 /* First the verb */ 01725 req->verb = c; 01726 while(*c && (*c > 32)) c++; 01727 if (*c) { 01728 *c = '\0'; 01729 c++; 01730 while(*c && (*c < 33)) c++; 01731 req->identifier = c; 01732 while(*c && (*c > 32)) c++; 01733 if (*c) { 01734 *c = '\0'; 01735 c++; 01736 while(*c && (*c < 33)) c++; 01737 req->endpoint = c; 01738 while(*c && (*c > 32)) c++; 01739 if (*c) { 01740 *c = '\0'; 01741 c++; 01742 while(*c && (*c < 33)) c++; 01743 req->version = c; 01744 while(*c && (*c > 32)) c++; 01745 while(*c && (*c < 33)) c++; 01746 while(*c && (*c > 32)) c++; 01747 *c = '\0'; 01748 } 01749 } 01750 } 01751 01752 if (mgcpdebug) { 01753 ast_verbose("Verb: '%s', Identifier: '%s', Endpoint: '%s', Version: '%s'\n", 01754 req->verb, req->identifier, req->endpoint, req->version); 01755 ast_verbose("%d headers, %d lines\n", req->headers, req->lines); 01756 } 01757 if (*c) 01758 ast_log(LOG_WARNING, "Odd content, extra stuff left over ('%s')\n", c); 01759 }
|
|
Definition at line 1761 of file chan_mgcp.c. References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_rtp_get_current_formats(), ast_rtp_pt_clear(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_set_rtpmap_type(), ast_strdupa, ast_strlen_zero(), ast_verbose(), capability, mgcp_endpoint::capability, get_sdp(), get_sdp_iterate(), hp, LOG_WARNING, mgcp_endpoint::nonCodecCapability, nonCodecCapability, mgcp_subchannel::parent, mgcp_subchannel::rtp, and sdpLineNum_iterator_init(). 01762 { 01763 char *m; 01764 char *c; 01765 char *a; 01766 char host[258]; 01767 int len; 01768 int portno; 01769 int peercapability, peerNonCodecCapability; 01770 struct sockaddr_in sin; 01771 char *codecs; 01772 struct ast_hostent ahp; struct hostent *hp; 01773 int codec, codec_count=0; 01774 int iterator; 01775 struct mgcp_endpoint *p = sub->parent; 01776 01777 /* Get codec and RTP info from SDP */ 01778 m = get_sdp(req, "m"); 01779 c = get_sdp(req, "c"); 01780 if (ast_strlen_zero(m) || ast_strlen_zero(c)) { 01781 ast_log(LOG_WARNING, "Insufficient information for SDP (m = '%s', c = '%s')\n", m, c); 01782 return -1; 01783 } 01784 if (sscanf(c, "IN IP4 %256s", host) != 1) { 01785 ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c); 01786 return -1; 01787 } 01788 /* XXX This could block for a long time, and block the main thread! XXX */ 01789 hp = ast_gethostbyname(host, &ahp); 01790 if (!hp) { 01791 ast_log(LOG_WARNING, "Unable to lookup host in c= line, '%s'\n", c); 01792 return -1; 01793 } 01794 if (sscanf(m, "audio %d RTP/AVP %n", &portno, &len) != 1) { 01795 ast_log(LOG_WARNING, "Unable to determine port number for RTP in '%s'\n", m); 01796 return -1; 01797 } 01798 sin.sin_family = AF_INET; 01799 memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); 01800 sin.sin_port = htons(portno); 01801 ast_rtp_set_peer(sub->rtp, &sin); 01802 #if 0 01803 printf("Peer RTP is at port %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); 01804 #endif 01805 /* Scan through the RTP payload types specified in a "m=" line: */ 01806 ast_rtp_pt_clear(sub->rtp); 01807 codecs = ast_strdupa(m + len); 01808 while (!ast_strlen_zero(codecs)) { 01809 if (sscanf(codecs, "%d%n", &codec, &len) != 1) { 01810 if (codec_count) 01811 break; 01812 ast_log(LOG_WARNING, "Error in codec string '%s' at '%s'\n", m, codecs); 01813 return -1; 01814 } 01815 ast_rtp_set_m_type(sub->rtp, codec); 01816 codec_count++; 01817 codecs += len; 01818 } 01819 01820 /* Next, scan through each "a=rtpmap:" line, noting each */ 01821 /* specified RTP payload type (with corresponding MIME subtype): */ 01822 sdpLineNum_iterator_init(&iterator); 01823 while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') { 01824 char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */ 01825 if (sscanf(a, "rtpmap: %u %[^/]/", &codec, mimeSubtype) != 2) 01826 continue; 01827 /* Note: should really look at the 'freq' and '#chans' params too */ 01828 ast_rtp_set_rtpmap_type(sub->rtp, codec, "audio", mimeSubtype); 01829 } 01830 01831 /* Now gather all of the codecs that were asked for: */ 01832 ast_rtp_get_current_formats(sub->rtp, &peercapability, &peerNonCodecCapability); 01833 p->capability = capability & peercapability; 01834 if (mgcpdebug) { 01835 ast_verbose("Capabilities: us - %d, them - %d, combined - %d\n", 01836 capability, peercapability, p->capability); 01837 ast_verbose("Non-codec capabilities: us - %d, them - %d, combined - %d\n", 01838 nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability); 01839 } 01840 if (!p->capability) { 01841 ast_log(LOG_WARNING, "No compatible codecs!\n"); 01842 return -1; 01843 } 01844 return 0; 01845 }
|
|
Definition at line 4050 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), destroy_endpoint(), destroy_gateway(), gateways, mgcp_gateway::next, and mgcp_endpoint::next. Referenced by reload_config(), and unload_module(). 04051 { 04052 struct mgcp_gateway *g, *z, *r; 04053 struct mgcp_endpoint *e, *p, *t; 04054 04055 ast_mutex_lock(&gatelock); 04056 04057 /* prune gateways */ 04058 for (z = NULL, g = gateways; g;) { 04059 /* prune endpoints */ 04060 for (p = NULL, e = g->endpoints; e; ) { 04061 if (e->delme || g->delme) { 04062 t = e; 04063 e = e->next; 04064 if (!p) 04065 g->endpoints = e; 04066 else 04067 p->next = e; 04068 destroy_endpoint(t); 04069 } else { 04070 p = e; 04071 e = e->next; 04072 } 04073 } 04074 04075 if (g->delme) { 04076 r = g; 04077 g = g->next; 04078 if (!z) 04079 gateways = g; 04080 else 04081 z->next = g; 04082 04083 destroy_gateway(r); 04084 } else { 04085 z = g; 04086 g = g->next; 04087 } 04088 } 04089 04090 ast_mutex_unlock(&gatelock); 04091 }
|
|
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 4318 of file chan_mgcp.c. References mgcp_reload(). 04319 { 04320 mgcp_reload(0, 0, NULL); 04321 return 0; 04322 }
|
|
Definition at line 4093 of file chan_mgcp.c. References __ourip, ahp, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_getformatbyname(), ast_gethostbyname(), ast_inet_ntoa(), ast_io_remove(), ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_variable_browse(), ast_verbose(), bindaddr, build_gateway(), capability, cfg, config, DEFAULT_MGCP_CA_PORT, mgcp_endpoint::delme, mgcp_gateway::delme, dtmfmode, mgcp_gateway::endpoints, gateways, hp, io, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mgcpsock, mgcpsock_read_id, monitor_thread, mgcp_endpoint::name, mgcp_gateway::name, ast_variable::name, mgcp_endpoint::needaudit, mgcp_gateway::next, mgcp_endpoint::next, ast_variable::next, option_verbose, ourhost, ourport, prune_gateways(), sched, tos, transmit_audit_endpoint(), ast_variable::value, VERBOSE_PREFIX_2, and VERBOSE_PREFIX_3. 04094 { 04095 struct ast_config *cfg; 04096 struct ast_variable *v; 04097 struct mgcp_gateway *g; 04098 struct mgcp_endpoint *e; 04099 char iabuf[INET_ADDRSTRLEN]; 04100 char *cat; 04101 struct ast_hostent ahp; 04102 struct hostent *hp; 04103 int format; 04104 04105 if (gethostname(ourhost, sizeof(ourhost)-1)) { 04106 ast_log(LOG_WARNING, "Unable to get hostname, MGCP disabled\n"); 04107 return 0; 04108 } 04109 cfg = ast_config_load(config); 04110 04111 /* We *must* have a config file otherwise stop immediately */ 04112 if (!cfg) { 04113 ast_log(LOG_NOTICE, "Unable to load config %s, MGCP disabled\n", config); 04114 return 0; 04115 } 04116 memset(&bindaddr, 0, sizeof(bindaddr)); 04117 dtmfmode = 0; 04118 v = ast_variable_browse(cfg, "general"); 04119 while(v) { 04120 /* Create the interface list */ 04121 if (!strcasecmp(v->name, "bindaddr")) { 04122 if (!(hp = ast_gethostbyname(v->value, &ahp))) { 04123 ast_log(LOG_WARNING, "Invalid address: %s\n", v->value); 04124 } else { 04125 memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr)); 04126 } 04127 } else if (!strcasecmp(v->name, "allow")) { 04128 format = ast_getformatbyname(v->value); 04129 if (format < 1) 04130 ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value); 04131 else 04132 capability |= format; 04133 } else if (!strcasecmp(v->name, "disallow")) { 04134 format = ast_getformatbyname(v->value); 04135 if (format < 1) 04136 ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value); 04137 else 04138 capability &= ~format; 04139 } else if (!strcasecmp(v->name, "tos")) { 04140 if (sscanf(v->value, "%d", &format) == 1) 04141 tos = format & 0xff; 04142 else if (!strcasecmp(v->value, "lowdelay")) 04143 tos = IPTOS_LOWDELAY; 04144 else if (!strcasecmp(v->value, "throughput")) 04145 tos = IPTOS_THROUGHPUT; 04146 else if (!strcasecmp(v->value, "reliability")) 04147 tos = IPTOS_RELIABILITY; 04148 else if (!strcasecmp(v->value, "mincost")) 04149 tos = IPTOS_MINCOST; 04150 else if (!strcasecmp(v->value, "none")) 04151 tos = 0; 04152 else 04153 ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno); 04154 } else if (!strcasecmp(v->name, "port")) { 04155 if (sscanf(v->value, "%d", &ourport) == 1) { 04156 bindaddr.sin_port = htons(ourport); 04157 } else { 04158 ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config); 04159 } 04160 } 04161 v = v->next; 04162 } 04163 04164 /* SC: mark existing entries for deletion */ 04165 ast_mutex_lock(&gatelock); 04166 g = gateways; 04167 while (g) { 04168 g->delme = 1; 04169 e = g->endpoints; 04170 while (e) { 04171 e->delme = 1; 04172 e = e->next; 04173 } 04174 g = g->next; 04175 } 04176 ast_mutex_unlock(&gatelock); 04177 04178 cat = ast_category_browse(cfg, NULL); 04179 while(cat) { 04180 if (strcasecmp(cat, "general")) { 04181 ast_mutex_lock(&gatelock); 04182 g = build_gateway(cat, ast_variable_browse(cfg, cat)); 04183 if (g) { 04184 if (option_verbose > 2) { 04185 ast_verbose(VERBOSE_PREFIX_3 "Added gateway '%s'\n", g->name); 04186 } 04187 g->next = gateways; 04188 gateways = g; 04189 } 04190 ast_mutex_unlock(&gatelock); 04191 04192 /* FS: process queue and IO */ 04193 if (monitor_thread == pthread_self()) { 04194 if (sched) ast_sched_runq(sched); 04195 if (io) ast_io_wait(io, 10); 04196 } 04197 } 04198 cat = ast_category_browse(cfg, cat); 04199 } 04200 04201 /* SC: prune deleted entries etc. */ 04202 prune_gateways(); 04203 04204 if (ntohl(bindaddr.sin_addr.s_addr)) { 04205 memcpy(&__ourip, &bindaddr.sin_addr, sizeof(__ourip)); 04206 } else { 04207 hp = ast_gethostbyname(ourhost, &ahp); 04208 if (!hp) { 04209 ast_log(LOG_WARNING, "Unable to get our IP address, MGCP disabled\n"); 04210 ast_config_destroy(cfg); 04211 return 0; 04212 } 04213 memcpy(&__ourip, hp->h_addr, sizeof(__ourip)); 04214 } 04215 if (!ntohs(bindaddr.sin_port)) 04216 bindaddr.sin_port = ntohs(DEFAULT_MGCP_CA_PORT); 04217 bindaddr.sin_family = AF_INET; 04218 ast_mutex_lock(&netlock); 04219 if (mgcpsock > -1) 04220 close(mgcpsock); 04221 04222 if (mgcpsock_read_id != NULL) 04223 ast_io_remove(io, mgcpsock_read_id); 04224 mgcpsock_read_id = NULL; 04225 04226 mgcpsock = socket(AF_INET, SOCK_DGRAM, 0); 04227 if (mgcpsock < 0) { 04228 ast_log(LOG_WARNING, "Unable to create MGCP socket: %s\n", strerror(errno)); 04229 } else { 04230 if (bind(mgcpsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { 04231 ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n", 04232 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port), 04233 strerror(errno)); 04234 close(mgcpsock); 04235 mgcpsock = -1; 04236 } else { 04237 if (option_verbose > 1) { 04238 ast_verbose(VERBOSE_PREFIX_2 "MGCP Listening on %s:%d\n", 04239 ast_inet_ntoa(iabuf, sizeof(iabuf), bindaddr.sin_addr), ntohs(bindaddr.sin_port)); 04240 ast_verbose(VERBOSE_PREFIX_2 "Using TOS bits %d\n", tos); 04241 } 04242 if (setsockopt(mgcpsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) 04243 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 04244 } 04245 } 04246 ast_mutex_unlock(&netlock); 04247 ast_config_destroy(cfg); 04248 04249 /* SC: send audit only to the new endpoints */ 04250 g = gateways; 04251 while (g) { 04252 e = g->endpoints; 04253 while (e && e->needaudit) { 04254 e->needaudit = 0; 04255 transmit_audit_endpoint(e); 04256 ast_verbose(VERBOSE_PREFIX_3 "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name); 04257 e = e->next; 04258 } 04259 g = g->next; 04260 } 04261 04262 return 0; 04263 }
|
|
Definition at line 1938 of file chan_mgcp.c. References init_req(), and oseq. 01939 { 01940 memset(req, 0, sizeof(struct mgcp_request)); 01941 oseq++; 01942 if (oseq > 999999999) 01943 oseq = 1; 01944 init_req(p, req, verb); 01945 return 0; 01946 }
|
|
Definition at line 563 of file chan_mgcp.c. References __mgcp_xmit(), mgcp_gateway::addr, ast_inet_ntoa(), ast_verbose(), mgcp_response::buf, mgcp_response::len, mgcp_endpoint::parent, 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 1931 of file chan_mgcp.c. References init_resp(). 01932 { 01933 memset(resp, 0, sizeof(*resp)); 01934 init_resp(resp, msg, req, msgrest); 01935 return 0; 01936 }
|
|
Definition at line 3470 of file chan_mgcp.c. References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create, do_monitor(), LOG_ERROR, LOG_WARNING, and monitor_thread. 03471 { 03472 /* If we're supposed to be stopped -- stay stopped */ 03473 if (monitor_thread == AST_PTHREADT_STOP) 03474 return 0; 03475 if (ast_mutex_lock(&monlock)) { 03476 ast_log(LOG_WARNING, "Unable to lock monitor\n"); 03477 return -1; 03478 } 03479 if (monitor_thread == pthread_self()) { 03480 ast_mutex_unlock(&monlock); 03481 ast_log(LOG_WARNING, "Cannot kill myself\n"); 03482 return -1; 03483 } 03484 if (monitor_thread != AST_PTHREADT_NULL) { 03485 /* Wake up the thread */ 03486 pthread_kill(monitor_thread, SIGURG); 03487 } else { 03488 /* Start a new monitor */ 03489 if (ast_pthread_create(&monitor_thread, NULL, do_monitor, NULL) < 0) { 03490 ast_mutex_unlock(&monlock); 03491 ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); 03492 return -1; 03493 } 03494 } 03495 ast_mutex_unlock(&monlock); 03496 return 0; 03497 }
|
|
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, mgcp_gateway::msgs, mgcp_gateway::msgs_lock, mgcp_gateway::name, mgcp_message::next, mgcp_message::retrans, and mgcp_gateway::retransid. Referenced by 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 1479 of file chan_mgcp.c. 01480 { 01481 *iterator = 0; 01482 }
|
|
Definition at line 800 of file chan_mgcp.c. References mgcp_gateway::addr, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_t, 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(), mgcp_request(), mgcp_request::next, mgcp_endpoint::parent, mgcp_endpoint::rqnt_queue, mgcp_endpoint::rqnt_queue_lock, and mgcp_endpoint::slowsequence. 00802 { 00803 int res = 0; 00804 struct mgcp_request **queue, *q, *r, *t; 00805 char iabuf[INET_ADDRSTRLEN]; 00806 ast_mutex_t *l; 00807 00808 ast_log(LOG_DEBUG, "Slow sequence is %d\n", p->slowsequence); 00809 if (p->slowsequence) { 00810 queue = &p->cmd_queue; 00811 l = &p->cmd_queue_lock; 00812 ast_mutex_lock(l); 00813 } else { 00814 switch (req->cmd) { 00815 case MGCP_CMD_DLCX: 00816 queue = &sub->cx_queue; 00817 l = &sub->cx_queue_lock; 00818 ast_mutex_lock(l); 00819 q = sub->cx_queue; 00820 /* delete pending cx cmds */ 00821 while (q) { 00822 r = q->next; 00823 free(q); 00824 q = r; 00825 } 00826 *queue = NULL; 00827 break; 00828 00829 case MGCP_CMD_CRCX: 00830 case MGCP_CMD_MDCX: 00831 queue = &sub->cx_queue; 00832 l = &sub->cx_queue_lock; 00833 ast_mutex_lock(l); 00834 break; 00835 00836 case MGCP_CMD_RQNT: 00837 queue = &p->rqnt_queue; 00838 l = &p->rqnt_queue_lock; 00839 ast_mutex_lock(l); 00840 break; 00841 00842 default: 00843 queue = &p->cmd_queue; 00844 l = &p->cmd_queue_lock; 00845 ast_mutex_lock(l); 00846 break; 00847 } 00848 } 00849 00850 r = (struct mgcp_request *) malloc (sizeof(struct mgcp_request)); 00851 if (!r) { 00852 ast_log(LOG_WARNING, "Cannot post MGCP request: insufficient memory\n"); 00853 ast_mutex_unlock(l); 00854 return -1; 00855 } 00856 memcpy(r, req, sizeof(struct mgcp_request)); 00857 00858 if (!(*queue)) { 00859 if (mgcpdebug) { 00860 ast_verbose("Posting Request:\n%s to %s:%d\n", req->data, 00861 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00862 } 00863 00864 res = mgcp_postrequest(p, sub, req->data, req->len, seqno); 00865 } else { 00866 if (mgcpdebug) { 00867 ast_verbose("Queueing Request:\n%s to %s:%d\n", req->data, 00868 ast_inet_ntoa(iabuf, sizeof(iabuf), p->parent->addr.sin_addr), ntohs(p->parent->addr.sin_port)); 00869 } 00870 } 00871 00872 /* XXX SC: find tail. We could also keep tail in the data struct for faster access */ 00873 for (t = *queue; t && t->next; t = t->next); 00874 00875 r->next = NULL; 00876 if (t) 00877 t->next = r; 00878 else 00879 *queue = r; 00880 00881 ast_mutex_unlock(l); 00882 00883 return res; 00884 }
|
|
Definition at line 577 of file chan_mgcp.c. References __mgcp_xmit(), mgcp_gateway::addr, ast_inet_ntoa(), ast_verbose(), mgcp_request::data, mgcp_request::len, mgcp_endpoint::parent, and mgcp_subchannel::parent. 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 2541 of file chan_mgcp.c. References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp_destroy(), ast_rtp_fd(), ast_rtp_new_with_bindaddr(), ast_rtp_set_callback(), ast_rtp_set_data(), ast_rtp_setnat(), bindaddr, mgcp_subchannel::callid, ast_channel::fds, io, mgcp_subchannel::lock, mgcp_subchannel::nat, mgcp_subchannel::owner, mgcp_subchannel::rtp, sched, transmit_connect_with_sdp(), and mgcp_subchannel::txident. 02542 { 02543 ast_mutex_lock(&sub->lock); 02544 /* SC: check again to be on the safe side */ 02545 if (sub->rtp) { 02546 ast_rtp_destroy(sub->rtp); 02547 sub->rtp = NULL; 02548 } 02549 /* Allocate the RTP now */ 02550 sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr); 02551 if (sub->rtp && sub->owner) 02552 sub->owner->fds[0] = ast_rtp_fd(sub->rtp); 02553 if (sub->rtp) 02554 ast_rtp_setnat(sub->rtp, sub->nat); 02555 #if 0 02556 ast_rtp_set_callback(p->rtp, rtpready); 02557 ast_rtp_set_data(p->rtp, p); 02558 #endif 02559 /* Make a call*ID */ 02560 snprintf(sub->callid, sizeof(sub->callid), "%08x%s", rand(), sub->txident); 02561 /* Transmit the connection create */ 02562 transmit_connect_with_sdp(sub, NULL); 02563 ast_mutex_unlock(&sub->lock); 02564 }
|
|
Definition at line 2251 of file chan_mgcp.c. References add_header(), mgcp_request::cmd, oseq, reqprep(), send_request(), and mgcp_request::trid. Referenced by handle_request(), mgcp_audit_endpoint(), and reload_config(). 02252 { 02253 struct mgcp_request resp; 02254 reqprep(&resp, p, "AUEP"); 02255 /* SC: removed unknown param VS */ 02256 /*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/ 02257 add_header(&resp, "F", "A"); 02258 /* SC: fill in new fields */ 02259 resp.cmd = MGCP_CMD_AUEP; 02260 resp.trid = oseq; 02261 return send_request(p, NULL, &resp, oseq); /* SC */ 02262 }
|
|
Definition at line 2106 of file chan_mgcp.c. References add_header(), add_sdp(), 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_cxmodes, 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(). 02107 { 02108 struct mgcp_request resp; 02109 char local[256]; 02110 char tmp[80]; 02111 int x; 02112 struct mgcp_endpoint *p = sub->parent; 02113 02114 snprintf(local, sizeof(local), "p:20"); 02115 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02116 if (p->capability & x) { 02117 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02118 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02119 } 02120 } 02121 if (mgcpdebug) { 02122 ast_verbose(VERBOSE_PREFIX_3 "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n", 02123 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02124 } 02125 reqprep(&resp, p, "CRCX"); 02126 add_header(&resp, "C", sub->callid); 02127 add_header(&resp, "L", local); 02128 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02129 /* SC: X header should not be sent. kept for compatibility */ 02130 add_header(&resp, "X", sub->txident); 02131 /*add_header(&resp, "S", "");*/ 02132 ast_rtp_offered_from_local(sub->rtp, 1); 02133 add_sdp(&resp, sub, rtp); 02134 /* SC: fill in new fields */ 02135 resp.cmd = MGCP_CMD_CRCX; 02136 resp.trid = oseq; 02137 return send_request(p, sub, &resp, oseq); /* SC */ 02138 }
|
|
Definition at line 2264 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_cxmodes, 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(). 02265 { 02266 struct mgcp_endpoint *p = sub->parent; 02267 struct mgcp_request resp; 02268 02269 if (mgcpdebug) { 02270 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n", 02271 sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02272 } 02273 reqprep(&resp, p, "DLCX"); 02274 /* SC: check if call id is avail */ 02275 if (sub->callid[0]) 02276 add_header(&resp, "C", sub->callid); 02277 /* SC: X header should not be sent. kept for compatibility */ 02278 add_header(&resp, "X", sub->txident); 02279 /* SC: check if cxident is avail */ 02280 if (sub->cxident[0]) 02281 add_header(&resp, "I", sub->cxident); 02282 /* SC: fill in new fields */ 02283 resp.cmd = MGCP_CMD_DLCX; 02284 resp.trid = oseq; 02285 return send_request(p, sub, &resp, oseq); /* SC */ 02286 }
|
|
Definition at line 2288 of file chan_mgcp.c. References add_header(), ast_verbose(), mgcp_request::cmd, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, reqprep(), send_request(), mgcp_endpoint::sub, mgcp_request::trid, and VERBOSE_PREFIX_3. Referenced by handle_response(). 02289 { 02290 struct mgcp_request resp; 02291 02292 if (mgcpdebug) { 02293 ast_verbose(VERBOSE_PREFIX_3 "Delete connection %s %s@%s on callid: %s\n", 02294 cxident ? cxident : "", p->name, p->parent->name, callid ? callid : ""); 02295 } 02296 reqprep(&resp, p, "DLCX"); 02297 /* SC: check if call id is avail */ 02298 if (callid && *callid) 02299 add_header(&resp, "C", callid); 02300 /* SC: check if cxident is avail */ 02301 if (cxident && *cxident) 02302 add_header(&resp, "I", cxident); 02303 /* SC: fill in new fields */ 02304 resp.cmd = MGCP_CMD_DLCX; 02305 resp.trid = oseq; 02306 return send_request(p, p->sub, &resp, oseq); 02307 }
|
|
Definition at line 2216 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_cxmodes, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_subchannel::rtp, send_request(), mgcp_request::trid, mgcp_subchannel::txident, and VERBOSE_PREFIX_3. Referenced by handle_hd_hf(), handle_request(), mgcp_answer(), mgcp_call(), and mgcp_hangup(). 02217 { 02218 struct mgcp_request resp; 02219 struct mgcp_endpoint *p = sub->parent; 02220 02221 if (ast_strlen_zero(sub->cxident)) { 02222 /* We don't have a CXident yet, store the destination and 02223 wait a bit */ 02224 return 0; 02225 } 02226 if (mgcpdebug) { 02227 ast_verbose(VERBOSE_PREFIX_3 "Modified %s@%s-%d with new mode: %s on callid: %s\n", 02228 p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid); 02229 } 02230 reqprep(&resp, p, "MDCX"); 02231 add_header(&resp, "C", sub->callid); 02232 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02233 /* SC: X header should not be sent. kept for compatibility */ 02234 add_header(&resp, "X", sub->txident); 02235 add_header(&resp, "I", sub->cxident); 02236 switch (sub->parent->hookstate) { 02237 case MGCP_ONHOOK: 02238 add_header(&resp, "R", "L/hd(N)"); 02239 break; 02240 case MGCP_OFFHOOK: 02241 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)"); 02242 break; 02243 } 02244 /* SC: fill in new fields */ 02245 resp.cmd = MGCP_CMD_MDCX; 02246 resp.trid = oseq; 02247 return send_request(p, sub, &resp, oseq); /* SC */ 02248 }
|
|
Definition at line 2065 of file chan_mgcp.c. References add_header(), add_sdp(), 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_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(). 02066 { 02067 struct mgcp_request resp; 02068 char local[256]; 02069 char tmp[80]; 02070 int x; 02071 int capability; 02072 struct mgcp_endpoint *p = sub->parent; 02073 02074 capability = p->capability; 02075 if (codecs) 02076 capability = codecs; 02077 if (ast_strlen_zero(sub->cxident) && rtp) { 02078 /* We don't have a CXident yet, store the destination and 02079 wait a bit */ 02080 ast_rtp_get_peer(rtp, &sub->tmpdest); 02081 return 0; 02082 } 02083 snprintf(local, sizeof(local), "p:20"); 02084 for (x=1;x<= AST_FORMAT_MAX_AUDIO; x <<= 1) { 02085 if (p->capability & x) { 02086 snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype(1, x)); 02087 strncat(local, tmp, sizeof(local) - strlen(local) - 1); 02088 } 02089 } 02090 reqprep(&resp, p, "MDCX"); 02091 add_header(&resp, "C", sub->callid); 02092 add_header(&resp, "L", local); 02093 add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]); 02094 /* SC: X header should not be sent. kept for compatibility */ 02095 add_header(&resp, "X", sub->txident); 02096 add_header(&resp, "I", sub->cxident); 02097 /*add_header(&resp, "S", "");*/ 02098 ast_rtp_offered_from_local(sub->rtp, 0); 02099 add_sdp(&resp, sub, rtp); 02100 /* SC: fill in new fields */ 02101 resp.cmd = MGCP_CMD_MDCX; 02102 resp.trid = oseq; 02103 return send_request(p, sub, &resp, oseq); /* SC */ 02104 }
|
|
Definition at line 2140 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_cxmodes, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_endpoint::rqnt_ident, mgcp_subchannel::rtp, send_request(), mgcp_request::trid, and VERBOSE_PREFIX_3. Referenced by do_monitor(), handle_hd_hf(), handle_request(), handle_response(), mgcp_answer(), mgcp_hangup(), mgcp_indicate(), mgcp_request(), mgcp_senddigit(), and mgcp_ss(). 02141 { 02142 struct mgcp_request resp; 02143 struct mgcp_endpoint *p = sub->parent; 02144 02145 if (mgcpdebug) { 02146 ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", 02147 tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); 02148 } 02149 strncpy(p->curtone, tone, sizeof(p->curtone) - 1); 02150 reqprep(&resp, p, "RQNT"); 02151 add_header(&resp, "X", p->rqnt_ident); /* SC */ 02152 switch (p->hookstate) { 02153 case MGCP_ONHOOK: 02154 add_header(&resp, "R", "L/hd(N)"); 02155 break; 02156 case MGCP_OFFHOOK: 02157 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)"); 02158 break; 02159 } 02160 if (!ast_strlen_zero(tone)) { 02161 add_header(&resp, "S", tone); 02162 } 02163 /* SC: fill in new fields */ 02164 resp.cmd = MGCP_CMD_RQNT; 02165 resp.trid = oseq; 02166 return send_request(p, NULL, &resp, oseq); /* SC */ 02167 }
|
|
Definition at line 2169 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_cxmodes, MGCP_DTMF_INBAND, MGCP_OFFHOOK, MGCP_ONHOOK, mgcp_gateway::name, mgcp_endpoint::name, oseq, mgcp_endpoint::parent, mgcp_subchannel::parent, reqprep(), mgcp_endpoint::rqnt_ident, mgcp_subchannel::rtp, send_request(), mgcp_request::trid, and VERBOSE_PREFIX_3. Referenced by mgcp_call(), and mgcp_hangup(). 02170 { 02171 struct mgcp_request resp; 02172 char tone2[256]; 02173 char *l, *n; 02174 time_t t; 02175 struct tm tm; 02176 struct mgcp_endpoint *p = sub->parent; 02177 02178 time(&t); 02179 localtime_r(&t,&tm); 02180 n = callername; 02181 l = callernum; 02182 if (!n) 02183 n = ""; 02184 if (!l) 02185 l = ""; 02186 02187 /* Keep track of last callerid for blacklist and callreturn */ 02188 strncpy(p->lastcallerid, l, sizeof(p->lastcallerid) - 1); 02189 02190 snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone, 02191 tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n); 02192 strncpy(p->curtone, tone, sizeof(p->curtone) - 1); 02193 reqprep(&resp, p, "RQNT"); 02194 add_header(&resp, "X", p->rqnt_ident); /* SC */ 02195 switch (p->hookstate) { 02196 case MGCP_ONHOOK: 02197 add_header(&resp, "R", "L/hd(N)"); 02198 break; 02199 case MGCP_OFFHOOK: 02200 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)"); 02201 break; 02202 } 02203 if (!ast_strlen_zero(tone2)) { 02204 add_header(&resp, "S", tone2); 02205 } 02206 if (mgcpdebug) { 02207 ast_verbose(VERBOSE_PREFIX_3 "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n", 02208 tone2, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]); 02209 } 02210 /* SC: fill in new fields */ 02211 resp.cmd = MGCP_CMD_RQNT; 02212 resp.trid = oseq; 02213 return send_request(p, NULL, &resp, oseq); /* SC */ 02214 }
|
|
Definition at line 1948 of file chan_mgcp.c. References mgcp_response::buf, mgcp_request::data, mgcp_request::identifier, mgcp_response::len, mgcp_request::len, malloc, mgcp_response::next, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_gateway::responses, respprep(), send_response(), mgcp_response::seqno, and mgcp_response::whensent. 01949 { 01950 struct mgcp_request resp; 01951 struct mgcp_endpoint *p = sub->parent; 01952 struct mgcp_response *mgr; 01953 01954 respprep(&resp, p, msg, req, msgrest); 01955 mgr = malloc(sizeof(struct mgcp_response) + resp.len + 1); 01956 if (mgr) { 01957 /* Store MGCP response in case we have to retransmit */ 01958 memset(mgr, 0, sizeof(struct mgcp_response)); 01959 sscanf(req->identifier, "%d", &mgr->seqno); 01960 time(&mgr->whensent); 01961 mgr->len = resp.len; 01962 memcpy(mgr->buf, resp.data, resp.len); 01963 mgr->buf[resp.len] = '\0'; 01964 mgr->next = p->parent->responses; 01965 p->parent->responses = mgr; 01966 } 01967 return send_response(sub, &resp); 01968 }
|
|
Definition at line 522 of file chan_mgcp.c. References mgcp_subchannel::alreadygone, ast_log(), ast_rtp_destroy(), ast_strlen_zero(), mgcp_subchannel::callid, mgcp_subchannel::cxident, mgcp_subchannel::cxmode, dump_cmd_queues(), mgcp_subchannel::id, LOG_DEBUG, LOG_WARNING, mgcp_gateway::name, mgcp_endpoint::name, mgcp_subchannel::outgoing, mgcp_subchannel::owner, mgcp_endpoint::parent, mgcp_subchannel::parent, mgcp_subchannel::rtp, mgcp_endpoint::sub, mgcp_subchannel::tmpdest, and transmit_connection_del(). 00523 { 00524 struct mgcp_endpoint *p = sub->parent; 00525 if (p->sub == sub) { 00526 ast_log(LOG_WARNING, "Trying to unalloc the real channel %s@%s?!?\n", p->name, p->parent->name); 00527 return -1; 00528 } 00529 ast_log(LOG_DEBUG, "Released sub %d of channel %s@%s\n", sub->id, p->name, p->parent->name); 00530 00531 sub->owner = NULL; 00532 if (!ast_strlen_zero(sub->cxident)) { 00533 transmit_connection_del(sub); 00534 } 00535 sub->cxident[0] = '\0'; 00536 sub->callid[0] = '\0'; 00537 sub->cxmode = MGCP_CX_INACTIVE; 00538 sub->outgoing = 0; 00539 sub->alreadygone = 0; 00540 memset(&sub->tmpdest, 0, sizeof(sub->tmpdest)); 00541 if (sub->rtp) { 00542 ast_rtp_destroy(sub->rtp); 00543 sub->rtp = NULL; 00544 } 00545 dump_cmd_queues(NULL, sub); /* SC */ 00546 return 0; 00547 }
|
|
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 4324 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_rtp_proto_unregister(), cli_audit_endpoint, cli_debug, cli_mgcp_reload, cli_no_debug, cli_show_endpoints, mgcp_endpoint::delme, mgcp_gateway::delme, mgcp_gateway::endpoints, LOG_WARNING, mgcp_reload(), mgcp_reloading, mgcp_rtp, mgcp_tech, mgcpsock, monitor_thread, mgcp_gateway::next, mgcp_endpoint::next, prune_gateways(), sched, and sched_context_destroy(). 04325 { 04326 struct mgcp_endpoint *e; 04327 struct mgcp_gateway *g; 04328 04329 /* Check to see if we're reloading */ 04330 if (ast_mutex_trylock(&mgcp_reload_lock)) { 04331 ast_log(LOG_WARNING, "MGCP is currently reloading. Unable to remove module.\n"); 04332 return -1; 04333 } else { 04334 mgcp_reloading = 1; 04335 ast_mutex_unlock(&mgcp_reload_lock); 04336 } 04337 04338 /* First, take us out of the channel loop */ 04339 ast_channel_unregister(&mgcp_tech); 04340 04341 /* Shut down the monitoring thread */ 04342 if (!ast_mutex_lock(&monlock)) { 04343 if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { 04344 pthread_cancel(monitor_thread); 04345 pthread_kill(monitor_thread, SIGURG); 04346 pthread_join(monitor_thread, NULL); 04347 } 04348 monitor_thread = AST_PTHREADT_STOP; 04349 ast_mutex_unlock(&monlock); 04350 } else { 04351 ast_log(LOG_WARNING, "Unable to lock the monitor\n"); 04352 /* We always want to leave this in a consistent state */ 04353 ast_channel_register(&mgcp_tech); 04354 mgcp_reloading = 0; 04355 mgcp_reload(0, 0, NULL); 04356 return -1; 04357 } 04358 04359 if (!ast_mutex_lock(&gatelock)) { 04360 g = gateways; 04361 while (g) { 04362 g->delme = 1; 04363 e = g->endpoints; 04364 while (e) { 04365 e->delme = 1; 04366 e = e->next; 04367 } 04368 g = g->next; 04369 } 04370 04371 prune_gateways(); 04372 ast_mutex_unlock(&gatelock); 04373 } else { 04374 ast_log(LOG_WARNING, "Unable to lock the gateways list.\n"); 04375 /* We always want to leave this in a consistent state */ 04376 ast_channel_register(&mgcp_tech); 04377 /* Allow the monitor to restart */ 04378 monitor_thread = AST_PTHREADT_NULL; 04379 mgcp_reloading = 0; 04380 mgcp_reload(0, 0, NULL); 04381 return -1; 04382 } 04383 04384 close(mgcpsock); 04385 ast_rtp_proto_unregister(&mgcp_rtp); 04386 ast_cli_unregister(&cli_show_endpoints); 04387 ast_cli_unregister(&cli_audit_endpoint); 04388 ast_cli_unregister(&cli_debug); 04389 ast_cli_unregister(&cli_no_debug); 04390 ast_cli_unregister(&cli_mgcp_reload); 04391 sched_context_destroy(sched); 04392 04393 return 0; 04394 }
|
|
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 4396 of file chan_mgcp.c. 04397 {
04398 return usecnt;
04399 }
|
|
Definition at line 272 of file chan_mgcp.c. Referenced by build_gateway(), find_subchannel_and_lock(), and reload_config(). |
|
Definition at line 234 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 240 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 238 of file chan_mgcp.c. Referenced by build_gateway(). |
|
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. Referenced by reload_config(), and start_rtp(). |
|
Definition at line 215 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 207 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 224 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 228 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 268 of file chan_mgcp.c. Referenced by process_sdp(), reload_config(), and transmit_modify_with_sdp(). |
|
Definition at line 184 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 183 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Initial value: { { "mgcp", "audit", "endpoint", NULL }, mgcp_audit_endpoint, "Audit specified MGCP endpoint", audit_endpoint_usage } Definition at line 1180 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "debug", NULL }, mgcp_do_debug, "Enable MGCP debugging", debug_usage } Definition at line 3990 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "reload", NULL }, mgcp_reload, "Reload MGCP configuration", mgcp_reload_usage } Definition at line 3994 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "no", "debug", NULL }, mgcp_no_debug, "Disable MGCP debugging", no_debug_usage } Definition at line 3992 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Initial value: { { "mgcp", "show", "endpoints", NULL }, mgcp_show_endpoints, "Show defined MGCP endpoints", show_endpoints_usage } Definition at line 1119 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 139 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 179 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 195 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 196 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Initial value: "Usage: mgcp debug\n" " Enables dumping of MGCP packets for debugging purposes\n" Definition at line 3978 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(), and reload_config(). |
|
Definition at line 248 of file chan_mgcp.c. |
|
Referenced by prune_gateways(), and reload_config(). |
|
Definition at line 251 of file chan_mgcp.c. |
|
Definition at line 205 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 278 of file chan_mgcp.c. Referenced by do_monitor(), load_module(), reload_config(), and start_rtp(). |
|
Definition at line 181 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 236 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 254 of file chan_mgcp.c. |
|
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 3986 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 3954 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 500 of file chan_mgcp.c. Referenced by load_module(), and unload_module(). |
|
Definition at line 275 of file chan_mgcp.c. Referenced by mgcp_do_debug(), and mgcp_no_debug(). |
|
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 3382 of file chan_mgcp.c. Referenced by do_monitor(), and reload_config(). |
|
Definition at line 264 of file chan_mgcp.c. Referenced by reload_config(), restart_monitor(), and unload_module(). |
|
Definition at line 182 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 187 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Initial value: "Usage: mgcp no debug\n" " Disables dumping of MGCP packets for debugging purposes\n" Definition at line 3982 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 reload_config(). |
|
Definition at line 273 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 277 of file chan_mgcp.c. Referenced by build_gateway(), do_monitor(), load_module(), mgcp_postrequest(), mgcpsock_read(), reload_config(), start_rtp(), and unload_module(). |
|
Initial value: "Usage: mgcp show endpoints\n" " Lists all endpoints known to the MGCP (Media Gateway Control Protocol) subsystem.\n" Definition at line 1115 of file chan_mgcp.c. |
|
Definition at line 226 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 217 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 138 of file chan_mgcp.c. |
|
Definition at line 219 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 203 of file chan_mgcp.c. Referenced by reload_config(). |
|
Definition at line 222 of file chan_mgcp.c. Referenced by build_gateway(). |
|
Definition at line 137 of file chan_mgcp.c. |
|
Definition at line 242 of file chan_mgcp.c. Referenced by mgcp_hangup(), and mgcp_new(). |