| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (C) 2004-2005 by Objective Systems, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This software is furnished under an open source license and may be  | 
					
						
							|  |  |  |  * used and copied only in accordance with the terms of this license.  | 
					
						
							|  |  |  |  * The text of the license may generally be found in the root  | 
					
						
							|  |  |  |  * directory of this installation in the COPYING file.  It  | 
					
						
							|  |  |  |  * can also be viewed online at the following URL: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   http://www.obj-sys.com/open/license.html
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Any redistributions of this file including modified versions must  | 
					
						
							|  |  |  |  * maintain this copyright notice. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | /* Reworked version I, Nov-2009, by Alexandr Anikin, may@telecom-service.ru */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-06 22:02:36 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<defaultenabled>no</defaultenabled> | 
					
						
							| 
									
										
										
										
											2011-07-14 20:13:06 +00:00
										 |  |  | 	<support_level>extended</support_level> | 
					
						
							| 
									
										
										
										
											2009-11-06 22:02:36 +00:00
										 |  |  |  ***/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | #include "chan_ooh323.h"
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | #include <math.h>
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | #define FORMAT_STRING_SIZE	512
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Defaults */ | 
					
						
							|  |  |  | #define DEFAULT_CONTEXT "default"
 | 
					
						
							|  |  |  | #define DEFAULT_H323ID "Asterisk PBX"
 | 
					
						
							|  |  |  | #define DEFAULT_LOGFILE "/var/log/asterisk/h323_log"
 | 
					
						
							|  |  |  | #define DEFAULT_H323ACCNT "ast_h323"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Flags */ | 
					
						
							|  |  |  | #define H323_SILENCESUPPRESSION (1<<0)
 | 
					
						
							|  |  |  | #define H323_GKROUTED           (1<<1)
 | 
					
						
							|  |  |  | #define H323_TUNNELING          (1<<2)
 | 
					
						
							|  |  |  | #define H323_FASTSTART          (1<<3)
 | 
					
						
							|  |  |  | #define H323_OUTGOING           (1<<4)
 | 
					
						
							|  |  |  | #define H323_ALREADYGONE        (1<<5)
 | 
					
						
							|  |  |  | #define H323_NEEDDESTROY        (1<<6)
 | 
					
						
							|  |  |  | #define H323_DISABLEGK          (1<<7)
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | #define H323_NEEDSTART		(1<<8)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MAXT30	240
 | 
					
						
							|  |  |  | #define T38TOAUDIOTIMEOUT 30
 | 
					
						
							|  |  |  | #define T38_DISABLED 0
 | 
					
						
							|  |  |  | #define T38_ENABLED 1
 | 
					
						
							|  |  |  | #define T38_FAXGW 1
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Channel description */ | 
					
						
							|  |  |  | static const char type[] = "OOH323"; | 
					
						
							|  |  |  | static const char tdesc[] = "Objective Systems H323 Channel Driver"; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static const char config[] = "ooh323.conf"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_module *myself; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static struct ast_jb_conf default_jbconf = | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	.flags = 0, | 
					
						
							|  |  |  | 	.max_size = -1, | 
					
						
							|  |  |  | 	.resync_threshold = -1, | 
					
						
							|  |  |  | 	.impl = "" | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | static struct ast_jb_conf global_jbconf; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Channel Definition */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | static struct ast_channel *ooh323_request(const char *type, format_t format,  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			const struct ast_channel *requestor,  void *data, int *cause); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static int ooh323_digit_begin(struct ast_channel *ast, char digit); | 
					
						
							|  |  |  | static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration); | 
					
						
							|  |  |  | static int ooh323_call(struct ast_channel *ast, char *dest, int timeout); | 
					
						
							|  |  |  | static int ooh323_hangup(struct ast_channel *ast); | 
					
						
							|  |  |  | static int ooh323_answer(struct ast_channel *ast); | 
					
						
							|  |  |  | static struct ast_frame *ooh323_read(struct ast_channel *ast); | 
					
						
							|  |  |  | static int ooh323_write(struct ast_channel *ast, struct ast_frame *f); | 
					
						
							|  |  |  | static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp); | 
					
						
							|  |  |  | static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp); | 
					
						
							|  |  |  | static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  |           struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan); | 
					
						
							|  |  |  | static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void print_codec_to_cli(int fd, struct ast_codec_pref *pref); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | struct ooh323_peer *find_friend(const char *name, int port); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static const struct ast_channel_tech ooh323_tech = { | 
					
						
							|  |  |  | 	.type = type, | 
					
						
							|  |  |  | 	.description = tdesc, | 
					
						
							|  |  |  | 	.capabilities = -1, | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER, | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	.requester = ooh323_request, | 
					
						
							|  |  |  | 	.send_digit_begin = ooh323_digit_begin, | 
					
						
							|  |  |  | 	.send_digit_end = ooh323_digit_end, | 
					
						
							|  |  |  | 	.call = ooh323_call, | 
					
						
							|  |  |  | 	.hangup = ooh323_hangup, | 
					
						
							|  |  |  | 	.answer = ooh323_answer, | 
					
						
							|  |  |  | 	.read = ooh323_read, | 
					
						
							|  |  |  | 	.write = ooh323_write, | 
					
						
							|  |  |  | 	.exception = ooh323_read, | 
					
						
							|  |  |  | 	.indicate = ooh323_indicate, | 
					
						
							|  |  |  | 	.fixup = ooh323_fixup, | 
					
						
							|  |  |  | 	.send_html = 0, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	.queryoption = ooh323_queryoption, | 
					
						
							|  |  |  | 	.bridge = ast_rtp_instance_bridge,		/* XXX chan unlocked ? */ | 
					
						
							|  |  |  | 	.early_bridge = ast_rtp_instance_early_bridge, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static struct ast_rtp_glue ooh323_rtp = { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	.type = type, | 
					
						
							|  |  |  | 	.get_rtp_info = ooh323_get_rtp_peer, | 
					
						
							|  |  |  | 	.get_vrtp_info = ooh323_get_vrtp_peer, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	.update_peer = ooh323_set_rtp_peer, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_udptl_protocol ooh323_udptl = { | 
					
						
							|  |  |  | 	type: "H323", | 
					
						
							|  |  |  | 	get_udptl_info: ooh323_get_udptl_peer, | 
					
						
							|  |  |  | 	set_udptl_peer: ooh323_set_udptl_peer, | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ooh323_user; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | /* H.323 channel private structure */ | 
					
						
							|  |  |  | static struct ooh323_pvt { | 
					
						
							|  |  |  | 	ast_mutex_t lock;		/* Channel private lock */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct ast_rtp_instance *rtp; | 
					
						
							|  |  |  | 	struct ast_rtp_instance *vrtp; /* Placeholder for now */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int t38support;			/* T.38 mode - disable, transparent, faxgw */ | 
					
						
							|  |  |  | 	int rtptimeout; | 
					
						
							|  |  |  | 	struct ast_udptl *udptl; | 
					
						
							|  |  |  | 	int faxmode; | 
					
						
							|  |  |  | 	int t38_tx_enable; | 
					
						
							|  |  |  | 	int t38_init; | 
					
						
							|  |  |  | 	struct sockaddr_in udptlredirip; | 
					
						
							|  |  |  | 	time_t lastTxT38; | 
					
						
							|  |  |  | 	int chmodepend; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_channel *owner;	/* Master Channel */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	union { | 
					
						
							|  |  |  |     		char  *user;	/* cooperating user/peer */ | 
					
						
							|  |  |  |     		char  *peer; | 
					
						
							|  |  |  |    	} neighbor; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	time_t lastrtptx; | 
					
						
							|  |  |  | 	time_t lastrtprx; | 
					
						
							|  |  |  | 	unsigned int flags; | 
					
						
							|  |  |  | 	unsigned int call_reference; | 
					
						
							|  |  |  | 	char *callToken; | 
					
						
							|  |  |  | 	char *username; | 
					
						
							|  |  |  | 	char *host; | 
					
						
							|  |  |  | 	char *callerid_name; | 
					
						
							|  |  |  | 	char *callerid_num; | 
					
						
							|  |  |  | 	char caller_h323id[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char caller_dialedDigits[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char caller_email[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char caller_url[256]; | 
					
						
							|  |  |  | 	char callee_h323id[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char callee_dialedDigits[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char callee_email[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	char callee_url[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | 	int port; | 
					
						
							| 
									
										
										
										
											2009-12-01 20:27:37 +00:00
										 |  |  | 	format_t readformat;   /* negotiated read format */ | 
					
						
							|  |  |  | 	format_t writeformat;  /* negotiated write format */ | 
					
						
							|  |  |  | 	format_t capability; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_codec_pref prefs; | 
					
						
							|  |  |  | 	int dtmfmode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	int dtmfcodec; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	char exten[AST_MAX_EXTENSION];	/* Requested extension */ | 
					
						
							|  |  |  | 	char context[AST_MAX_EXTENSION];	/* Context where to start */ | 
					
						
							|  |  |  | 	char accountcode[256];	/* Account code */ | 
					
						
							|  |  |  | 	int nat; | 
					
						
							|  |  |  | 	int amaflags; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	int progsent;			/* progress is sent */ | 
					
						
							| 
									
										
										
										
											2011-02-10 18:50:50 +00:00
										 |  |  | 	int alertsent;			/* alerting is sent */ | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 	int g729onlyA;			/* G.729 only A */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_dsp *vad; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct OOH323Regex *rtpmask;	/* rtp ip regexp */ | 
					
						
							|  |  |  | 	char rtpmaskstr[120]; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	int rtdrcount, rtdrinterval;	/* roundtripdelayreq */ | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 	int faststart, h245tunneling;	/* faststart & h245 tunneling */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ooh323_pvt *next;	/* Next entity */ | 
					
						
							|  |  |  | } *iflist = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Protect the channel/interface list (ooh323_pvt) */ | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(iflock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Profile of H.323 user registered with PBX*/ | 
					
						
							|  |  |  | struct ooh323_user{ | 
					
						
							|  |  |  | 	ast_mutex_t lock; | 
					
						
							|  |  |  | 	char        name[256]; | 
					
						
							|  |  |  | 	char        context[AST_MAX_EXTENSION]; | 
					
						
							|  |  |  | 	int         incominglimit; | 
					
						
							|  |  |  | 	unsigned    inUse; | 
					
						
							|  |  |  | 	char        accountcode[20]; | 
					
						
							|  |  |  | 	int         amaflags; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 	format_t    capability; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_codec_pref prefs; | 
					
						
							|  |  |  | 	int         dtmfmode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	int	    dtmfcodec; | 
					
						
							|  |  |  | 	int	    t38support; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	int         rtptimeout; | 
					
						
							|  |  |  | 	int         mUseIP;        /* Use IP address or H323-ID to search user */ | 
					
						
							|  |  |  | 	char        mIP[20]; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct OOH323Regex	    *rtpmask; | 
					
						
							|  |  |  | 	char	    rtpmaskstr[120]; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	int	    rtdrcount, rtdrinterval; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 	int	    faststart, h245tunneling; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 	int	    g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ooh323_user *next; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Profile of valid asterisk peers */ | 
					
						
							|  |  |  | struct ooh323_peer{ | 
					
						
							|  |  |  | 	ast_mutex_t lock; | 
					
						
							|  |  |  | 	char        name[256]; | 
					
						
							|  |  |  | 	unsigned    outgoinglimit; | 
					
						
							|  |  |  | 	unsigned    outUse; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 	format_t    capability; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_codec_pref prefs; | 
					
						
							|  |  |  | 	char        accountcode[20]; | 
					
						
							|  |  |  | 	int         amaflags; | 
					
						
							|  |  |  | 	int         dtmfmode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	int	    dtmfcodec; | 
					
						
							|  |  |  | 	int	    t38support; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	int         mFriend;    /* indicates defined as friend */ | 
					
						
							|  |  |  | 	char        ip[20]; | 
					
						
							|  |  |  | 	int         port; | 
					
						
							|  |  |  | 	char        *h323id;    /* H323-ID alias, which asterisk will register with gk to reach this peer*/ | 
					
						
							|  |  |  | 	char        *email;     /* Email alias, which asterisk will register with gk to reach this peer*/ | 
					
						
							|  |  |  | 	char        *url;       /* url alias, which asterisk will register with gk to reach this peer*/ | 
					
						
							|  |  |  | 	char        *e164;      /* e164 alias, which asterisk will register with gk to reach this peer*/ | 
					
						
							|  |  |  | 	int         rtptimeout; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct OOH323Regex	    *rtpmask; | 
					
						
							|  |  |  | 	char	    rtpmaskstr[120]; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	int	    rtdrcount,rtdrinterval; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 	int	    faststart, h245tunneling; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 	int	    g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ooh323_peer *next; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* List of H.323 users known to PBX */ | 
					
						
							|  |  |  | static struct ast_user_list { | 
					
						
							|  |  |  | 	struct ooh323_user *users; | 
					
						
							|  |  |  | 	ast_mutex_t lock; | 
					
						
							|  |  |  | } userl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_peer_list { | 
					
						
							|  |  |  | 	struct ooh323_peer *peers; | 
					
						
							|  |  |  | 	ast_mutex_t lock; | 
					
						
							|  |  |  | } peerl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Mutex to protect H.323 reload process */ | 
					
						
							|  |  |  | static int h323_reloading = 0; | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(h323_reload_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Mutex to protect usage counter */ | 
					
						
							|  |  |  | static int usecnt = 0; | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(usecnt_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(ooh323c_cmd_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static long callnumber = 0; | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(ooh323c_cn_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | /* stack callbacks */ | 
					
						
							|  |  |  | int onAlerting(ooCallData *call); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | int onProgress(ooCallData *call); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | int onNewCallCreated(ooCallData *call); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | int onOutgoingCall(ooCallData *call); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | int onCallEstablished(ooCallData *call); | 
					
						
							|  |  |  | int onCallCleared(ooCallData *call); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | void onModeChanged(ooCallData *call, int t38mode); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char gLogFile[256] = DEFAULT_LOGFILE; | 
					
						
							|  |  |  | static int  gPort = 1720; | 
					
						
							|  |  |  | static char gIP[20]; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static char gCallerID[AST_MAX_EXTENSION] = ""; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static struct ooAliases *gAliasList; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | static format_t gCapability = AST_FORMAT_ULAW; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static struct ast_codec_pref gPrefs; | 
					
						
							|  |  |  | static int  gDTMFMode = H323_DTMF_RFC2833; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int  gDTMFCodec = 101; | 
					
						
							|  |  |  | static int  gT38Support = T38_FAXGW; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static char gGatekeeper[100]; | 
					
						
							|  |  |  | static enum RasGatekeeperMode gRasGkMode = RasNoGatekeeper; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int  gIsGateway = 0; | 
					
						
							|  |  |  | static int  gFastStart = 1; | 
					
						
							|  |  |  | static int  gTunneling = 1; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int  gBeMaster = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static int  gMediaWaitForConnect = 0; | 
					
						
							|  |  |  | static int  gTOS = 0; | 
					
						
							|  |  |  | static int  gRTPTimeout = 60; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | static int  g729onlyA = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static char gAccountcode[80] = DEFAULT_H323ACCNT; | 
					
						
							|  |  |  | static int  gAMAFLAGS; | 
					
						
							|  |  |  | static char gContext[AST_MAX_EXTENSION] = DEFAULT_CONTEXT; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int  gIncomingLimit = 1024; | 
					
						
							|  |  |  | static int  gOutgoingLimit = 1024; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | OOBOOL gH323Debug = FALSE; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int gTRCLVL = OOTRCLVLERR; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | static int gRTDRCount = 0, gRTDRInterval = 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int t35countrycode = 0; | 
					
						
							|  |  |  | static int t35extensions = 0; | 
					
						
							|  |  |  | static int manufacturer = 0; | 
					
						
							|  |  |  | static char vendor[AST_MAX_EXTENSION] =  ""; | 
					
						
							|  |  |  | static char version[AST_MAX_EXTENSION] = ""; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct ooh323_config | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |    int  mTCPPortStart; | 
					
						
							|  |  |  |    int  mTCPPortEnd; | 
					
						
							|  |  |  | } ooconfig; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Asterisk RTP stuff*/ | 
					
						
							|  |  |  | static struct sched_context *sched; | 
					
						
							|  |  |  | static struct io_context *io; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Protect the monitoring thread, so only one process can kill or start it, 
 | 
					
						
							|  |  |  |    and not when it's doing something critical. */ | 
					
						
							|  |  |  | AST_MUTEX_DEFINE_STATIC(monlock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* This is the thread for the monitor which checks for input on the channels
 | 
					
						
							|  |  |  |    which are not currently in use.  */ | 
					
						
							|  |  |  | static pthread_t monitor_thread = AST_PTHREADT_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |                                              const char *host, int capability, const char *linkedid)  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ast_channel *ch = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	int fmt = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_verbose("---   ooh323_new - %s, %d\n", host, capability); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Don't hold a h323 pvt lock while we allocate a channel */ | 
					
						
							|  |  |  | 	ast_mutex_unlock(&i->lock); | 
					
						
							| 
									
										
										
										
											2011-10-18 23:20:53 +00:00
										 |  |  |    	ast_mutex_lock(&ooh323c_cn_lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,  | 
					
						
							|  |  |  | 				i->accountcode, i->exten, i->context, linkedid, i->amaflags, | 
					
						
							|  |  |  | 				"OOH323/%s-%ld", host, callnumber); | 
					
						
							|  |  |  |    	callnumber++; | 
					
						
							|  |  |  |    	ast_mutex_unlock(&ooh323c_cn_lock); | 
					
						
							|  |  |  |     | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&i->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ch) { | 
					
						
							|  |  |  | 		ast_channel_lock(ch); | 
					
						
							|  |  |  | 		ch->tech = &ooh323_tech; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (capability) | 
					
						
							|  |  |  | 			fmt = ast_best_codec(capability); | 
					
						
							|  |  |  | 		if (!fmt)  | 
					
						
							|  |  |  | 			fmt = ast_codec_pref_index(&i->prefs, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ch->nativeformats = ch->rawwriteformat = ch->rawreadformat = fmt; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(i->rtp, 0)); | 
					
						
							|  |  |  | 		ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(i->rtp, 1)); | 
					
						
							|  |  |  | 		ast_channel_set_fd(ch, 5, ast_udptl_fd(i->udptl)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_jb_configure(ch, &global_jbconf); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (state == AST_STATE_RING) | 
					
						
							|  |  |  | 			ch->rings = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ch->adsicpe = AST_ADSI_UNAVAILABLE; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_set_write_format(ch, fmt); | 
					
						
							|  |  |  | 		ast_set_read_format(ch, fmt); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ch->tech_pvt = i; | 
					
						
							|  |  |  | 		i->owner = ch; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_module_ref(myself); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Allocate dsp for in-band DTMF support */ | 
					
						
							|  |  |  | 		if (i->dtmfmode & H323_DTMF_INBAND) { | 
					
						
							|  |  |  | 			i->vad = ast_dsp_new(); | 
					
						
							|  |  |  | 			ast_dsp_set_features(i->vad, DSP_FEATURE_DIGIT_DETECT); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |        			ast_dsp_set_features(i->vad, | 
					
						
							|  |  |  | 						DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT); | 
					
						
							|  |  |  |         		ast_dsp_set_faxmode(i->vad, | 
					
						
							|  |  |  | 						DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_CED); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (i->dtmfmode & H323_DTMF_INBANDRELAX) | 
					
						
							|  |  |  | 				ast_dsp_set_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_lock(&usecnt_lock); | 
					
						
							|  |  |  | 		usecnt++; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&usecnt_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Notify the module monitors that use count for resource has changed*/ | 
					
						
							|  |  |  | 		ast_update_use_count(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_copy_string(ch->context, i->context, sizeof(ch->context)); | 
					
						
							|  |  |  | 		ast_copy_string(ch->exten, i->exten, sizeof(ch->exten)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ch->priority = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		if(!ast_test_flag(i, H323_OUTGOING)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(i->caller_h323id)) { | 
					
						
							|  |  |  | 				pbx_builtin_setvar_helper(ch, "_CALLER_H323ID", i->caller_h323id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(i->caller_dialedDigits)) { | 
					
						
							|  |  |  | 				pbx_builtin_setvar_helper(ch, "_CALLER_H323DIALEDDIGITS",  | 
					
						
							|  |  |  | 				i->caller_dialedDigits); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(i->caller_email)) { | 
					
						
							|  |  |  | 				pbx_builtin_setvar_helper(ch, "_CALLER_H323EMAIL",  | 
					
						
							|  |  |  | 				i->caller_email); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(i->caller_url)) { | 
					
						
							|  |  |  | 				pbx_builtin_setvar_helper(ch, "_CALLER_H323URL", i->caller_url); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(i->accountcode)) | 
					
						
							|  |  |  | 			ast_string_field_set(ch, accountcode, i->accountcode); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (i->amaflags) | 
					
						
							|  |  |  | 			ch->amaflags = i->amaflags; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_setstate(ch, state); | 
					
						
							|  |  |  | 		if (state != AST_STATE_DOWN) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		if (ast_pbx_start(ch)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ch->name); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			ast_channel_unlock(ch); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_hangup(ch); | 
					
						
							|  |  |  | 				ch = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			}  | 
					
						
							|  |  |  | 	 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-14 09:41:38 +00:00
										 |  |  | 		if (ch) { | 
					
						
							|  |  |  | 			manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",  | 
					
						
							|  |  |  | 				"Channel: %s\r\nChanneltype: %s\r\n" | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				"CallRef: %d\r\n", ch->name, "OOH323", i->call_reference); | 
					
						
							| 
									
										
										
										
											2012-02-14 09:41:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} else | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	if(ch)   ast_channel_unlock(ch); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   h323_new\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ch; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)  | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *pvt = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct sockaddr_in ouraddr; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	struct ast_sockaddr tmp; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct in_addr ipAddr; | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_alloc\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(pvt = ast_calloc(1, sizeof(*pvt)))) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_init(&pvt->lock); | 
					
						
							|  |  |  | 	ast_mutex_lock(&pvt->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (!inet_aton(gIP, &ipAddr)) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Invalid OOH323 driver ip address\n"); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&pvt->lock); | 
					
						
							|  |  |  | 		ast_mutex_destroy(&pvt->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_free(pvt); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	ouraddr.sin_family = AF_INET; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ouraddr.sin_addr = ipAddr; | 
					
						
							| 
									
										
										
										
											2010-07-08 23:23:17 +00:00
										 |  |  | 	ast_sockaddr_from_sin(&tmp, &ouraddr); | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	if (!(pvt->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to create RTP session: %s\n",  | 
					
						
							|  |  |  | 				  strerror(errno)); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&pvt->lock); | 
					
						
							|  |  |  | 		ast_mutex_destroy(&pvt->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_free(pvt); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_rtp_instance_set_qos(pvt->rtp, gTOS, 0, "ooh323-rtp"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-23 15:52:37 +00:00
										 |  |  | 	if (!(pvt->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &tmp))) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n", | 
					
						
							|  |  |  | 				strerror(errno)); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&pvt->lock); | 
					
						
							|  |  |  | 		ast_mutex_destroy(&pvt->lock); | 
					
						
							|  |  |  | 		ast_free(pvt); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_udptl_set_error_correction_scheme(pvt->udptl, UDPTL_ERROR_CORRECTION_NONE); | 
					
						
							| 
									
										
										
										
											2011-03-14 21:45:53 +00:00
										 |  |  | 	ast_udptl_set_far_max_datagram(pvt->udptl, 144); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	pvt->faxmode = 0; | 
					
						
							|  |  |  | 	pvt->t38support = gT38Support; | 
					
						
							|  |  |  | 	pvt->rtptimeout = gRTPTimeout; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	pvt->rtdrinterval = gRTDRInterval; | 
					
						
							|  |  |  | 	pvt->rtdrcount = gRTDRCount; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 	pvt->g729onlyA = g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pvt->call_reference = callref; | 
					
						
							|  |  |  | 	if (callToken) | 
					
						
							|  |  |  | 		pvt->callToken = strdup(callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* whether to use gk for this call */ | 
					
						
							|  |  |  | 	if (gRasGkMode == RasNoGatekeeper) | 
					
						
							|  |  |  | 		OO_SETFLAG(pvt->flags, H323_DISABLEGK); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pvt->dtmfmode = gDTMFMode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	pvt->dtmfcodec = gDTMFCodec; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_copy_string(pvt->context, gContext, sizeof(pvt->context)); | 
					
						
							|  |  |  | 	ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	pvt->amaflags = gAMAFLAGS; | 
					
						
							|  |  |  | 	pvt->capability = gCapability; | 
					
						
							|  |  |  | 	memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&pvt->lock);  | 
					
						
							|  |  |  | 	/* Add to interface list */ | 
					
						
							|  |  |  | 	ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 	pvt->next = iflist; | 
					
						
							|  |  |  | 	iflist = pvt; | 
					
						
							|  |  |  | 	ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_alloc\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return pvt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  | 	Possible data values - peername, exten/peername, exten@ip | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | static struct ast_channel *ooh323_request(const char *type, format_t format, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		const struct ast_channel *requestor, void *data, int *cause) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ast_channel *chan = NULL; | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct ooh323_peer *peer = NULL; | 
					
						
							|  |  |  | 	char *dest = NULL;  | 
					
						
							|  |  |  | 	char *ext = NULL; | 
					
						
							|  |  |  | 	char tmp[256]; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	char formats[FORMAT_STRING_SIZE]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	int port = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_request - data %s format %s\n", (char*)data,   | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 										ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,format)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	format &= AST_FORMAT_AUDIO_MASK; | 
					
						
							|  |  |  | 	if (!format) { | 
					
						
							| 
									
										
										
										
											2010-01-10 19:37:30 +00:00
										 |  |  | 		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%lld'\n", (long long) format); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = ooh323_alloc(0,0); /* Initial callRef is zero */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char*)data); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* This is an outgoing call, since ooh323_request is called */ | 
					
						
							|  |  |  | 	ast_set_flag(p, H323_OUTGOING); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    	ast_copy_string(tmp, data, sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dest = strchr(tmp, '/'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dest) {   | 
					
						
							|  |  |  | 		*dest = '\0'; | 
					
						
							|  |  |  | 		dest++; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ext = dest; | 
					
						
							|  |  |  | 		dest = tmp; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} else if ((dest = strchr(tmp, '@'))) { | 
					
						
							|  |  |  | 		*dest = '\0'; | 
					
						
							|  |  |  | 		dest++; | 
					
						
							|  |  |  | 		ext = tmp; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		dest = tmp; | 
					
						
							|  |  |  | 		ext = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	if ((sport = strchr(dest, ':'))) { | 
					
						
							|  |  |  | 		*sport = '\0'; | 
					
						
							|  |  |  | 		sport++; | 
					
						
							|  |  |  | 		port = atoi(sport); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (dest) { | 
					
						
							|  |  |  | 		peer = find_peer(dest, port); | 
					
						
							|  |  |  | 	} else{ | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 		ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ooh323_destroy(p); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&iflock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Destination format is not supported\n"); | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (peer) { | 
					
						
							|  |  |  | 		p->username = strdup(peer->name); | 
					
						
							|  |  |  | 		p->host = strdup(peer->ip); | 
					
						
							|  |  |  | 		p->port = peer->port; | 
					
						
							|  |  |  | 		/* Disable gk as we are going to call a known peer*/ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		/* OO_SETFLAG(p->flags, H323_DISABLEGK); */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (ext) | 
					
						
							|  |  |  | 			ast_copy_string(p->exten, ext, sizeof(p->exten)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		p->capability = peer->capability; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref)); | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		p->g729onlyA = peer->g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		p->dtmfmode |= peer->dtmfmode; | 
					
						
							|  |  |  | 		p->dtmfcodec  = peer->dtmfcodec; | 
					
						
							|  |  |  | 		p->t38support = peer->t38support; | 
					
						
							|  |  |  | 		p->rtptimeout = peer->rtptimeout; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 		p->faststart = peer->faststart; | 
					
						
							|  |  |  | 		p->h245tunneling = peer->h245tunneling; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (peer->rtpmask && peer->rtpmaskstr[0]) { | 
					
						
							|  |  |  | 			p->rtpmask = peer->rtpmask; | 
					
						
							|  |  |  | 			ast_copy_string(p->rtpmaskstr, peer->rtpmaskstr, sizeof(p->rtpmaskstr)); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (peer->rtdrinterval) { | 
					
						
							|  |  |  | 			p->rtdrinterval = peer->rtdrinterval; | 
					
						
							|  |  |  | 			p->rtdrcount = peer->rtdrcount; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_copy_string(p->accountcode, peer->accountcode, sizeof(p->accountcode)); | 
					
						
							|  |  |  | 		p->amaflags = peer->amaflags; | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 		if (gRasGkMode ==  RasNoGatekeeper) { | 
					
						
							|  |  |  | 			/* no gk and no peer */ | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Call to undefined peer %s", dest); | 
					
						
							|  |  |  | 			ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ooh323_destroy(p); | 
					
						
							|  |  |  | 			ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		p->g729onlyA = g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		p->dtmfmode = gDTMFMode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		p->dtmfcodec = gDTMFCodec; | 
					
						
							|  |  |  | 		p->t38support = gT38Support; | 
					
						
							|  |  |  | 		p->rtptimeout = gRTPTimeout; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		p->capability = gCapability; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 		p->rtdrinterval = gRTDRInterval; | 
					
						
							|  |  |  | 		p->rtdrcount = gRTDRCount; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 		p->faststart = gFastStart; | 
					
						
							|  |  |  | 		p->h245tunneling = gTunneling; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref)); | 
					
						
							|  |  |  | 		p->username = strdup(dest); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		p->host = strdup(dest); | 
					
						
							|  |  |  | 		if (port > 0) { | 
					
						
							|  |  |  | 			p->port = port; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (ext) { | 
					
						
							|  |  |  | 			ast_copy_string(p->exten, ext, sizeof(p->exten)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	chan = ooh323_new(p, AST_STATE_DOWN, p->username, format, | 
					
						
							|  |  |  | 				 requestor ? requestor->linkedid : NULL); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!chan) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 		ooh323_destroy(p); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&iflock); | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  |    	} else { | 
					
						
							|  |  |  |       		ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  |       		p->callToken = (char*)ast_malloc(AST_MAX_EXTENSION); | 
					
						
							|  |  |  |       		if(!p->callToken) { | 
					
						
							|  |  |  |        			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  |        			ast_mutex_lock(&iflock); | 
					
						
							|  |  |  |        			ooh323_destroy(p); | 
					
						
							|  |  |  |        			ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  |        			ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n"); | 
					
						
							|  |  |  |        			return NULL; | 
					
						
							|  |  |  |       		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  |       		ast_mutex_lock(&ooh323c_cmd_lock); | 
					
						
							|  |  |  |       		ooMakeCall(data, p->callToken, AST_MAX_EXTENSION, NULL); | 
					
						
							|  |  |  |       		ast_mutex_unlock(&ooh323c_cmd_lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	restart_monitor(); | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_request\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return chan; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ooh323_pvt* find_call(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   find_call\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (p = iflist; p; p = p->next) { | 
					
						
							|  |  |  | 		if (p->callToken && !strcmp(p->callToken, call->callToken)) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   find_call\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ooh323_user *find_user(const char * name, const char* ip) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *user; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_verbose("---   find_user: %s, %s\n",name,ip); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&userl.lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	for (user = userl.users; user; user = user->next) { | 
					
						
							|  |  |  | 		if (ip && user->mUseIP && !strcmp(user->mIP, ip)) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (name && !strcmp(user->name, name)) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   find_user\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return user; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ooh323_peer *find_friend(const char *name, int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *peer;   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   find_friend \"%s\"\n", name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 	for (peer = peerl.peers; peer; peer = peer->next) { | 
					
						
							|  |  |  | 		if (gH323Debug) { | 
					
						
							|  |  |  | 			ast_verbose("		comparing with \"%s\"\n", peer->ip); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!strcmp(peer->ip, name)) { | 
					
						
							|  |  |  | 			if (port <= 0 || (port > 0 && peer->port == port)) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		if (peer) { | 
					
						
							|  |  |  | 			ast_verbose("		found matching friend\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_verbose("+++   find_friend \"%s\"\n", name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return peer;		 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ooh323_peer *find_peer(const char * name, int port) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *peer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   find_peer \"%s\"\n", name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 	for (peer = peerl.peers; peer; peer = peer->next) { | 
					
						
							|  |  |  | 		if (gH323Debug) { | 
					
						
							|  |  |  | 			ast_verbose("		comparing with \"%s\"\n", peer->ip); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!strcasecmp(peer->name, name)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if (peer->h323id && !strcasecmp(peer->h323id, name)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		if (peer->e164 && !strcasecmp(peer->e164, name)) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		/*
 | 
					
						
							|  |  |  | 		if (!strcmp(peer->ip, name)) { | 
					
						
							|  |  |  | 			if (port > 0 && peer->port == port) { break; } | 
					
						
							|  |  |  | 			else if (port <= 0) { break; } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		*/ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		if (peer) { | 
					
						
							|  |  |  | 			ast_verbose("		found matching peer\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_verbose("+++   find_peer \"%s\"\n", name); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return peer;		 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_digit_begin(struct ast_channel *chan, char digit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char dtmf[2]; | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt; | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	int res = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_digit_begin\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No private structure for call\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (digit == 'e' && !p->faxmode && p->t38support != T38_DISABLED)  { | 
					
						
							|  |  |  | 		if (!p->chmodepend) { | 
					
						
							|  |  |  | 			if (gH323Debug) | 
					
						
							|  |  |  | 				ast_verbose("request to change %s to t.38 because fax cng\n", | 
					
						
							|  |  |  | 						p->callToken); | 
					
						
							|  |  |  | 			p->chmodepend = 1; | 
					
						
							|  |  |  | 			ooRequestChangeMode(p->callToken, 1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO))) { | 
					
						
							|  |  |  | 		ast_rtp_instance_dtmf_begin(p->rtp, digit); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} else if (((p->dtmfmode & H323_DTMF_Q931) || | 
					
						
							|  |  |  | 						 (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) || | 
					
						
							|  |  |  | 						 (p->dtmfmode & H323_DTMF_H245SIGNAL))) { | 
					
						
							|  |  |  | 		dtmf[0] = digit; | 
					
						
							|  |  |  | 		dtmf[1] = '\0'; | 
					
						
							|  |  |  | 		ooSendDTMFDigit(p->callToken, dtmf); | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	} else if (p->dtmfmode & H323_DTMF_INBAND) { | 
					
						
							|  |  |  | 		res = -1; // tell Asterisk to generate inband indications
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_digit_begin %d\n", res); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_digit_end(struct ast_channel *chan, char digit, unsigned int duration) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt; | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	int res = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_digit_end\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No private structure for call\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	if (p->rtp && ((p->dtmfmode & H323_DTMF_RFC2833) || (p->dtmfmode & H323_DTMF_CISCO)) ) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_rtp_instance_dtmf_end(p->rtp, digit); | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	} else if(p->dtmfmode & H323_DTMF_INBAND) { | 
					
						
							|  |  |  | 		res = -1; // tell Asterisk to stop inband indications
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_digit_end, res = %d\n", res); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-26 20:14:50 +00:00
										 |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_call(struct ast_channel *ast, char *dest, int timeout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = ast->tech_pvt; | 
					
						
							|  |  |  | 	char destination[256]; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	int res=0, i; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	const char *val = NULL; | 
					
						
							|  |  |  | 	ooCallOptions opts = { | 
					
						
							|  |  |  | 		.fastStart = TRUE, | 
					
						
							|  |  |  | 		.tunneling = TRUE, | 
					
						
							|  |  |  | 		.disableGk = TRUE, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		.callMode = OO_CALLMODE_AUDIOCALL, | 
					
						
							|  |  |  |       		.transfercap = 0 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_call- %s\n", dest); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  |    	if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor " | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 								"reserved\n", ast->name); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	ast_set_flag(p, H323_OUTGOING); | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 	if (ast->connected.id.number.valid && ast->connected.id.number.str) { | 
					
						
							|  |  |  | 		free(p->callerid_num); | 
					
						
							|  |  |  | 		p->callerid_num = strdup(ast->connected.id.number.str); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 	if (ast->connected.id.name.valid && ast->connected.id.name.str) { | 
					
						
							|  |  |  | 		free(p->callerid_name); | 
					
						
							|  |  |  | 		p->callerid_name = strdup(ast->connected.id.name.str); | 
					
						
							|  |  |  | 	} else if (ast->connected.id.number.valid && ast->connected.id.number.str) { | 
					
						
							|  |  |  | 		free(p->callerid_name); | 
					
						
							|  |  |  | 		p->callerid_name = strdup(ast->connected.id.number.str); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		ast->connected.id.name.valid = 1; | 
					
						
							|  |  |  | 		free(ast->connected.id.name.str); | 
					
						
							|  |  |  | 		ast->connected.id.name.str = strdup(gCallerID); | 
					
						
							|  |  |  | 		free(p->callerid_name); | 
					
						
							|  |  |  | 		p->callerid_name = strdup(ast->connected.id.name.str); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Retrieve vars */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID"))) { | 
					
						
							|  |  |  | 		ast_copy_string(p->caller_h323id, val, sizeof(p->caller_h323id)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS"))) { | 
					
						
							|  |  |  | 		ast_copy_string(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		if(!p->callerid_num) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			p->callerid_num = strdup(val); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL"))) { | 
					
						
							|  |  |  | 		ast_copy_string(p->caller_email, val, sizeof(p->caller_email)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL"))) { | 
					
						
							|  |  |  | 		ast_copy_string(p->caller_url, val, sizeof(p->caller_url)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->host && p->port != 0) | 
					
						
							|  |  |  | 		snprintf(destination, sizeof(destination), "%s:%d", p->host, p->port); | 
					
						
							|  |  |  | 	else if (p->host) | 
					
						
							|  |  |  | 		snprintf(destination, sizeof(destination), "%s", p->host); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ast_copy_string(destination, dest, sizeof(destination)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 	destination[sizeof(destination)-1]='\0'; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 	opts.transfercap = ast->transfercapability; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 	opts.fastStart = p->faststart; | 
					
						
							|  |  |  | 	opts.tunneling = p->h245tunneling; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 	for (i=0;i<480 && !isRunning(p->callToken);i++) usleep(12000); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-27 23:51:13 +00:00
										 |  |  | 	if(OO_TESTFLAG(p->flags, H323_DISABLEGK)) { | 
					
						
							|  |  |  | 		res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, &opts); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		res = ooRunCall(destination, p->callToken, AST_MAX_EXTENSION, NULL); | 
					
						
							|  |  |  |  	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	if (res != OO_OK) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Failed to make call\n"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		return -1; /* ToDO: cleanup */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_call\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_hangup(struct ast_channel *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = ast->tech_pvt; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	int q931cause = AST_CAUSE_NORMAL_CLEARING; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_hangup\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |         if (ast->hangupcause) { | 
					
						
							|  |  |  |                 q931cause = ast->hangupcause; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |                 const char *cause = pbx_builtin_getvar_helper(ast, "DIALSTATUS"); | 
					
						
							|  |  |  |                 if (cause) { | 
					
						
							|  |  |  |                         if (!strcmp(cause, "CONGESTION")) { | 
					
						
							|  |  |  |                                 q931cause = AST_CAUSE_NORMAL_CIRCUIT_CONGESTION; | 
					
						
							|  |  |  |                         } else if (!strcmp(cause, "BUSY")) { | 
					
						
							|  |  |  |                                 q931cause = AST_CAUSE_USER_BUSY; | 
					
						
							|  |  |  |                         } else if (!strcmp(cause, "CHANISUNVAIL")) { | 
					
						
							|  |  |  |                                 q931cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL; | 
					
						
							|  |  |  |                         } else if (!strcmp(cause, "NOANSWER")) { | 
					
						
							|  |  |  |                                 q931cause = AST_CAUSE_NO_ANSWER; | 
					
						
							|  |  |  |                         } else if (!strcmp(cause, "CANCEL")) { | 
					
						
							|  |  |  |                                 q931cause = AST_CAUSE_CALL_REJECTED; | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		if (gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_verbose("    hanging %s with cause: %d\n", p->username, q931cause); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast->tech_pvt = NULL;  | 
					
						
							|  |  |  | 		if (!ast_test_flag(p, H323_ALREADYGONE)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		ooHangCall(p->callToken,  | 
					
						
							|  |  |  | 				ooh323_convert_hangupcause_asteriskToH323(q931cause), q931cause); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_set_flag(p, H323_ALREADYGONE); | 
					
						
							|  |  |  | 			/* ast_mutex_unlock(&p->lock); */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		} else  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_set_flag(p, H323_NEEDDESTROY); | 
					
						
							|  |  |  | 		/* detach channel here */ | 
					
						
							|  |  |  | 		if (p->owner) { | 
					
						
							|  |  |  | 			p->owner->tech_pvt = NULL; | 
					
						
							|  |  |  | 			p->owner = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_module_unref(myself); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_mutex_lock(&usecnt_lock); | 
					
						
							|  |  |  | 		usecnt--; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&usecnt_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Notify the module monitors that use count for resource has changed */ | 
					
						
							|  |  |  | 		ast_update_use_count(); | 
					
						
							|  |  |  | 	   | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | 		ast_debug(1, "No call to hangup\n" ); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_hangup\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_answer(struct ast_channel *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = ast->tech_pvt; | 
					
						
							| 
									
										
										
										
											2011-06-01 10:40:19 +00:00
										 |  |  | 	char *callToken = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("--- ooh323_answer\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (p) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2011-06-01 10:40:19 +00:00
										 |  |  | 		callToken = (p->callToken ? strdup(p->callToken) : NULL); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (ast->_state != AST_STATE_UP) { | 
					
						
							|  |  |  | 			ast_channel_lock(ast); | 
					
						
							| 
									
										
										
										
											2011-06-01 10:40:19 +00:00
										 |  |  | 			if (!p->alertsent) { | 
					
						
							|  |  |  | 	    			if (gH323Debug) { | 
					
						
							|  |  |  | 					ast_debug(1, "Sending forced ringback for %s, res = %d\n",  | 
					
						
							|  |  |  | 						callToken, ooManualRingback(callToken)); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 	    				ooManualRingback(callToken); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				p->alertsent = 1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_setstate(ast, AST_STATE_UP); | 
					
						
							|  |  |  |       			if (option_debug) | 
					
						
							|  |  |  | 				ast_debug(1, "ooh323_answer(%s)\n", ast->name); | 
					
						
							|  |  |  | 			ast_channel_unlock(ast); | 
					
						
							|  |  |  | 			ooAnswerCall(p->callToken); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-08-09 16:13:09 +00:00
										 |  |  | 		if (callToken) { | 
					
						
							|  |  |  | 			free(callToken); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++ ooh323_answer\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_frame *ooh323_read(struct ast_channel *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ast_frame *fr; | 
					
						
							|  |  |  | 	static struct ast_frame null_frame = { AST_FRAME_NULL, }; | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = ast->tech_pvt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (!p) return &null_frame; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->rtp) | 
					
						
							|  |  |  | 		fr = ooh323_rtp_read(ast, p); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		fr = &null_frame; | 
					
						
							|  |  |  | 	/* time(&p->lastrtprx); */ | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	return fr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_write(struct ast_channel *ast, struct ast_frame *f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = ast->tech_pvt; | 
					
						
							|  |  |  | 	int res = 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 	char buf[256]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (p) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (f->frametype == AST_FRAME_MODEM) { | 
					
						
							|  |  |  | 			ast_debug(1, "Send UDPTL %d/%d len %d for %s\n", | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 				f->frametype, f->subclass.integer, f->datalen, ast->name); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			if (p->udptl) | 
					
						
							|  |  |  | 				res = ast_udptl_write(p->udptl, f); | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			return res; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		if (f->frametype == AST_FRAME_VOICE) { | 
					
						
							|  |  |  | /* sending progress for first */ | 
					
						
							|  |  |  | 			if (!ast_test_flag(p, H323_OUTGOING) && !p->progsent && | 
					
						
							|  |  |  | 			 		p->callToken) { | 
					
						
							|  |  |  | 				ooManualProgress(p->callToken); | 
					
						
							|  |  |  | 				p->progsent = 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 			if (!(f->subclass.codec & ast->nativeformats)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				if (ast->nativeformats != 0) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 					ast_log(LOG_WARNING, | 
					
						
							|  |  |  | 							"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n", | 
					
						
							|  |  |  | 							ast_getformatname(f->subclass.codec), | 
					
						
							|  |  |  | 							ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats), | 
					
						
							|  |  |  | 							ast_getformatname(ast->readformat), | 
					
						
							|  |  |  | 							ast_getformatname(ast->writeformat)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					ast_set_write_format(ast, f->subclass.codec); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					/* ast_set_write_format(ast, f->subclass);
 | 
					
						
							|  |  |  | 					ast->nativeformats = f->subclass; */ | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p->rtp) | 
					
						
							|  |  |  | 			res = ast_rtp_instance_write(p->rtp, f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else if (f->frametype == AST_FRAME_IMAGE) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Can't send %d type frames with OOH323 write\n",  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 									 f->frametype); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt; | 
					
						
							|  |  |  | 	char *callToken = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2011-03-27 21:47:13 +00:00
										 |  |  | 	int res = -1; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (!p) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	callToken = (p->callToken ? strdup(p->callToken) : NULL); | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!callToken) { | 
					
						
							|  |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 			ast_verbose("	ooh323_indicate - No callToken\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken); | 
					
						
							|  |  |  | 	  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	switch (condition) { | 
					
						
							| 
									
										
										
										
											2011-09-09 16:09:09 +00:00
										 |  |  | 	case AST_CONTROL_INCOMPLETE: | 
					
						
							|  |  |  | 		/* While h323 does support overlapped dialing, this channel driver does not
 | 
					
						
							|  |  |  | 		 * at this time.  Treat a response of Incomplete as if it were congestion. | 
					
						
							|  |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	case AST_CONTROL_CONGESTION: | 
					
						
							|  |  |  | 		if (!ast_test_flag(p, H323_ALREADYGONE)) { | 
					
						
							| 
									
										
										
										
											2011-09-09 16:09:09 +00:00
										 |  |  | 			ooHangCall(callToken, OO_REASON_LOCAL_CONGESTED, AST_CAUSE_SWITCH_CONGESTION); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_set_flag(p, H323_ALREADYGONE); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AST_CONTROL_BUSY: | 
					
						
							|  |  |  | 		if (!ast_test_flag(p, H323_ALREADYGONE)) { | 
					
						
							| 
									
										
										
										
											2011-09-09 16:09:09 +00:00
										 |  |  | 			ooHangCall(callToken, OO_REASON_LOCAL_BUSY, AST_CAUSE_USER_BUSY); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_set_flag(p, H323_ALREADYGONE); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AST_CONTROL_HOLD: | 
					
						
							| 
									
										
										
										
											2011-09-09 16:09:09 +00:00
										 |  |  | 		ast_moh_start(ast, data, NULL); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case AST_CONTROL_UNHOLD: | 
					
						
							|  |  |  | 		ast_moh_stop(ast); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case AST_CONTROL_PROGRESS: | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (ast->_state != AST_STATE_UP) { | 
					
						
							|  |  |  | 	    		if (!p->progsent) { | 
					
						
							|  |  |  | 	     			if (gH323Debug)  | 
					
						
							|  |  |  | 					ast_log(LOG_DEBUG,"Sending manual progress for %s, res = %d\n", callToken, | 
					
						
							|  |  |  |              				ooManualProgress(callToken));	 | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 	     				ooManualProgress(callToken); | 
					
						
							|  |  |  | 	     			p->progsent = 1; | 
					
						
							|  |  |  | 	    		} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  |       case AST_CONTROL_RINGING: | 
					
						
							|  |  |  | 	    if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING) { | 
					
						
							| 
									
										
										
										
											2011-02-10 18:50:50 +00:00
										 |  |  | 		if (!p->alertsent) { | 
					
						
							|  |  |  | 	    		if (gH323Debug) { | 
					
						
							|  |  |  | 				ast_debug(1, "Sending manual ringback for %s, res = %d\n",  | 
					
						
							|  |  |  | 					callToken, | 
					
						
							|  |  |  |             				ooManualRingback(callToken)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 	    				ooManualRingback(callToken); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-06-01 10:40:19 +00:00
										 |  |  | 			p->alertsent = 1; | 
					
						
							| 
									
										
										
										
											2011-02-10 18:50:50 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	    } | 
					
						
							|  |  |  | 	 break; | 
					
						
							| 
									
										
										
										
											2010-03-12 22:04:51 +00:00
										 |  |  | 	case AST_CONTROL_SRCUPDATE: | 
					
						
							| 
									
										
										
										
											2011-04-09 20:56:17 +00:00
										 |  |  | 		if (p->rtp) { | 
					
						
							|  |  |  | 			ast_rtp_instance_update_source(p->rtp); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-03-12 22:04:51 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case AST_CONTROL_SRCCHANGE: | 
					
						
							| 
									
										
										
										
											2011-04-09 20:56:17 +00:00
										 |  |  | 		if (p->rtp) { | 
					
						
							|  |  |  | 			ast_rtp_instance_change_source(p->rtp); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 	case AST_CONTROL_CONNECTED_LINE: | 
					
						
							|  |  |  | 		if (!ast->connected.id.name.valid | 
					
						
							|  |  |  | 			|| ast_strlen_zero(ast->connected.id.name.str)) { | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-05-23 18:23:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 			ast_log(LOG_DEBUG, "Sending connected line info for %s (%s)\n", | 
					
						
							|  |  |  | 				callToken, ast->connected.id.name.str); | 
					
						
							|  |  |  | 		ooSetANI(callToken, ast->connected.id.name.str); | 
					
						
							| 
									
										
										
										
											2010-01-24 22:42:11 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       case AST_CONTROL_T38_PARAMETERS: | 
					
						
							|  |  |  | 		if (p->t38support != T38_ENABLED) { | 
					
						
							|  |  |  | 			struct ast_control_t38_parameters parameters = { .request_response = 0 }; | 
					
						
							|  |  |  | 			parameters.request_response = AST_T38_REFUSED; | 
					
						
							|  |  |  | 			ast_queue_control_data(ast, AST_CONTROL_T38_PARAMETERS, | 
					
						
							|  |  |  | 						 ¶meters, sizeof(parameters)); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (datalen != sizeof(struct ast_control_t38_parameters)) { | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38. " | 
					
						
							|  |  |  | 					   "Expected %d, got %d\n", | 
					
						
							|  |  |  | 				(int)sizeof(enum ast_control_t38), (int)datalen); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			const struct ast_control_t38_parameters *parameters = data; | 
					
						
							|  |  |  | 			enum ast_control_t38 message = parameters->request_response; | 
					
						
							|  |  |  | 			switch (message) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case AST_T38_REQUEST_NEGOTIATE: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!p->chmodepend && !p->faxmode) { | 
					
						
							|  |  |  | 					ooRequestChangeMode(p->callToken, 1); | 
					
						
							|  |  |  | 					p->chmodepend = 1; | 
					
						
							| 
									
										
										
										
											2011-03-27 21:47:13 +00:00
										 |  |  | 					res = 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case AST_T38_REQUEST_TERMINATE: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!p->chmodepend && p->faxmode) { | 
					
						
							|  |  |  | 					ooRequestChangeMode(p->callToken, 0); | 
					
						
							|  |  |  | 					p->chmodepend = 1; | 
					
						
							| 
									
										
										
										
											2011-03-27 21:47:13 +00:00
										 |  |  | 					res = 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  |       case AST_CONTROL_PROCEEDING: | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	case -1: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Don't know how to indicate condition %d on %s\n", | 
					
						
							|  |  |  | 									condition, callToken); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("++++  ooh323_indicate %d on %s\n", condition, callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	free(callToken); | 
					
						
							| 
									
										
										
										
											2011-03-27 21:47:13 +00:00
										 |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int ooh323_queryoption(struct ast_channel *ast, int option, void *data, int *datalen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt; | 
					
						
							|  |  |  | 	int res = -1; | 
					
						
							|  |  |  | 	enum ast_t38_state state = T38_STATE_UNAVAILABLE; | 
					
						
							|  |  |  | 	char* cp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("----- ooh323_queryoption %d on channel %s\n", option, ast->name); | 
					
						
							|  |  |  | 	  | 
					
						
							|  |  |  | 	switch (option) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case AST_OPTION_T38_STATE: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (*datalen != sizeof(enum ast_t38_state)) { | 
					
						
							|  |  |  |                         	ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option." | 
					
						
							|  |  |  | 				" Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (p->t38support != T38_DISABLED) | 
					
						
							|  |  |  | 				state = T38_STATE_UNKNOWN; | 
					
						
							|  |  |  | 			if (p->faxmode) | 
					
						
							|  |  |  | 				state = (p->chmodepend) ? T38_STATE_UNKNOWN : T38_STATE_NEGOTIATED; | 
					
						
							|  |  |  | 			else if (p->chmodepend) | 
					
						
							|  |  |  | 				state = T38_STATE_NEGOTIATING; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			*((enum ast_t38_state *) data) = state; | 
					
						
							|  |  |  | 			res = 0; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case AST_OPTION_DIGIT_DETECT: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			cp = (char *) data; | 
					
						
							|  |  |  | 			*cp = p->vad ? 1 : 0; | 
					
						
							|  |  |  | 			ast_debug(1, "Reporting digit detection %sabled on %s\n", | 
					
						
							|  |  |  | 							 *cp ? "en" : "dis", ast->name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			res = 0; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default:	; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++++ ooh323_queryoption %d on channel %s\n", option, ast->name); | 
					
						
							|  |  |  | 	  | 
					
						
							|  |  |  |    	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = newchan->tech_pvt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | 	if (!p) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("--- ooh323c ooh323_fixup\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->owner != oldchan) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Old channel wasn't %p but was %p\n", oldchan, p->owner); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->owner == oldchan) { | 
					
						
							|  |  |  | 		p->owner = newchan; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		p->owner = oldchan; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++ ooh323c ooh323_fixup \n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | void ooh323_set_write_format(ooCallData *call, int fmt, int txframes) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	char formats[FORMAT_STRING_SIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_update_writeformat %s/%d\n",  | 
					
						
							|  |  |  | 				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt), txframes); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p->writeformat = fmt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->owner) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 	  		ast_verbose("Writeformat before update %s/%s\n",  | 
					
						
							|  |  |  | 			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->writeformat), | 
					
						
							|  |  |  | 			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->nativeformats)); | 
					
						
							|  |  |  | 		if (txframes) | 
					
						
							|  |  |  | 			ast_codec_pref_setsize(&p->prefs, fmt, txframes); | 
					
						
							|  |  |  | 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); | 
					
						
							|  |  |  | 		if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) { | 
					
						
							|  |  |  | 			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), | 
					
						
							|  |  |  | 				 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) { | 
					
						
							|  |  |  | 			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), | 
					
						
							|  |  |  | 				 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		p->owner->nativeformats = fmt; | 
					
						
							|  |  |  | 	  	ast_set_write_format(p->owner, p->owner->writeformat); | 
					
						
							|  |  |  | 	  	ast_set_read_format(p->owner, p->owner->readformat); | 
					
						
							|  |  |  | 		ast_channel_unlock(p->owner); | 
					
						
							|  |  |  |    	} else | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No owner found\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_update_writeformat\n"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void ooh323_set_read_format(ooCallData *call, int fmt) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	char formats[FORMAT_STRING_SIZE]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_update_readformat %s\n",  | 
					
						
							|  |  |  | 				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt)); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	p->readformat = fmt; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->owner) { | 
					
						
							|  |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 	  		ast_verbose("Readformat before update %s\n",  | 
					
						
							|  |  |  | 				  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->readformat)); | 
					
						
							|  |  |  | 		p->owner->nativeformats = fmt; | 
					
						
							|  |  |  | 	  	ast_set_read_format(p->owner, p->owner->readformat); | 
					
						
							|  |  |  | 		ast_channel_unlock(p->owner); | 
					
						
							|  |  |  |    	} else | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No owner found\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_update_readformat\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | int onAlerting(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct ast_channel *c = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("--- onAlerting %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	p = find_call(call); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	if(!p) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "No matching call found\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	}   | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (!p->owner) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 		ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 		DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!p->owner) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	c = p->owner; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (call->remoteDisplayName) { | 
					
						
							|  |  |  | 		struct ast_party_connected_line connected; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		struct ast_set_party_connected_line update_connected; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memset(&update_connected, 0, sizeof(update_connected)); | 
					
						
							|  |  |  | 		update_connected.id.name = 1; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 		ast_party_connected_line_init(&connected); | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		connected.id.name.valid = 1; | 
					
						
							|  |  |  | 		connected.id.name.str = (char *) call->remoteDisplayName; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 		connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		ast_channel_queue_connected_line_update(c, &connected, &update_connected); | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (c->_state != AST_STATE_UP) | 
					
						
							|  |  |  | 		ast_setstate(c, AST_STATE_RINGING); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_queue_control(c, AST_CONTROL_RINGING); | 
					
						
							|  |  |  |       	ast_channel_unlock(c); | 
					
						
							|  |  |  |       	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++ onAlerting %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | int onProgress(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct ast_channel *c = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("--- onProgress %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	p = find_call(call); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	if(!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No matching call found\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	}   | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (!p->owner) { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 		ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 		DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!p->owner) { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	c = p->owner; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (call->remoteDisplayName) { | 
					
						
							|  |  |  | 		struct ast_party_connected_line connected; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		struct ast_set_party_connected_line update_connected; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		memset(&update_connected, 0, sizeof(update_connected)); | 
					
						
							|  |  |  | 		update_connected.id.name = 1; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 		ast_party_connected_line_init(&connected); | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		connected.id.name.valid = 1; | 
					
						
							|  |  |  | 		connected.id.name.str = (char *) call->remoteDisplayName; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 		connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 		ast_channel_queue_connected_line_update(c, &connected, &update_connected); | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (c->_state != AST_STATE_UP) | 
					
						
							|  |  |  | 		ast_setstate(c, AST_STATE_RINGING); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_queue_control(c, AST_CONTROL_PROGRESS); | 
					
						
							|  |  |  |       	ast_channel_unlock(c); | 
					
						
							|  |  |  |       	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++ onProgress %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   * Callback for sending digits from H.323 up to asterisk | 
					
						
							|  |  |  |   * | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | int ooh323_onReceivedDigit(OOH323CallData *call, const char *digit) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct ast_frame f; | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_debug(1, "Received Digit: %c\n", digit[0]); | 
					
						
							|  |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Failed to find a matching call.\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!p->owner) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	memset(&f, 0, sizeof(f)); | 
					
						
							|  |  |  | 	f.frametype = AST_FRAME_DTMF; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 	f.subclass.integer = digit[0]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	f.datalen = 0; | 
					
						
							|  |  |  | 	f.samples = 800; | 
					
						
							|  |  |  | 	f.offset = 0; | 
					
						
							|  |  |  | 	f.data.ptr = NULL; | 
					
						
							|  |  |  | 	f.mallocd = 0; | 
					
						
							|  |  |  | 	f.src = "SEND_DIGIT"; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 		ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 		DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!p->owner) { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	res = ast_queue_frame(p->owner, &f); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	ast_channel_unlock(p->owner); | 
					
						
							|  |  |  |    	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct ooh323_user *user = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	struct ast_channel *c = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ooAliases *alias = NULL; | 
					
						
							|  |  |  | 	char *at = NULL; | 
					
						
							|  |  |  | 	char number [OO_MAX_NUMBER_LENGTH]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_onReceivedSetup %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(p = ooh323_alloc(call->callReference, call->callToken))) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Failed to create a new call.\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	ast_clear_flag(p, H323_OUTGOING); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (call->remoteDisplayName) { | 
					
						
							|  |  |  | 		p->callerid_name = strdup(call->remoteDisplayName); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ooCallGetCallingPartyNumber(call, number, OO_MAX_NUMBER_LENGTH) == OO_OK) { | 
					
						
							|  |  |  | 		p->callerid_num = strdup(number); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (call->remoteAliases) { | 
					
						
							|  |  |  | 		for (alias = call->remoteAliases; alias; alias = alias->next) { | 
					
						
							|  |  |  | 			if (alias->type == T_H225AliasAddress_h323_ID) { | 
					
						
							|  |  |  | 				if (!p->callerid_name) { | 
					
						
							|  |  |  | 					p->callerid_name = strdup(alias->value); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ast_copy_string(p->caller_h323id, alias->value, sizeof(p->caller_h323id)); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          else if(alias->type == T_H225AliasAddress_dialedDigits) | 
					
						
							|  |  |  |          { | 
					
						
							|  |  |  |             if(!p->callerid_num) | 
					
						
							|  |  |  |                p->callerid_num = strdup(alias->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_copy_string(p->caller_dialedDigits, alias->value,  | 
					
						
							|  |  |  | 															sizeof(p->caller_dialedDigits)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          } | 
					
						
							|  |  |  |          else if(alias->type == T_H225AliasAddress_email_ID) | 
					
						
							|  |  |  |          { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_copy_string(p->caller_email, alias->value, sizeof(p->caller_email)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          } | 
					
						
							|  |  |  |          else if(alias->type == T_H225AliasAddress_url_ID) | 
					
						
							|  |  |  |          { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_copy_string(p->caller_url, alias->value, sizeof(p->caller_url)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	number[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	if(ooCallGetCalledPartyNumber(call, number, OO_MAX_NUMBER_LENGTH)== OO_OK) { | 
					
						
							|  |  |  |       		strncpy(p->exten, number, sizeof(p->exten)-1); | 
					
						
							|  |  |  |    	} else { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		update_our_aliases(call, p); | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->callee_dialedDigits)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		ast_copy_string(p->exten, p->callee_dialedDigits, sizeof(p->exten)); | 
					
						
							|  |  |  |       		} else if(!ast_strlen_zero(p->callee_h323id)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_copy_string(p->exten, p->callee_h323id, sizeof(p->exten)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		} else if(!ast_strlen_zero(p->callee_email)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_copy_string(p->exten, p->callee_email, sizeof(p->exten)); | 
					
						
							|  |  |  | 			if ((at = strchr(p->exten, '@'))) { | 
					
						
							|  |  |  | 				*at = '\0'; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if no extension found, set to default 's' */ | 
					
						
							|  |  |  | 	if (ast_strlen_zero(p->exten)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		p->exten[0]='s'; | 
					
						
							|  |  |  |       		p->exten[1]='\0'; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       	user = find_user(p->callerid_name, call->remoteIP); | 
					
						
							|  |  |  |       	if(user && (user->incominglimit == 0 || user->inUse < user->incominglimit)) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&user->lock); | 
					
						
							|  |  |  | 		p->username = strdup(user->name); | 
					
						
							|  |  |  |  		p->neighbor.user = user->mUseIP ? ast_strdup(user->mIP) : | 
					
						
							|  |  |  | 						  ast_strdup(user->name); | 
					
						
							|  |  |  | 		ast_copy_string(p->context, user->context, sizeof(p->context)); | 
					
						
							|  |  |  | 		ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode)); | 
					
						
							|  |  |  | 		p->amaflags = user->amaflags; | 
					
						
							|  |  |  | 		p->capability = user->capability; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		p->g729onlyA = user->g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref)); | 
					
						
							|  |  |  | 		p->dtmfmode |= user->dtmfmode; | 
					
						
							|  |  |  | 		p->dtmfcodec = user->dtmfcodec; | 
					
						
							|  |  |  | 		p->t38support = user->t38support; | 
					
						
							|  |  |  | 		p->rtptimeout = user->rtptimeout; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 		p->h245tunneling = user->h245tunneling; | 
					
						
							|  |  |  | 		p->faststart = user->faststart; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p->faststart) | 
					
						
							|  |  |  |          		OO_SETFLAG(call->flags, OO_M_FASTSTART); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			OO_CLRFLAG(call->flags, OO_M_FASTSTART); | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		/* if we disable h245tun for this user then we clear flag */ | 
					
						
							|  |  |  | 		/* in any other case we don't must touch this */ | 
					
						
							|  |  |  | 		/* ie if we receive setup without h245tun but enabled
 | 
					
						
							|  |  |  | 		   				we can't enable it per call */ | 
					
						
							|  |  |  | 		if (!p->h245tunneling) | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 			OO_CLRFLAG(call->flags, OO_M_TUNNELING); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (user->rtpmask && user->rtpmaskstr[0]) { | 
					
						
							|  |  |  | 			p->rtpmask = user->rtpmask; | 
					
						
							|  |  |  | 			ast_copy_string(p->rtpmaskstr, user->rtpmaskstr,  | 
					
						
							|  |  |  | 							 sizeof(p->rtpmaskstr)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 		if (user->rtdrcount > 0 && user->rtdrinterval > 0) { | 
					
						
							|  |  |  | 			p->rtdrcount = user->rtdrcount; | 
					
						
							|  |  |  | 			p->rtdrinterval = user->rtdrinterval; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	 	if (user->incominglimit) user->inUse++; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&user->lock); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	 if (!OO_TESTFLAG(p->flags,H323_DISABLEGK)) { | 
					
						
							|  |  |  | 		p->username = strdup(call->remoteIP); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 	  ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	  ast_log(LOG_ERROR, "Unacceptable ip %s\n", call->remoteIP); | 
					
						
							|  |  |  | 	  if (!user)  | 
					
						
							|  |  |  | 	   ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_CALL_REJECTED), AST_CAUSE_CALL_REJECTED); | 
					
						
							|  |  |  | 	  else | 
					
						
							|  |  |  | 	   ooHangCall(call->callToken, ooh323_convert_hangupcause_asteriskToH323(AST_CAUSE_NORMAL_CIRCUIT_CONGESTION), AST_CAUSE_NORMAL_CIRCUIT_CONGESTION); | 
					
						
							|  |  |  | 	  ast_set_flag(p, H323_NEEDDESTROY); | 
					
						
							|  |  |  | 	  return -1; | 
					
						
							|  |  |  | 	 } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->dtmfcodec, | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 					 p->t38support, p->g729onlyA); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	configure_local_rtp(p, call); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | /* Incoming call */ | 
					
						
							|  |  |  |   	c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL); | 
					
						
							|  |  |  |   	if(!c) { | 
					
						
							|  |  |  |    	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  |    	ast_log(LOG_ERROR, "Could not create ast_channel\n"); | 
					
						
							|  |  |  |          return -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_onReceivedSetup - Determined context %s, " | 
					
						
							|  |  |  | 						"extension %s\n", p->context, p->exten); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | int onOutgoingCall(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	int i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   onOutgoingCall %lx: %s\n", (long unsigned int) call, call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!strcmp(call->callType, "outgoing")) { | 
					
						
							|  |  |  | 		p = find_call(call); | 
					
						
							|  |  |  | 		if (!p) { | 
					
						
							|  |  |  |       			ast_log(LOG_ERROR, "Failed to find a matching call.\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->callerid_name)) { | 
					
						
							|  |  |  | 			ooCallSetCallerId(call, p->callerid_name); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->callerid_num)) { | 
					
						
							|  |  |  | 			i = 0; | 
					
						
							|  |  |  | 			while (*(p->callerid_num + i) != '\0') { | 
					
						
							|  |  |  |             			if(!isdigit(*(p->callerid_num+i))) { break; } | 
					
						
							|  |  |  | 				i++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  |          		if(*(p->callerid_num+i) == '\0') | 
					
						
							|  |  |  | 				ooCallSetCallingPartyNumber(call, p->callerid_num); | 
					
						
							|  |  |  |          		else { | 
					
						
							|  |  |  |             			if(!p->callerid_name) | 
					
						
							|  |  |  | 					ooCallSetCallerId(call, p->callerid_num); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->caller_h323id)) | 
					
						
							|  |  |  | 			ooCallAddAliasH323ID(call, p->caller_h323id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->caller_dialedDigits)) { | 
					
						
							|  |  |  | 			if (gH323Debug) { | 
					
						
							|  |  |  | 				ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ooCallAddAliasDialedDigits(call, p->caller_dialedDigits); | 
					
						
							|  |  |  | 		} else if (!ast_strlen_zero(p->callerid_num)) { | 
					
						
							|  |  |  | 			if (ooIsDailedDigit(p->callerid_num)) { | 
					
						
							|  |  |  | 				if (gH323Debug) { | 
					
						
							|  |  |  | 					ast_verbose("setting callid number %s\n", p->callerid_num); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ooCallAddAliasDialedDigits(call, p->callerid_num); | 
					
						
							|  |  |  | 			} else if (ast_strlen_zero(p->caller_h323id)) { | 
					
						
							|  |  |  | 				ooCallAddAliasH323ID(call, p->callerid_num); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (p->rtpmask && p->rtpmaskstr[0]) { | 
					
						
							|  |  |  | 			call->rtpMask = p->rtpmask; | 
					
						
							|  |  |  | 			ast_mutex_lock(&call->rtpMask->lock); | 
					
						
							|  |  |  | 			call->rtpMask->inuse++; | 
					
						
							|  |  |  | 			ast_mutex_unlock(&call->rtpMask->lock); | 
					
						
							|  |  |  | 			ast_copy_string(call->rtpMaskStr, p->rtpmaskstr, sizeof(call->rtpMaskStr)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   onOutgoingCall %s\n", call->callToken); | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | int onNewCallCreated(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	int i = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_verbose("---   onNewCallCreated %lx: %s\n", (long unsigned int) call, call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	ast_mutex_lock(&call->Lock); | 
					
						
							|  |  |  |    	if (ooh323c_start_call_thread(call)) { | 
					
						
							|  |  |  |     		ast_log(LOG_ERROR,"Failed to create call thread.\n"); | 
					
						
							|  |  |  |     		ast_mutex_unlock(&call->Lock); | 
					
						
							|  |  |  |     		return -1; | 
					
						
							|  |  |  |    	} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!strcmp(call->callType, "outgoing")) { | 
					
						
							|  |  |  | 		p = find_call(call); | 
					
						
							|  |  |  | 		if (!p) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       			ast_log(LOG_ERROR, "Failed to find a matching call.\n"); | 
					
						
							|  |  |  | 			ast_mutex_unlock(&call->Lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-25 18:51:37 +00:00
										 |  |  | 		if (!ast_strlen_zero(p->callerid_name)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ooCallSetCallerId(call, p->callerid_name); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-25 18:51:37 +00:00
										 |  |  | 		if (!ast_strlen_zero(p->callerid_num)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			i = 0; | 
					
						
							|  |  |  | 			while (*(p->callerid_num + i) != '\0') { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			if(!isdigit(*(p->callerid_num+i))) { break; } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				i++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		if(*(p->callerid_num+i) == '\0') | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ooCallSetCallingPartyNumber(call, p->callerid_num); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		else { | 
					
						
							| 
									
										
										
										
											2010-04-25 18:51:37 +00:00
										 |  |  |             			if(ast_strlen_zero(p->callerid_name)) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					ooCallSetCallerId(call, p->callerid_num); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->caller_h323id)) | 
					
						
							|  |  |  | 			ooCallAddAliasH323ID(call, p->caller_h323id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->caller_dialedDigits)) { | 
					
						
							|  |  |  | 			if (gH323Debug) { | 
					
						
							|  |  |  | 				ast_verbose("Setting dialed digits %s\n", p->caller_dialedDigits); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ooCallAddAliasDialedDigits(call, p->caller_dialedDigits); | 
					
						
							| 
									
										
										
										
											2010-04-25 18:34:29 +00:00
										 |  |  | 		} else if (!ast_strlen_zero(p->callerid_num)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			if (ooIsDailedDigit(p->callerid_num)) { | 
					
						
							|  |  |  | 				if (gH323Debug) { | 
					
						
							|  |  |  | 					ast_verbose("setting callid number %s\n", p->callerid_num); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ooCallAddAliasDialedDigits(call, p->callerid_num); | 
					
						
							|  |  |  | 			} else if (ast_strlen_zero(p->caller_h323id)) { | 
					
						
							|  |  |  | 				ooCallAddAliasH323ID(call, p->callerid_num); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_strlen_zero(p->exten))  { | 
					
						
							|  |  |  | 			if (ooIsDailedDigit(p->exten)) { | 
					
						
							|  |  |  | 				ooCallSetCalledPartyNumber(call, p->exten); | 
					
						
							|  |  |  | 				ooCallAddRemoteAliasDialedDigits(call, p->exten); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 			  ooCallAddRemoteAliasH323ID(call, p->exten); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (gH323Debug) { | 
					
						
							|  |  |  | 			char prefsBuf[256]; | 
					
						
							|  |  |  | 			ast_codec_pref_string(&p->prefs, prefsBuf, sizeof(prefsBuf)); | 
					
						
							|  |  |  | 			ast_verbose(" Outgoing call %s(%s) - Codec prefs - %s\n",  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				p->username?p->username:"NULL", call->callToken, prefsBuf); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		ooh323c_set_capability_for_call(call, &p->prefs, p->capability,  | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  |                                      p->dtmfmode, p->dtmfcodec, p->t38support, p->g729onlyA); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		configure_local_rtp(p, call); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    	ast_mutex_unlock(&call->Lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   onNewCallCreated %s\n", call->callToken); | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int onCallEstablished(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   onCallEstablished %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (!(p = find_call(call))) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Failed to find a matching call.\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    	if(ast_test_flag(p, H323_OUTGOING)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (p->owner) { | 
					
						
							|  |  |  | 			struct ast_channel* c = p->owner; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (call->remoteDisplayName) { | 
					
						
							|  |  |  | 				struct ast_party_connected_line connected; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 				struct ast_set_party_connected_line update_connected; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				memset(&update_connected, 0, sizeof(update_connected)); | 
					
						
							|  |  |  | 				update_connected.id.name = 1; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 				ast_party_connected_line_init(&connected); | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 				connected.id.name.valid = 1; | 
					
						
							|  |  |  | 				connected.id.name.str = (char *) call->remoteDisplayName; | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 				connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; | 
					
						
							| 
									
										
										
										
											2010-07-14 15:48:36 +00:00
										 |  |  | 				ast_channel_queue_connected_line_update(c, &connected, &update_connected); | 
					
						
							| 
									
										
										
										
											2010-02-16 22:58:22 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_queue_control(c, AST_CONTROL_ANSWER); | 
					
						
							|  |  |  |    			ast_channel_unlock(p->owner); | 
					
						
							|  |  |  | 			manager_event(EVENT_FLAG_SYSTEM,"ChannelUpdate","Channel: %s\r\nChanneltype: %s\r\n" | 
					
						
							|  |  |  | 				"CallRef: %d\r\n", c->name, "OOH323", p->call_reference); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   onCallEstablished %s\n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int onCallCleared(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	int ownerLock = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   onCallCleared %s \n", call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    if ((p = find_call(call))) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 	while (p->owner) { | 
					
						
							|  |  |  | 		if (ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ooTrace(OOTRCLVLINFO, "Failed to grab lock, trying again\n"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		ast_log(LOG_DEBUG,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		ownerLock = 1; break; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ownerLock) { | 
					
						
							|  |  |  | 		if (!ast_test_flag(p, H323_ALREADYGONE)) {  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ast_set_flag(p, H323_ALREADYGONE); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			p->owner->hangupcause = call->q931cause; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			p->owner->_softhangup |= AST_SOFTHANGUP_DEV; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_queue_hangup_with_cause(p->owner,call->q931cause); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	if(p->owner) { | 
					
						
							|  |  |  |     		p->owner->tech_pvt = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_channel_unlock(p->owner); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |     		p->owner = NULL; | 
					
						
							|  |  |  | 		ast_module_unref(myself); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_set_flag(p, H323_NEEDDESTROY); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    	ooh323c_stop_call_thread(call); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	ast_mutex_lock(&usecnt_lock); | 
					
						
							|  |  |  |    	usecnt--; | 
					
						
							|  |  |  |    	ast_mutex_unlock(&usecnt_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   onCallCleared\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return OO_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | /* static void ooh323_delete_user(struct ooh323_user *user)
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *prev = NULL, *cur = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_delete_user\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (user) {	 | 
					
						
							|  |  |  | 		cur = userl.users; | 
					
						
							|  |  |  | 		ast_mutex_lock(&userl.lock); | 
					
						
							|  |  |  | 		while (cur) { | 
					
						
							|  |  |  | 			if (cur == user) break; | 
					
						
							|  |  |  | 			prev = cur; | 
					
						
							|  |  |  | 			cur = cur->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur) { | 
					
						
							|  |  |  | 			if (prev) | 
					
						
							|  |  |  | 				prev->next = cur->next; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				userl.users = cur->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		free(user); | 
					
						
							|  |  |  | 	}   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_delete_user\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | } */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void ooh323_delete_peer(struct ooh323_peer *peer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *prev = NULL, *cur = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_delete_peer\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (peer) {	 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       cur = peerl.peers; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_lock(&peerl.lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       while(cur) { | 
					
						
							|  |  |  |          if(cur==peer) break; | 
					
						
							|  |  |  |          prev = cur; | 
					
						
							|  |  |  |          cur = cur->next; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          if(prev) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				prev->next = cur->next; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          else | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				peerl.peers = cur->next; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       if(peer->h323id)   free(peer->h323id); | 
					
						
							|  |  |  |       if(peer->email)    free(peer->email); | 
					
						
							|  |  |  |       if(peer->url)      free(peer->url); | 
					
						
							|  |  |  |       if(peer->e164)     free(peer->e164); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		free(peer); | 
					
						
							|  |  |  | 	}   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_delete_peer\n"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ooh323_user *build_user(const char *name, struct ast_variable *v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *user = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   build_user\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	user = ast_calloc(1,sizeof(struct ooh323_user)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (user) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		memset(user, 0, sizeof(struct ooh323_user)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_init(&user->lock); | 
					
						
							|  |  |  | 		ast_copy_string(user->name, name, sizeof(user->name)); | 
					
						
							|  |  |  | 		user->capability = gCapability; | 
					
						
							|  |  |  | 		memcpy(&user->prefs, &gPrefs, sizeof(user->prefs)); | 
					
						
							|  |  |  | 		user->rtptimeout = gRTPTimeout; | 
					
						
							|  |  |  | 		user->dtmfmode = gDTMFMode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		user->dtmfcodec = gDTMFCodec; | 
					
						
							|  |  |  | 		user->t38support = gT38Support; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 		user->faststart = gFastStart; | 
					
						
							|  |  |  | 		user->h245tunneling = gTunneling; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		user->g729onlyA = g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* set default context */ | 
					
						
							|  |  |  | 		ast_copy_string(user->context, gContext, sizeof(user->context)); | 
					
						
							|  |  |  | 		ast_copy_string(user->accountcode, gAccountcode, sizeof(user->accountcode)); | 
					
						
							|  |  |  | 		user->amaflags = gAMAFLAGS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (v) { | 
					
						
							|  |  |  | 			if (!strcasecmp(v->name, "context")) { | 
					
						
							|  |  |  | 				ast_copy_string(user->context, v->value, sizeof(user->context)); | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "incominglimit")) { | 
					
						
							|  |  |  | 				user->incominglimit = atoi(v->value); | 
					
						
							|  |  |  | 				if (user->incominglimit < 0) | 
					
						
							|  |  |  | 					user->incominglimit = 0; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "accountcode")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			strncpy(user->accountcode, v->value,  | 
					
						
							|  |  |  | 						sizeof(user->accountcode)-1); | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "roundtrip")) { | 
					
						
							|  |  |  | 				sscanf(v->value, "%d,%d", &user->rtdrcount, &user->rtdrinterval); | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "faststart")) { | 
					
						
							|  |  |  | 				user->faststart = ast_true(v->value); | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "h245tunneling")) { | 
					
						
							|  |  |  | 				user->h245tunneling = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "g729onlyA")) { | 
					
						
							|  |  |  | 				user->g729onlyA = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "rtptimeout")) { | 
					
						
							|  |  |  | 				user->rtptimeout = atoi(v->value); | 
					
						
							|  |  |  | 				if (user->rtptimeout < 0) | 
					
						
							|  |  |  | 					user->rtptimeout = gRTPTimeout; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "rtpmask")) { | 
					
						
							|  |  |  | 				if ((user->rtpmask = malloc(sizeof(struct OOH323Regex))) && | 
					
						
							|  |  |  | 					(regcomp(&user->rtpmask->regex, v->value, REG_EXTENDED)  | 
					
						
							|  |  |  | 											== 0)) { | 
					
						
							|  |  |  | 					ast_mutex_init(&user->rtpmask->lock); | 
					
						
							|  |  |  | 					user->rtpmask->inuse = 1; | 
					
						
							|  |  |  | 					ast_copy_string(user->rtpmaskstr, v->value,  | 
					
						
							|  |  |  | 								sizeof(user->rtpmaskstr)); | 
					
						
							|  |  |  | 				} else user->rtpmask = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "disallow")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				ast_parse_allow_disallow(&user->prefs,  | 
					
						
							|  |  |  | 					&user->capability,  v->value, 0); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "allow")) { | 
					
						
							|  |  |  | 				const char* tcodecs = v->value; | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "all")) { | 
					
						
							|  |  |  | 					tcodecs = "ulaw,alaw,g729,g723,gsm"; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				ast_parse_allow_disallow(&user->prefs, | 
					
						
							|  |  |  | 					 &user->capability,  tcodecs, 1); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "amaflags")) { | 
					
						
							|  |  |  | 				user->amaflags = ast_cdr_amaflags2int(v->value); | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "ip")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			strncpy(user->mIP, v->value, sizeof(user->mIP)-1); | 
					
						
							|  |  |  |             			user->mUseIP = 1; | 
					
						
							|  |  |  |          		} else if (!strcasecmp(v->name, "host")) { | 
					
						
							|  |  |  |             			strncpy(user->mIP, v->value, sizeof(user->mIP)-1); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				user->mUseIP = 1; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	 		} else if (!strcasecmp(v->name, "dtmfmode")) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				if (!strcasecmp(v->value, "rfc2833")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_RFC2833; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				if (!strcasecmp(v->value, "cisco")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_CISCO; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				else if (!strcasecmp(v->value, "q931keypad")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_Q931; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "h245alphanumeric")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_H245ALPHANUMERIC; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "h245signal")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_H245SIGNAL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				else if (!strcasecmp(v->value, "inband")) | 
					
						
							|  |  |  | 					user->dtmfmode = H323_DTMF_INBAND; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "relaxdtmf")) { | 
					
						
							|  |  |  | 				user->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { | 
					
						
							|  |  |  | 				user->dtmfcodec = atoi(v->value); | 
					
						
							|  |  |  | 	 		} else if (!strcasecmp(v->name, "t38support")) { | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "disabled")) | 
					
						
							|  |  |  | 					user->t38support = T38_DISABLED; | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "no")) | 
					
						
							|  |  |  | 					user->t38support = T38_DISABLED; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "faxgw")) | 
					
						
							|  |  |  | 					user->t38support = T38_FAXGW; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "yes")) | 
					
						
							|  |  |  | 					user->t38support = T38_ENABLED; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			v = v->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   build_user\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return user; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v, int friend_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *peer = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   build_peer\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	peer = ast_calloc(1, sizeof(*peer)); | 
					
						
							|  |  |  | 	if (peer) { | 
					
						
							|  |  |  | 		memset(peer, 0, sizeof(struct ooh323_peer)); | 
					
						
							|  |  |  | 		ast_mutex_init(&peer->lock); | 
					
						
							|  |  |  | 		ast_copy_string(peer->name, name, sizeof(peer->name)); | 
					
						
							|  |  |  | 		peer->capability = gCapability; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		peer->rtptimeout = gRTPTimeout; | 
					
						
							|  |  |  | 		ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode)); | 
					
						
							|  |  |  | 		peer->amaflags = gAMAFLAGS; | 
					
						
							|  |  |  | 		peer->dtmfmode = gDTMFMode; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		peer->dtmfcodec = gDTMFCodec; | 
					
						
							|  |  |  | 		peer->t38support = gT38Support; | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 		peer->faststart = gFastStart; | 
					
						
							|  |  |  | 		peer->h245tunneling = gTunneling; | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		peer->g729onlyA = g729onlyA; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		peer->port = 1720; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		if (0 == friend_type) { | 
					
						
							|  |  |  | 			peer->mFriend = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (v) { | 
					
						
							|  |  |  | 			if (!strcasecmp(v->name, "h323id")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	    if (!(peer->h323id = ast_strdup(v->value))) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					ast_log(LOG_ERROR, "Could not allocate memory for h323id of " | 
					
						
							|  |  |  | 											 "peer %s\n", name); | 
					
						
							|  |  |  | 					ooh323_delete_peer(peer); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "e164")) { | 
					
						
							|  |  |  | 				if (!(peer->e164 = ast_strdup(v->value))) { | 
					
						
							|  |  |  | 					ast_log(LOG_ERROR, "Could not allocate memory for e164 of " | 
					
						
							|  |  |  | 											 "peer %s\n", name); | 
					
						
							|  |  |  | 					ooh323_delete_peer(peer); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else  if (!strcasecmp(v->name, "email")) { | 
					
						
							|  |  |  | 				if (!(peer->email = ast_strdup(v->value))) { | 
					
						
							|  |  |  | 					ast_log(LOG_ERROR, "Could not allocate memory for email of " | 
					
						
							|  |  |  | 											 "peer %s\n", name); | 
					
						
							|  |  |  | 					ooh323_delete_peer(peer); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "url")) { | 
					
						
							|  |  |  | 				if (!(peer->url = ast_strdup(v->value))) { | 
					
						
							|  |  |  | 					ast_log(LOG_ERROR, "Could not allocate memory for h323id of " | 
					
						
							|  |  |  | 											 "peer %s\n", name); | 
					
						
							|  |  |  | 					ooh323_delete_peer(peer); | 
					
						
							|  |  |  | 					return NULL; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "port")) { | 
					
						
							|  |  |  | 				peer->port = atoi(v->value); | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "ip")) { | 
					
						
							|  |  |  | 				ast_copy_string(peer->ip, v->value, sizeof(peer->ip)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		} else if (!strcasecmp(v->name, "host")) { | 
					
						
							|  |  |  |             			ast_copy_string(peer->ip, v->value, sizeof(peer->ip)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "outgoinglimit")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			peer->outgoinglimit = atoi(v->value); | 
					
						
							|  |  |  |             			if (peer->outgoinglimit < 0) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					peer->outgoinglimit = 0; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "accountcode")) { | 
					
						
							|  |  |  | 				ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode)); | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "faststart")) { | 
					
						
							|  |  |  | 				peer->faststart = ast_true(v->value); | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "h245tunneling")) { | 
					
						
							|  |  |  | 				peer->h245tunneling = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "g729onlyA")) { | 
					
						
							|  |  |  | 				peer->g729onlyA = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "rtptimeout")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			peer->rtptimeout = atoi(v->value); | 
					
						
							|  |  |  |             			if(peer->rtptimeout < 0) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					peer->rtptimeout = gRTPTimeout; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "rtpmask")) { | 
					
						
							|  |  |  | 				if ((peer->rtpmask = malloc(sizeof(struct OOH323Regex))) && | 
					
						
							|  |  |  | 					(regcomp(&peer->rtpmask->regex, v->value, REG_EXTENDED)  | 
					
						
							|  |  |  | 											== 0)) { | 
					
						
							|  |  |  | 					ast_mutex_init(&peer->rtpmask->lock); | 
					
						
							|  |  |  | 					peer->rtpmask->inuse = 1; | 
					
						
							|  |  |  | 					ast_copy_string(peer->rtpmaskstr, v->value,  | 
					
						
							|  |  |  | 								sizeof(peer->rtpmaskstr)); | 
					
						
							|  |  |  | 				} else peer->rtpmask = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "disallow")) { | 
					
						
							|  |  |  | 				ast_parse_allow_disallow(&peer->prefs, &peer->capability,  | 
					
						
							|  |  |  | 												 v->value, 0);  | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "allow")) { | 
					
						
							|  |  |  | 				const char* tcodecs = v->value; | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "all")) { | 
					
						
							|  |  |  | 					tcodecs = "ulaw,alaw,g729,g723,gsm"; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				ast_parse_allow_disallow(&peer->prefs, &peer->capability,  | 
					
						
							|  |  |  | 												 tcodecs, 1);				  | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name,  "amaflags")) { | 
					
						
							|  |  |  | 				peer->amaflags = ast_cdr_amaflags2int(v->value); | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "roundtrip")) { | 
					
						
							|  |  |  | 				sscanf(v->value, "%d,%d", &peer->rtdrcount, &peer->rtdrinterval); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} else if (!strcasecmp(v->name, "dtmfmode")) { | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "rfc2833")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_RFC2833; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				if (!strcasecmp(v->value, "cisco")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_CISCO; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				else if (!strcasecmp(v->value, "q931keypad")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_Q931; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "h245alphanumeric")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_H245ALPHANUMERIC; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "h245signal")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_H245SIGNAL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 				else if (!strcasecmp(v->value, "inband")) | 
					
						
							|  |  |  | 					peer->dtmfmode = H323_DTMF_INBAND; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "relaxdtmf")) { | 
					
						
							|  |  |  | 				peer->dtmfmode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { | 
					
						
							|  |  |  | 				peer->dtmfcodec = atoi(v->value); | 
					
						
							|  |  |  | 	 		} else if (!strcasecmp(v->name, "t38support")) { | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "disabled")) | 
					
						
							|  |  |  | 					peer->t38support = T38_DISABLED; | 
					
						
							|  |  |  | 				if (!strcasecmp(v->value, "no")) | 
					
						
							|  |  |  | 					peer->t38support = T38_DISABLED; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "faxgw")) | 
					
						
							|  |  |  | 					peer->t38support = T38_FAXGW; | 
					
						
							|  |  |  | 				else if (!strcasecmp(v->value, "yes")) | 
					
						
							|  |  |  | 					peer->t38support = T38_ENABLED; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			v = v->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   build_peer\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return peer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_do_reload(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_do_reload\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	reload_config(1); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_do_reload\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*--- h323_reload: Force reload of module from cli ---*/ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | char *handle_cli_ooh323_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |        switch (cmd) { | 
					
						
							|  |  |  |        case CLI_INIT: | 
					
						
							|  |  |  |                e->command = "ooh323 reload"; | 
					
						
							|  |  |  |                e->usage = | 
					
						
							|  |  |  |                        "Usage: ooh323 reload\n" | 
					
						
							|  |  |  |                        "                Reload OOH323 config.\n"; | 
					
						
							|  |  |  |                return NULL; | 
					
						
							|  |  |  |        case CLI_GENERATE: | 
					
						
							|  |  |  |                return NULL; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (a->argc != 2) | 
					
						
							|  |  |  |                return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_reload\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&h323_reload_lock); | 
					
						
							|  |  |  | 	if (h323_reloading) { | 
					
						
							|  |  |  | 		ast_verbose("Previous OOH323 reload not yet done\n"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    } else { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		h323_reloading = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&h323_reload_lock); | 
					
						
							|  |  |  | 	restart_monitor(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_reload\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int reload_config(int reload) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int format; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct ooAliases  *pNewAlias = NULL, *cur, *prev; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	struct ast_config *cfg; | 
					
						
							|  |  |  | 	struct ast_variable *v; | 
					
						
							|  |  |  | 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; | 
					
						
							|  |  |  | 	struct ooh323_user *user = NULL; | 
					
						
							|  |  |  | 	struct ooh323_peer *peer = NULL; | 
					
						
							|  |  |  | 	char *cat; | 
					
						
							|  |  |  | 	const char *utype; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   reload_config\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	cfg = ast_config_load((char*)config, config_flags); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* We *must* have a config file otherwise stop immediately */ | 
					
						
							|  |  |  | 	if (!cfg) { | 
					
						
							|  |  |  | 		ast_log(LOG_NOTICE, "Unable to load config %s, OOH323 disabled\n", config); | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | 	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) | 
					
						
							|  |  |  | 		return RESULT_SUCCESS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (reload) { | 
					
						
							|  |  |  | 		delete_users(); | 
					
						
							|  |  |  | 		delete_peers(); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (gH323Debug) { | 
					
						
							|  |  |  | 			ast_verbose("  reload_config - Freeing up alias list\n"); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		cur = gAliasList; | 
					
						
							|  |  |  | 		while (cur) { | 
					
						
							|  |  |  | 			prev = cur; | 
					
						
							|  |  |  | 	  		cur = cur->next; | 
					
						
							|  |  |  | 	  		free(prev->value); | 
					
						
							|  |  |  | 	  		free(prev); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		gAliasList = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Inintialize everything to default */ | 
					
						
							|  |  |  | 	strcpy(gLogFile, DEFAULT_LOGFILE); | 
					
						
							|  |  |  | 	gPort = 1720; | 
					
						
							|  |  |  | 	gIP[0] = '\0'; | 
					
						
							|  |  |  | 	strcpy(gCallerID, DEFAULT_H323ID); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    	gCapability = AST_FORMAT_ALAW; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	memset(&gPrefs, 0, sizeof(struct ast_codec_pref)); | 
					
						
							|  |  |  | 	gDTMFMode = H323_DTMF_RFC2833; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	gDTMFCodec = 101; | 
					
						
							|  |  |  | 	gT38Support = T38_FAXGW; | 
					
						
							|  |  |  | 	gTRCLVL = OOTRCLVLERR; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	gRasGkMode = RasNoGatekeeper; | 
					
						
							|  |  |  | 	gGatekeeper[0] = '\0'; | 
					
						
							|  |  |  | 	gRTPTimeout = 60; | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	gRTDRInterval = 0; | 
					
						
							|  |  |  | 	gRTDRCount = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	strcpy(gAccountcode, DEFAULT_H323ACCNT); | 
					
						
							|  |  |  | 	gFastStart = 1; | 
					
						
							|  |  |  | 	gTunneling = 1; | 
					
						
							|  |  |  | 	gTOS = 0; | 
					
						
							|  |  |  | 	strcpy(gContext, DEFAULT_CONTEXT); | 
					
						
							|  |  |  | 	gAliasList = NULL; | 
					
						
							|  |  |  | 	gMediaWaitForConnect = 0; | 
					
						
							|  |  |  | 	ooconfig.mTCPPortStart = 12030; | 
					
						
							|  |  |  | 	ooconfig.mTCPPortEnd = 12230; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	v = ast_variable_browse(cfg, "general"); | 
					
						
							|  |  |  | 	while (v) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!ast_jb_read_conf(&global_jbconf, v->name, v->value)) { | 
					
						
							|  |  |  | 			v = v->next; | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 		if (!strcasecmp(v->name, "port")) { | 
					
						
							|  |  |  | 			gPort = (int)strtol(v->value, NULL, 10); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "bindaddr")) { | 
					
						
							|  |  |  | 			ast_copy_string(gIP, v->value, sizeof(gIP)); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "h225portrange")) { | 
					
						
							|  |  |  | 			char* endlimit = 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		char temp[512]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_copy_string(temp, v->value, sizeof(temp)); | 
					
						
							|  |  |  | 			endlimit = strchr(temp, ','); | 
					
						
							|  |  |  | 			if (endlimit) { | 
					
						
							|  |  |  | 				*endlimit = '\0'; | 
					
						
							|  |  |  | 				endlimit++; | 
					
						
							|  |  |  | 				ooconfig.mTCPPortStart = atoi(temp); | 
					
						
							|  |  |  | 				ooconfig.mTCPPortEnd = atoi(endlimit); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "h225portrange: Invalid format, separate port range with \",\"\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "gateway")) { | 
					
						
							|  |  |  | 			gIsGateway = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		} else if (!strcasecmp(v->name, "faststart")) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			gFastStart = ast_true(v->value); | 
					
						
							|  |  |  | 			if (gFastStart) | 
					
						
							|  |  |  | 				ooH323EpEnableFastStart(); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				ooH323EpDisableFastStart(); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "mediawaitforconnect")) { | 
					
						
							|  |  |  | 			gMediaWaitForConnect = ast_true(v->value); | 
					
						
							|  |  |  | 			if (gMediaWaitForConnect) | 
					
						
							|  |  |  | 				ooH323EpEnableMediaWaitForConnect(); | 
					
						
							|  |  |  | 			else  | 
					
						
							|  |  |  | 				ooH323EpDisableMediaWaitForConnect(); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "h245tunneling")) { | 
					
						
							|  |  |  | 			gTunneling = ast_true(v->value); | 
					
						
							|  |  |  | 			if (gTunneling) | 
					
						
							|  |  |  | 				ooH323EpEnableH245Tunneling(); | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				ooH323EpDisableH245Tunneling(); | 
					
						
							| 
									
										
										
										
											2011-02-18 00:07:20 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "g729onlyA")) { | 
					
						
							|  |  |  | 			g729onlyA = ast_true(v->value); | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "roundtrip")) { | 
					
						
							|  |  |  | 			sscanf(v->value, "%d,%d", &gRTDRCount, &gRTDRInterval); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		} else if (!strcasecmp(v->name, "trybemaster")) { | 
					
						
							|  |  |  | 			gBeMaster = ast_true(v->value); | 
					
						
							|  |  |  | 			if (gBeMaster) | 
					
						
							|  |  |  | 				ooH323EpTryBeMaster(1); | 
					
						
							|  |  |  | 			else  | 
					
						
							|  |  |  | 				ooH323EpTryBeMaster(0); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "h323id")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		pNewAlias = malloc(sizeof(struct ooAliases)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			if (!pNewAlias) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "Failed to allocate memory for h323id alias\n"); | 
					
						
							|  |  |  | 				return 1; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	 		if (gAliasList == NULL) { /* first h323id - set as callerid if callerid is not set */ | 
					
						
							|  |  |  | 	  			ast_copy_string(gCallerID, v->value, sizeof(gCallerID)); | 
					
						
							|  |  |  | 	 		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			pNewAlias->type =  T_H225AliasAddress_h323_ID; | 
					
						
							|  |  |  | 			pNewAlias->value = strdup(v->value); | 
					
						
							|  |  |  | 			pNewAlias->next = gAliasList; | 
					
						
							|  |  |  | 			gAliasList = pNewAlias; | 
					
						
							|  |  |  | 			pNewAlias = NULL; | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "e164")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		pNewAlias = malloc(sizeof(struct ooAliases)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			if (!pNewAlias) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "Failed to allocate memory for e164 alias\n"); | 
					
						
							|  |  |  | 				return 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			pNewAlias->type =  T_H225AliasAddress_dialedDigits; | 
					
						
							|  |  |  | 			pNewAlias->value = strdup(v->value); | 
					
						
							|  |  |  | 			pNewAlias->next = gAliasList; | 
					
						
							|  |  |  | 			gAliasList = pNewAlias; | 
					
						
							|  |  |  | 			pNewAlias = NULL; | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "email")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		pNewAlias = malloc(sizeof(struct ooAliases)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			if (!pNewAlias) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "Failed to allocate memory for email alias\n"); | 
					
						
							|  |  |  | 				return 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			pNewAlias->type =  T_H225AliasAddress_email_ID; | 
					
						
							|  |  |  | 			pNewAlias->value = strdup(v->value); | 
					
						
							|  |  |  | 			pNewAlias->next = gAliasList; | 
					
						
							|  |  |  | 			gAliasList = pNewAlias; | 
					
						
							|  |  |  | 			pNewAlias = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       } else if (!strcasecmp(v->name, "t35country")) { | 
					
						
							|  |  |  |          t35countrycode = atoi(v->value); | 
					
						
							|  |  |  |       } else if (!strcasecmp(v->name, "t35extensions")) { | 
					
						
							|  |  |  |          t35extensions = atoi(v->value); | 
					
						
							|  |  |  |       } else if (!strcasecmp(v->name, "manufacturer")) { | 
					
						
							|  |  |  |          manufacturer = atoi(v->value); | 
					
						
							|  |  |  |       } else if (!strcasecmp(v->name, "vendorid")) { | 
					
						
							|  |  |  |          ast_copy_string(vendor, v->value, sizeof(vendor)); | 
					
						
							|  |  |  |       } else if (!strcasecmp(v->name, "versionid")) { | 
					
						
							|  |  |  |          ast_copy_string(version, v->value, sizeof(version)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "callerid")) { | 
					
						
							|  |  |  | 			ast_copy_string(gCallerID, v->value, sizeof(gCallerID)); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "incominglimit")) { | 
					
						
							|  |  |  | 			gIncomingLimit = atoi(v->value); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "outgoinglimit")) { | 
					
						
							|  |  |  | 			gOutgoingLimit = atoi(v->value); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "gatekeeper")) { | 
					
						
							|  |  |  | 			if (!strcasecmp(v->value, "DISABLE")) { | 
					
						
							|  |  |  | 				gRasGkMode = RasNoGatekeeper; | 
					
						
							|  |  |  | 			} else if (!strcasecmp(v->value, "DISCOVER")) { | 
					
						
							|  |  |  | 				gRasGkMode = RasDiscoverGatekeeper; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				gRasGkMode = RasUseSpecificGatekeeper; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			strncpy(gGatekeeper, v->value, sizeof(gGatekeeper)-1); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "logfile")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          strncpy(gLogFile, v->value, sizeof(gLogFile)-1); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "context")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          strncpy(gContext, v->value, sizeof(gContext)-1); | 
					
						
							|  |  |  |          ast_verbose(VERBOSE_PREFIX_3 "  == Setting default context to %s\n",  | 
					
						
							|  |  |  |                                                       gContext); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "rtptimeout")) { | 
					
						
							|  |  |  | 			gRTPTimeout = atoi(v->value); | 
					
						
							|  |  |  | 			if (gRTPTimeout <= 0) | 
					
						
							|  |  |  | 				gRTPTimeout = 60; | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "tos")) { | 
					
						
							| 
									
										
										
										
											2009-08-10 19:20:57 +00:00
										 |  |  | 			if (sscanf(v->value, "%30i", &format) == 1) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				gTOS = format & 0xff; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "lowdelay")) | 
					
						
							|  |  |  | 				gTOS = IPTOS_LOWDELAY; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "throughput")) | 
					
						
							|  |  |  | 				gTOS = IPTOS_THROUGHPUT; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "reliability")) | 
					
						
							|  |  |  | 				gTOS = IPTOS_RELIABILITY; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "mincost")) | 
					
						
							|  |  |  | 				gTOS = IPTOS_MINCOST; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "none")) | 
					
						
							|  |  |  | 				gTOS = 0; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "Invalid tos value at line %d, should be " | 
					
						
							|  |  |  | 											"'lowdelay', 'throughput', 'reliability', " | 
					
						
							|  |  |  | 											"'mincost', or 'none'\n", v->lineno); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "amaflags")) { | 
					
						
							|  |  |  | 			gAMAFLAGS = ast_cdr_amaflags2int(v->value); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "accountcode")) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "disallow")) { | 
					
						
							|  |  |  | 			ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 0); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "allow")) { | 
					
						
							|  |  |  | 			const char* tcodecs = v->value; | 
					
						
							|  |  |  | 			if (!strcasecmp(v->value, "all")) { | 
					
						
							|  |  |  | 				tcodecs = "ulaw,alaw,g729,g723,gsm"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ast_parse_allow_disallow(&gPrefs, &gCapability, tcodecs, 1); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "dtmfmode")) { | 
					
						
							|  |  |  | 			if (!strcasecmp(v->value, "inband")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_INBAND; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "rfc2833")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_RFC2833; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			else if (!strcasecmp(v->value, "cisco")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_CISCO; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			else if (!strcasecmp(v->value, "q931keypad")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_Q931; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "h245alphanumeric")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_H245ALPHANUMERIC; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "h245signal")) | 
					
						
							|  |  |  | 				gDTMFMode = H323_DTMF_H245SIGNAL; | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n",  | 
					
						
							|  |  |  |                                                                     v->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				gDTMFMode = H323_DTMF_RFC2833; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "relaxdtmf")) { | 
					
						
							|  |  |  | 			gDTMFMode |= ast_true(v->value) ? H323_DTMF_INBANDRELAX : 0; | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "dtmfcodec") && atoi(v->value)) { | 
					
						
							|  |  |  | 			gDTMFCodec = atoi(v->value); | 
					
						
							|  |  |  | 	 	} else if (!strcasecmp(v->name, "t38support")) { | 
					
						
							|  |  |  | 			if (!strcasecmp(v->value, "disabled")) | 
					
						
							|  |  |  | 				gT38Support = T38_DISABLED; | 
					
						
							|  |  |  | 			if (!strcasecmp(v->value, "no")) | 
					
						
							|  |  |  | 				gT38Support = T38_DISABLED; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "faxgw")) | 
					
						
							|  |  |  | 				gT38Support = T38_FAXGW; | 
					
						
							|  |  |  | 			else if (!strcasecmp(v->value, "yes")) | 
					
						
							|  |  |  | 				gT38Support = T38_ENABLED; | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "tracelevel")) { | 
					
						
							|  |  |  | 			gTRCLVL = atoi(v->value); | 
					
						
							|  |  |  | 			ooH323EpSetTraceLevel(gTRCLVL); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		v = v->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) { | 
					
						
							|  |  |  | 		if (strcasecmp(cat, "general")) { | 
					
						
							|  |  |  | 			int friend_type = 0; | 
					
						
							|  |  |  | 			utype = ast_variable_retrieve(cfg, cat, "type"); | 
					
						
							|  |  |  | 			if (utype) { | 
					
						
							|  |  |  | 				friend_type = strcasecmp(utype, "friend"); | 
					
						
							|  |  |  | 				if (!strcmp(utype, "user") || 0 == friend_type) { | 
					
						
							|  |  |  | 					user = build_user(cat, ast_variable_browse(cfg, cat)); | 
					
						
							|  |  |  | 					if (user) { | 
					
						
							|  |  |  | 						ast_mutex_lock(&userl.lock); | 
					
						
							|  |  |  | 						user->next = userl.users; | 
					
						
							|  |  |  | 						userl.users = user; | 
					
						
							|  |  |  | 						ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						ast_log(LOG_WARNING, "Failed to build user %s\n", cat); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!strcasecmp(utype, "peer") || 0 == friend_type) { | 
					
						
							|  |  |  | 					peer = build_peer(cat, ast_variable_browse(cfg, cat), friend_type); | 
					
						
							|  |  |  | 					if (peer) { | 
					
						
							|  |  |  | 						ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 						peer->next = peerl.peers; | 
					
						
							|  |  |  | 						peerl.peers = peer; | 
					
						
							|  |  |  | 						ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 					} else { | 
					
						
							|  |  |  | 						ast_log(LOG_WARNING, "Failed to build peer %s\n", cat); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_config_destroy(cfg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	/* Determine ip address if neccessary */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (ast_strlen_zero(gIP)) { | 
					
						
							|  |  |  | 		ooGetLocalIPAddress(gIP); | 
					
						
							|  |  |  | 		if (!strcmp(gIP, "127.0.0.1")) { | 
					
						
							|  |  |  | 			ast_log(LOG_NOTICE, "Failed to determine local ip address. Please " | 
					
						
							|  |  |  | 									 "specify it in ooh323.conf. OOH323 Disabled\n"); | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   reload_config\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static char *handle_cli_ooh323_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char ip_port[30]; | 
					
						
							|  |  |  | 	struct ooh323_peer *prev = NULL, *peer = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 show peer"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 show peer <name>\n" | 
					
						
							|  |  |  | 			"		 List details of specific OOH323 peer.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc != 4) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 	peer = peerl.peers; | 
					
						
							|  |  |  | 	while (peer) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&peer->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		if(!strcmp(peer->name, a->argv[3])) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			prev = peer; | 
					
						
							|  |  |  | 			peer = peer->next; | 
					
						
							|  |  |  | 			ast_mutex_unlock(&prev->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (peer) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       sprintf(ip_port, "%s:%d", peer->ip, peer->port); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", peer->name); | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  |       ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", peer->faststart?"yes":"no", | 
					
						
							|  |  |  | 					peer->h245tunneling?"yes":"no"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "("); | 
					
						
							|  |  |  |       print_codec_to_cli(a->fd, &peer->prefs); | 
					
						
							|  |  |  |       ast_cli(a->fd, ")\n"); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s", "DTMF Mode: "); | 
					
						
							|  |  |  | 		if (peer->dtmfmode & H323_DTMF_CISCO) { | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "cisco"); | 
					
						
							|  |  |  | 	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec); | 
					
						
							|  |  |  | 		} else if (peer->dtmfmode & H323_DTMF_RFC2833) { | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "rfc2833"); | 
					
						
							|  |  |  | 	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", peer->dtmfcodec); | 
					
						
							|  |  |  | 		} else if (peer->dtmfmode & H323_DTMF_Q931) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "q931keypad"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else if (peer->dtmfmode & H323_DTMF_H245ALPHANUMERIC) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "h245alphanumeric"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else if (peer->dtmfmode & H323_DTMF_H245SIGNAL) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "h245signal"); | 
					
						
							|  |  |  | 		else if (peer->dtmfmode & H323_DTMF_INBAND && peer->dtmfmode & H323_DTMF_INBANDRELAX) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband-relaxed"); | 
					
						
							|  |  |  | 		else if (peer->dtmfmode & H323_DTMF_INBAND) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "unknown"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_cli(a->fd,"%-15s", "T.38 Mode: "); | 
					
						
							|  |  |  | 	if (peer->t38support == T38_DISABLED) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "disabled"); | 
					
						
							|  |  |  | 	else if (peer->t38support == T38_FAXGW) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", peer->accountcode); | 
					
						
							|  |  |  | 	ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ",  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_cdr_flags2str(peer->amaflags)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_cli(a->fd, "%-15.15s%s\n", "IP:Port: ", ip_port); | 
					
						
							|  |  |  | 	ast_cli(a->fd, "%-15.15s%d\n", "OutgoingLimit: ", peer->outgoinglimit); | 
					
						
							|  |  |  | 	ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", peer->rtptimeout); | 
					
						
							|  |  |  | 	if (peer->rtpmaskstr[0]) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", peer->rtpmaskstr); | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	if (peer->rtdrcount && peer->rtdrinterval)  | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", peer->rtdrcount, peer->rtdrinterval); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_mutex_unlock(&peer->lock); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_cli(a->fd, "Peer %s not found\n", a->argv[3]); | 
					
						
							|  |  |  | 	ast_cli(a->fd, "\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *prev = NULL, *peer = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    char formats[FORMAT_STRING_SIZE]; | 
					
						
							|  |  |  |    char ip_port[30]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | #define FORMAT  "%-15.15s  %-15.15s  %-23.23s  %-s\n"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 show peers"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 show peers\n" | 
					
						
							|  |  |  | 			"		 Lists all known OOH323 peers.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc != 3) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd, FORMAT, "Name", "Accountcode", "ip:port", "Formats"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 	peer = peerl.peers; | 
					
						
							|  |  |  | 	while (peer) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&peer->lock); | 
					
						
							|  |  |  | 		snprintf(ip_port, sizeof(ip_port), "%s:%d", peer->ip, peer->port); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |      ast_cli(a->fd, FORMAT, peer->name,  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					peer->accountcode, | 
					
						
							|  |  |  | 					ip_port, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |                  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->capability)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		prev = peer; | 
					
						
							|  |  |  | 		peer = peer->next; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&prev->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | #undef FORMAT
 | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*! \brief Print codec list from preference to CLI/manager */ | 
					
						
							|  |  |  | static void print_codec_to_cli(int fd, struct ast_codec_pref *pref) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int x, codec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < 32; x++) { | 
					
						
							|  |  |  | 		codec = ast_codec_pref_index(pref, x); | 
					
						
							|  |  |  | 		if (!codec) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		ast_cli(fd, "%s", ast_getformatname(codec)); | 
					
						
							|  |  |  | 		ast_cli(fd, ":%d", pref->framing[x]); | 
					
						
							|  |  |  | 		if (x < 31 && ast_codec_pref_index(pref, x + 1)) | 
					
						
							|  |  |  | 			ast_cli(fd, ","); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!x) | 
					
						
							|  |  |  | 		ast_cli(fd, "none"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ooh323_show_user(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *prev = NULL, *user = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 show user"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 show user <name>\n" | 
					
						
							|  |  |  | 			"		 List details of specific OOH323 user.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc != 4) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_mutex_lock(&userl.lock); | 
					
						
							|  |  |  | 	user = userl.users; | 
					
						
							|  |  |  | 	while (user) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&user->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       if(!strcmp(user->name, a->argv[3])) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			prev = user; | 
					
						
							|  |  |  | 			user = user->next; | 
					
						
							|  |  |  | 			ast_mutex_unlock(&prev->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (user) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_cli(a->fd, "%-15.15s%s\n", "Name: ", user->name); | 
					
						
							| 
									
										
										
										
											2010-10-09 14:02:26 +00:00
										 |  |  |       ast_cli(a->fd, "%s:%s,%s\n", "FastStart/H.245 Tunneling", user->faststart?"yes":"no", | 
					
						
							|  |  |  | 					user->h245tunneling?"yes":"no"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_cli(a->fd, "%-15.15s%s", "Format Prefs: ", "("); | 
					
						
							|  |  |  |       print_codec_to_cli(a->fd, &user->prefs); | 
					
						
							|  |  |  |       ast_cli(a->fd, ")\n"); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s", "DTMF Mode: "); | 
					
						
							|  |  |  | 		if (user->dtmfmode & H323_DTMF_CISCO) { | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "cisco"); | 
					
						
							|  |  |  | 	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec); | 
					
						
							|  |  |  | 		} else if (user->dtmfmode & H323_DTMF_RFC2833) { | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "rfc2833"); | 
					
						
							|  |  |  | 	 ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", user->dtmfcodec); | 
					
						
							|  |  |  | 		} else if (user->dtmfmode & H323_DTMF_Q931) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "q931keypad"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else if (user->dtmfmode & H323_DTMF_H245ALPHANUMERIC) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "h245alphanumeric"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else if (user->dtmfmode & H323_DTMF_H245SIGNAL) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "h245signal"); | 
					
						
							|  |  |  | 		else if (user->dtmfmode & H323_DTMF_INBAND && user->dtmfmode & H323_DTMF_INBANDRELAX) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband-relaxed"); | 
					
						
							|  |  |  | 		else if (user->dtmfmode & H323_DTMF_INBAND) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd, "%s\n", "unknown"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	ast_cli(a->fd,"%-15s", "T.38 Mode: "); | 
					
						
							|  |  |  | 	if (user->t38support == T38_DISABLED) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "disabled"); | 
					
						
							|  |  |  | 	else if (user->t38support == T38_FAXGW) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%s\n", "AccountCode: ", user->accountcode); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%s\n", "AMA flags: ",  | 
					
						
							|  |  |  |                                             ast_cdr_flags2str(user->amaflags)); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%s\n", "Context: ", user->context); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%d\n", "IncomingLimit: ", user->incominglimit); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%d\n", "InUse: ", user->inUse); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%d\n", "rtptimeout: ", user->rtptimeout); | 
					
						
							|  |  |  | 	if (user->rtpmaskstr[0]) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%-15.15s%s\n", "rtpmask: ", user->rtpmaskstr); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_unlock(&user->lock); | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	if (user->rtdrcount && user->rtdrinterval)  | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", user->rtdrcount, user->rtdrinterval); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |      ast_cli(a->fd, "User %s not found\n", a->argv[3]); | 
					
						
							|  |  |  |      ast_cli(a->fd, "\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *prev = NULL, *user = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    char formats[FORMAT_STRING_SIZE]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | #define FORMAT1  "%-15.15s  %-15.15s  %-15.15s  %-s\n"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 show users"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 show users \n" | 
					
						
							|  |  |  | 			"		 Lists all known OOH323 users.\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc != 3) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    ast_cli(a->fd, FORMAT1, "Username", "Accountcode", "Context", "Formats"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&userl.lock); | 
					
						
							|  |  |  | 	user = userl.users; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    while(user) | 
					
						
							|  |  |  |    { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_lock(&user->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |      		ast_cli(a->fd, FORMAT1, user->name,  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 					user->accountcode, user->context, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 					ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->capability)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		prev = user; | 
					
						
							|  |  |  | 		user = user->next; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&prev->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | #undef FORMAT1
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    return RESULT_SUCCESS; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ooh323_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 set debug [off]"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 set debug [off]\n" | 
					
						
							|  |  |  | 			"		 Enables/Disables debugging of OOH323 channel driver\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc < 3 || a->argc > 4) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 	if (a->argc == 4 && strcasecmp(a->argv[3], "off")) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gH323Debug = (a->argc == 4) ? FALSE : TRUE; | 
					
						
							|  |  |  | 	ast_cli(a->fd, "OOH323 Debugging %s\n", gH323Debug ? "Enabled" : "Disabled"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | static int ooh323_show_channels(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	char value[FORMAT_STRING_SIZE]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ooAliases *pAlias = NULL, *pAliasNext = NULL;; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ooh323 show config"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							|  |  |  | 			"Usage: ooh323 show config\n" | 
					
						
							|  |  |  | 			"		 Shows global configuration of H.323 channel driver\n"; | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc != 3) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd, "\nObjective Open H.323 Channel Driver's Config:\n"); | 
					
						
							|  |  |  | 	snprintf(value, sizeof(value), "%s:%d", gIP, gPort); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "IP:Port: ", value); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%d-%d\n", "H.225 port range: ",  | 
					
						
							|  |  |  |       ooconfig.mTCPPortStart, ooconfig.mTCPPortEnd); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "FastStart", gFastStart?"yes":"no"); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "Tunneling", gTunneling?"yes":"no"); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "CallerId", gCallerID); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "MediaWaitForConnect",  | 
					
						
							|  |  |  |       gMediaWaitForConnect?"yes":"no"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if (0)
 | 
					
						
							|  |  |  | 		extern OOH323EndPoint gH323ep; | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "FASTSTART",  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			(OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART) != 0) ? "yes" : "no"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd, "%-20s%s\n", "TUNNELING",  | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			(OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING) != 0) ? "yes" : "no"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd, "%-20s%s\n", "MEDIAWAITFORCONN", | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			(OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN) != 0) ? "yes" : "no"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gRasGkMode == RasNoGatekeeper) | 
					
						
							|  |  |  | 		snprintf(value, sizeof(value), "%s", "No Gatekeeper"); | 
					
						
							|  |  |  | 	else if (gRasGkMode == RasDiscoverGatekeeper) | 
					
						
							|  |  |  | 		snprintf(value, sizeof(value), "%s", "Discover"); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		snprintf(value, sizeof(value), "%s", gGatekeeper); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd,  "%-20s%s\n", "Gatekeeper:", value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    ast_cli(a->fd,  "%-20s%s\n", "H.323 LogFile:", gLogFile);    | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext); | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |    ast_cli(a->fd,  "%-20s%s\n", "Capability:",  | 
					
						
							|  |  |  |            ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s", "DTMF Mode: "); | 
					
						
							|  |  |  | 	if (gDTMFMode & H323_DTMF_CISCO) { | 
					
						
							|  |  |  |       ast_cli(a->fd, "%s\n", "cisco"); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); | 
					
						
							|  |  |  | 	} else if (gDTMFMode & H323_DTMF_RFC2833) { | 
					
						
							|  |  |  |       ast_cli(a->fd, "%s\n", "rfc2833"); | 
					
						
							|  |  |  |       ast_cli(a->fd, "%-15.15s%d\n", "DTMF Codec: ", gDTMFCodec); | 
					
						
							|  |  |  | 	} else if (gDTMFMode & H323_DTMF_Q931) | 
					
						
							|  |  |  |       ast_cli(a->fd, "%s\n", "q931keypad"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	else if (gDTMFMode & H323_DTMF_H245ALPHANUMERIC) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_cli(a->fd, "%s\n", "h245alphanumeric"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	else if (gDTMFMode & H323_DTMF_H245SIGNAL) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_cli(a->fd, "%s\n", "h245signal"); | 
					
						
							|  |  |  | 		else if (gDTMFMode & H323_DTMF_INBAND && gDTMFMode & H323_DTMF_INBANDRELAX) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband-relaxed"); | 
					
						
							|  |  |  | 		else if (gDTMFMode & H323_DTMF_INBAND) | 
					
						
							|  |  |  |          ast_cli(a->fd, "%s\n", "inband"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "unknown"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    	ast_cli(a->fd,"%-20s", "T.38 Mode: "); | 
					
						
							|  |  |  | 	if (gT38Support == T38_DISABLED) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "disabled"); | 
					
						
							|  |  |  | 	else if (gT38Support == T38_FAXGW) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%s\n", "faxgw/chan_sip compatible"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	if (gRTDRCount && gRTDRInterval) | 
					
						
							|  |  |  | 		ast_cli(a->fd, "%-15.15s%d,%d\n", "RoundTrip: ", gRTDRCount, gRTDRInterval); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    ast_cli(a->fd, "%-20s%ld\n", "Call counter: ", callnumber); | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "AccountCode: ", gAccountcode); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    ast_cli(a->fd, "%-20s%s\n", "AMA flags: ", ast_cdr_flags2str(gAMAFLAGS)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	pAlias = gAliasList; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    if(pAlias) { | 
					
						
							|  |  |  |      ast_cli(a->fd, "%-20s\n", "Aliases: "); | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	while (pAlias) { | 
					
						
							|  |  |  | 		pAliasNext = pAlias->next; | 
					
						
							|  |  |  | 		if (pAliasNext) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_cli(a->fd,"\t%-30s\t%-30s\n",pAlias->value, pAliasNext->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			pAlias = pAliasNext->next; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       } | 
					
						
							|  |  |  |       else{ | 
					
						
							|  |  |  |          ast_cli(a->fd,"\t%-30s\n",pAlias->value); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			pAlias = pAlias->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return CLI_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_cli_entry cli_ooh323[] = { | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_set_debug,	"Enable/Disable OOH323 debugging"), | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_show_config, "Show details on global configuration of H.323 channel driver"), | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_show_peer,	"Show details on specific OOH323 peer"), | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_show_peers,  "Show defined OOH323 peers"), | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_show_user,	"Show details on specific OOH323 user"), | 
					
						
							|  |  |  | 	AST_CLI_DEFINE(handle_cli_ooh323_show_users,  "Show defined OOH323 users"), | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |         AST_CLI_DEFINE(handle_cli_ooh323_reload, "reload ooh323 config") | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | static int load_module(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	struct ooAliases * pNewAlias = NULL; | 
					
						
							|  |  |  | 	struct ooh323_peer *peer = NULL; | 
					
						
							|  |  |  | 	OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	OOH323CALLBACKS h323Callbacks = { | 
					
						
							|  |  |  | 		.onNewCallCreated = onNewCallCreated, | 
					
						
							|  |  |  | 		.onAlerting = onAlerting, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		.onProgress = onProgress, | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		.onIncomingCall = NULL, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		.onOutgoingCall = onOutgoingCall, | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		.onCallEstablished = onCallEstablished, | 
					
						
							|  |  |  | 		.onCallCleared = onCallCleared, | 
					
						
							|  |  |  | 		.openLogicalChannels = NULL, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		.onReceivedDTMF = ooh323_onReceivedDigit, | 
					
						
							|  |  |  | 		.onModeChanged = onModeChanged | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	myself = ast_module_info->self; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	h225Callbacks.onReceivedSetup = &ooh323_onReceivedSetup; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	userl.users = NULL; | 
					
						
							|  |  |  | 	ast_mutex_init(&userl.lock); | 
					
						
							|  |  |  | 	peerl.peers = NULL; | 
					
						
							|  |  |  | 	ast_mutex_init(&peerl.lock); | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | #if 0		
 | 
					
						
							|  |  |  | 	ast_register_atexit(&ast_ooh323c_exit); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(sched = sched_context_create())) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to create schedule context\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!(io = io_context_create())) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to create I/O context\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!(res = reload_config(0))) { | 
					
						
							|  |  |  | 		/* Make sure we can register our OOH323 channel type */ | 
					
						
							|  |  |  | 		if (ast_channel_register(&ooh323_tech)) { | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Unable to register channel class %s\n", type); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_rtp_glue_register(&ooh323_rtp); | 
					
						
							|  |  |  | 		ast_udptl_proto_register(&ooh323_udptl); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_cli_register_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		 /* fire up the H.323 Endpoint */		  | 
					
						
							|  |  |  | 		if (OO_OK != ooH323EpInitialize(OO_CALLMODE_AUDIOCALL, gLogFile)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_log(LOG_ERROR, "Failed to initialize OOH323 endpoint-" | 
					
						
							|  |  |  |                             "OOH323 Disabled\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (gIsGateway) | 
					
						
							|  |  |  | 			ooH323EpSetAsGateway(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		ooH323EpSetVersionInfo(t35countrycode, t35extensions, manufacturer, | 
					
						
							|  |  |  | 									 vendor, version); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ooH323EpDisableAutoAnswer(); | 
					
						
							|  |  |  | 		ooH323EpSetH225MsgCallbacks(h225Callbacks); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       		ooH323EpSetTraceLevel(gTRCLVL); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ooH323EpSetLocalAddress(gIP, gPort); | 
					
						
							|  |  |  | 		ooH323EpSetCallerID(gCallerID); | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       if(ooH323EpSetTCPPortRange(ooconfig.mTCPPortStart,  | 
					
						
							|  |  |  |                                  ooconfig.mTCPPortEnd) == OO_FAILED) { | 
					
						
							|  |  |  |          ast_log(LOG_ERROR, "h225portrange: Failed to set range\n"); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* Set aliases if any */ | 
					
						
							|  |  |  | 		for (pNewAlias = gAliasList; pNewAlias; pNewAlias = pNewAlias->next) { | 
					
						
							|  |  |  | 			switch (pNewAlias->type) { | 
					
						
							|  |  |  | 			case T_H225AliasAddress_h323_ID: | 
					
						
							|  |  |  | 				ooH323EpAddAliasH323ID(pNewAlias->value); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case T_H225AliasAddress_dialedDigits:	 | 
					
						
							|  |  |  | 				ooH323EpAddAliasDialedDigits(pNewAlias->value); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case T_H225AliasAddress_email_ID:	 | 
					
						
							|  |  |  | 				ooH323EpAddAliasEmailID(pNewAlias->value); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          default: | 
					
						
							|  |  |  |             ; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 		peer = peerl.peers; | 
					
						
							|  |  |  | 		while (peer) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          if(peer->h323id) ooH323EpAddAliasH323ID(peer->h323id); | 
					
						
							|  |  |  |          if(peer->email)  ooH323EpAddAliasEmailID(peer->email); | 
					
						
							|  |  |  |          if(peer->e164)   ooH323EpAddAliasDialedDigits(peer->e164); | 
					
						
							|  |  |  |          if(peer->url)    ooH323EpAddAliasURLID(peer->url); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			peer = peer->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (gMediaWaitForConnect) | 
					
						
							|  |  |  | 			ooH323EpEnableMediaWaitForConnect(); | 
					
						
							|  |  |  | 		else  | 
					
						
							|  |  |  | 			ooH323EpDisableMediaWaitForConnect(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Fast start and tunneling options */ | 
					
						
							|  |  |  | 		if (gFastStart) | 
					
						
							|  |  |  | 			ooH323EpEnableFastStart(); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			ooH323EpDisableFastStart(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!gTunneling) | 
					
						
							|  |  |  | 			ooH323EpDisableH245Tunneling(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (gBeMaster) | 
					
						
							|  |  |  | 			ooH323EpTryBeMaster(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       		ooH323EpEnableManualRingback(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* Gatekeeper */ | 
					
						
							|  |  |  | 		if (gRasGkMode == RasUseSpecificGatekeeper) | 
					
						
							|  |  |  | 			ooGkClientInit(gRasGkMode, gGatekeeper, 0); | 
					
						
							|  |  |  | 		else if (gRasGkMode == RasDiscoverGatekeeper) | 
					
						
							|  |  |  | 			ooGkClientInit(gRasGkMode, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Register callbacks */ | 
					
						
							|  |  |  | 		ooH323EpSetH323Callbacks(h323Callbacks); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Add endpoint capabilities */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode, gDTMFCodec) < 0) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n"); | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 		/* Create H.323 listener */ | 
					
						
							|  |  |  | 		if (ooCreateH323Listener() != OO_OK) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_log(LOG_ERROR, "OOH323 Listener Creation failure. " | 
					
						
							|  |  |  |                             "OOH323 DISABLED\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 			ooH323EpDestroy(); | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (ooh323c_start_stack_thread() < 0) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_log(LOG_ERROR, "Failed to start OOH323 stack thread. " | 
					
						
							|  |  |  |                             "OOH323 DISABLED\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ooH323EpDestroy(); | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* And start the monitor for the first time */ | 
					
						
							|  |  |  | 		restart_monitor(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *do_monitor(void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	int reloading; | 
					
						
							|  |  |  | 	struct ooh323_pvt *h323 = NULL; | 
					
						
							|  |  |  | 	time_t t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							|  |  |  | 		struct ooh323_pvt *h323_next; | 
					
						
							|  |  |  | 		/* Check for a reload request */ | 
					
						
							|  |  |  | 		ast_mutex_lock(&h323_reload_lock); | 
					
						
							|  |  |  | 		reloading = h323_reloading; | 
					
						
							|  |  |  | 		h323_reloading = 0; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&h323_reload_lock); | 
					
						
							|  |  |  | 		if (reloading) { | 
					
						
							|  |  |  | 			ast_verb(1, "Reloading H.323\n"); | 
					
						
							|  |  |  | 			ooh323_do_reload(); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* Check for interfaces needing to be killed */ | 
					
						
							|  |  |  | 		ast_mutex_lock(&iflock); | 
					
						
							|  |  |  | 		time(&t); | 
					
						
							|  |  |  | 		h323 = iflist; | 
					
						
							|  |  |  | 		while (h323) { | 
					
						
							|  |  |  | 			h323_next = h323->next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* TODO: Need to add rtptimeout keepalive support */ | 
					
						
							|  |  |  | 			if (ast_test_flag(h323, H323_NEEDDESTROY)) { | 
					
						
							|  |  |  | 				ooh323_destroy (h323); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          } /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
 | 
					
						
							|  |  |  | 	  ast_channel_lock(h323->owner); | 
					
						
							|  |  |  |           if (ast_pbx_start(h323->owner)) { | 
					
						
							|  |  |  |             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name); | 
					
						
							|  |  |  |             ast_channel_unlock(h323->owner); | 
					
						
							|  |  |  |             ast_hangup(h323->owner); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           ast_channel_unlock(h323->owner); | 
					
						
							|  |  |  | 	  ast_clear_flag(h323, H323_NEEDSTART); | 
					
						
							|  |  |  | 	 } */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			h323 = h323_next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 		pthread_testcancel(); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* Wait for sched or io */ | 
					
						
							|  |  |  | 		res = ast_sched_wait(sched); | 
					
						
							|  |  |  | 		if ((res < 0) || (res > 1000)) { | 
					
						
							|  |  |  | 			res = 1000; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		res = ast_io_wait(io, res); | 
					
						
							|  |  |  | 		pthread_testcancel(); | 
					
						
							|  |  |  | 		ast_mutex_lock(&monlock); | 
					
						
							|  |  |  | 		if (res >= 0) { | 
					
						
							|  |  |  | 			ast_sched_runq(sched); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_mutex_unlock(&monlock); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* Never reached */ | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int restart_monitor(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	pthread_attr_t attr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* If we're supposed to be stopped -- stay stopped */ | 
					
						
							|  |  |  | 	if (monitor_thread == AST_PTHREADT_STOP) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (ast_mutex_lock(&monlock)) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to lock monitor\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (monitor_thread == pthread_self()) { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&monlock); | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Cannot kill myself\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (monitor_thread != AST_PTHREADT_NULL) { | 
					
						
							|  |  |  | 		/* Wake up the thread */ | 
					
						
							|  |  |  | 		pthread_kill(monitor_thread, SIGURG); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		pthread_attr_init(&attr); | 
					
						
							|  |  |  | 		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 
					
						
							|  |  |  | 		/* Start a new monitor */ | 
					
						
							|  |  |  | 		if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&monlock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Unable to start monitor thread.\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&monlock); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ooh323_destroy(struct ooh323_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* NOTE: Assumes iflock already acquired */ | 
					
						
							|  |  |  | 	struct ooh323_pvt *prev = NULL, *cur = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	struct ooh323_user *user = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_destroy \n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p) | 
					
						
							|  |  |  | 			ast_verbose(" Destroying %s\n", p->username); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cur = iflist; | 
					
						
							|  |  |  | 	while (cur) { | 
					
						
							|  |  |  | 		if (cur == p) { break; } | 
					
						
							|  |  |  | 		prev = cur; | 
					
						
							|  |  |  | 		cur = cur->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cur) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&cur->lock); | 
					
						
							|  |  |  | 		if (prev) | 
					
						
							|  |  |  | 			prev->next = cur->next; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			iflist = cur->next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->callToken) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	 		if (gH323Debug)  | 
					
						
							|  |  |  | 				ast_verbose(" Destroying %s\n", cur->callToken); | 
					
						
							|  |  |  | 			ast_free(cur->callToken); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			cur->callToken = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->username) { | 
					
						
							|  |  |  | 			free(cur->username); | 
					
						
							|  |  |  | 			cur->username = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->host) { | 
					
						
							|  |  |  | 			free(cur->host); | 
					
						
							|  |  |  | 			cur->host = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->callerid_name) { | 
					
						
							|  |  |  | 			free(cur->callerid_name); | 
					
						
							|  |  |  | 			cur->callerid_name = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		if (cur->callerid_num) { | 
					
						
							|  |  |  | 			free(cur->callerid_num); | 
					
						
							|  |  |  | 			cur->callerid_num = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->rtp) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_rtp_instance_destroy(cur->rtp); | 
					
						
							|  |  |  | 			cur->rtp = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur->udptl) { | 
					
						
							|  |  |  | 			ast_udptl_destroy(cur->udptl); | 
					
						
							|  |  |  | 			cur->udptl = NULL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		/* Unlink us from the owner if we have one */ | 
					
						
							|  |  |  | 		if (cur->owner) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          		while(ast_channel_trylock(cur->owner)) { | 
					
						
							|  |  |  |             			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 				DEADLOCK_AVOIDANCE(&cur->lock); | 
					
						
							|  |  |  |          		}            | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			ast_debug(1, "Detaching from %s\n", cur->owner->name); | 
					
						
							|  |  |  | 			cur->owner->tech_pvt = NULL; | 
					
						
							|  |  |  | 			ast_channel_unlock(cur->owner); | 
					
						
							|  |  |  | 			cur->owner = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_module_unref(myself); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | 		if (cur->vad) { | 
					
						
							|  |  |  | 			ast_dsp_free(cur->vad); | 
					
						
							|  |  |  | 			cur->vad = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* decrement user/peer count */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if(!ast_test_flag(cur, H323_OUTGOING)) { | 
					
						
							|  |  |  | 	 if (cur->neighbor.user) { | 
					
						
							|  |  |  | 	  user = find_user(p->callerid_name, cur->neighbor.user); | 
					
						
							|  |  |  | 	  if(user && user->inUse > 0) { | 
					
						
							|  |  |  | 	  	ast_mutex_lock(&user->lock); | 
					
						
							|  |  |  | 	  	user->inUse--; | 
					
						
							|  |  |  | 	  	ast_mutex_unlock(&user->lock); | 
					
						
							|  |  |  | 	  } | 
					
						
							|  |  |  | 	  free(cur->neighbor.user); | 
					
						
							|  |  |  | 	 } | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | /* outgoing limit decrement here !!! */ | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_mutex_unlock(&cur->lock); | 
					
						
							|  |  |  | 		ast_mutex_destroy(&cur->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_free(cur); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   ooh323_destroy\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int delete_peers() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_peer *cur = NULL, *prev = NULL; | 
					
						
							|  |  |  | 	ast_mutex_lock(&peerl.lock); | 
					
						
							|  |  |  | 	cur = peerl.peers; | 
					
						
							|  |  |  | 	while (cur) { | 
					
						
							|  |  |  | 		prev = cur; | 
					
						
							|  |  |  | 		cur = cur->next; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_mutex_destroy(&prev->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       if(prev->h323id)   free(prev->h323id); | 
					
						
							|  |  |  |       if(prev->email)    free(prev->email); | 
					
						
							|  |  |  |       if(prev->url)      free(prev->url); | 
					
						
							|  |  |  |       if(prev->e164)     free(prev->e164); | 
					
						
							|  |  |  |       if(prev->rtpmask) { | 
					
						
							|  |  |  | 		ast_mutex_lock(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 		prev->rtpmask->inuse--; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 	 	if (prev->rtpmask->inuse == 0) { | 
					
						
							|  |  |  | 	  		regfree(&prev->rtpmask->regex); | 
					
						
							|  |  |  | 			ast_mutex_destroy(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 	  		free(prev->rtpmask); | 
					
						
							|  |  |  |       		} | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		free(prev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (cur == peerl.peers) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	peerl.peers = NULL; | 
					
						
							|  |  |  | 	ast_mutex_unlock(&peerl.lock); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int delete_users() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_user *cur = NULL, *prev = NULL; | 
					
						
							|  |  |  | 	ast_mutex_lock(&userl.lock); | 
					
						
							|  |  |  | 	cur = userl.users; | 
					
						
							|  |  |  | 	while (cur) { | 
					
						
							|  |  |  | 		prev = cur; | 
					
						
							|  |  |  | 		cur = cur->next; | 
					
						
							|  |  |  | 		ast_mutex_destroy(&prev->lock); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       		if(prev->rtpmask) { | 
					
						
							|  |  |  | 			ast_mutex_lock(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 			prev->rtpmask->inuse--; | 
					
						
							|  |  |  | 			ast_mutex_unlock(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 	 		if (prev->rtpmask->inuse == 0) { | 
					
						
							|  |  |  | 	  			regfree(&prev->rtpmask->regex); | 
					
						
							|  |  |  | 				ast_mutex_destroy(&prev->rtpmask->lock); | 
					
						
							|  |  |  | 	  			free(prev->rtpmask); | 
					
						
							|  |  |  |       			} | 
					
						
							|  |  |  |       		} | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		free(prev); | 
					
						
							|  |  |  | 		if (cur == userl.users) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	userl.users = NULL; | 
					
						
							|  |  |  | 	ast_mutex_unlock(&userl.lock); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | static int unload_module(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p; | 
					
						
							|  |  |  | 	struct ooAliases *cur = NULL, *prev = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("--- ooh323  unload_module \n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* First, take us out of the channel loop */ | 
					
						
							|  |  |  | 	ast_cli_unregister_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry)); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_rtp_glue_unregister(&ooh323_rtp); | 
					
						
							|  |  |  | 	ast_udptl_proto_unregister(&ooh323_udptl); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ast_channel_unregister(&ooh323_tech); | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	ast_unregister_atexit(&ast_ooh323c_exit); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("  unload_module - hanging up all interfaces\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!ast_mutex_lock(&iflock)) { | 
					
						
							|  |  |  | 		/* Hangup all interfaces if they have an owner */ | 
					
						
							|  |  |  | 		p = iflist; | 
					
						
							|  |  |  | 		while (p) { | 
					
						
							|  |  |  | 			if (p->owner) { | 
					
						
							|  |  |  | 				ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			p = p->next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		iflist = NULL; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to lock the interface list\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("  unload_module - stopping monitor thread\n"); | 
					
						
							|  |  |  | 	}   | 
					
						
							|  |  |  | 	if (monitor_thread != AST_PTHREADT_NULL) { | 
					
						
							|  |  |  | 		if (!ast_mutex_lock(&monlock)) { | 
					
						
							|  |  |  | 			if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) { | 
					
						
							|  |  |  | 				pthread_cancel(monitor_thread); | 
					
						
							|  |  |  | 				pthread_kill(monitor_thread, SIGURG); | 
					
						
							|  |  |  | 				pthread_join(monitor_thread, NULL); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			monitor_thread = AST_PTHREADT_STOP; | 
					
						
							|  |  |  | 			ast_mutex_unlock(&monlock); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to lock the monitor\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("   unload_module - stopping stack thread\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ooh323c_stop_stack_thread(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("   unload_module - freeing up memory used by interfaces\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!ast_mutex_lock(&iflock)) { | 
					
						
							|  |  |  | 		struct ooh323_pvt *pl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* Destroy all the interfaces and free their memory */ | 
					
						
							|  |  |  | 		p = iflist; | 
					
						
							|  |  |  | 		while (p) { | 
					
						
							|  |  |  | 			pl = p; | 
					
						
							|  |  |  | 			p = p->next; | 
					
						
							|  |  |  | 			/* Free associated memory */ | 
					
						
							|  |  |  | 			ooh323_destroy(pl); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		iflist = NULL; | 
					
						
							|  |  |  | 		ast_mutex_unlock(&iflock); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to lock the interface list\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("  unload_module - deleting users\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	delete_users(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("  unload_module - deleting peers\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	delete_peers(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("  unload_module - Freeing up alias list\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cur = gAliasList; | 
					
						
							|  |  |  | 	while (cur) { | 
					
						
							|  |  |  | 	  prev = cur; | 
					
						
							|  |  |  | 	  cur = cur->next; | 
					
						
							|  |  |  | 	  free(prev->value); | 
					
						
							|  |  |  | 	  free(prev); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	gAliasList = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("	unload_module- destroying OOH323 endpoint \n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ooH323EpDestroy(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) { | 
					
						
							|  |  |  | 		ast_verbose("+++ ooh323  unload_module \n");	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!(p = (struct ooh323_pvt *) chan->tech_pvt)) | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | 		return AST_RTP_GLUE_RESULT_FORBID; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!(p->rtp)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		return AST_RTP_GLUE_RESULT_FORBID; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*rtp = p->rtp ? ao2_ref(p->rtp, +1), p->rtp : NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = AST_RTP_GLUE_RESULT_LOCAL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-03 20:26:55 +00:00
										 |  |  | 	if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) { | 
					
						
							|  |  |  | 		res = AST_RTP_GLUE_RESULT_FORBID; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!(p = (struct ooh323_pvt *) chan->tech_pvt)) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		return AST_RTP_GLUE_RESULT_FORBID; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!(p->rtp)) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		return AST_RTP_GLUE_RESULT_FORBID; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	*rtp = p->vrtp ? ao2_ref(p->vrtp, +1), p->vrtp : NULL; | 
					
						
							|  |  |  | 	res = AST_RTP_GLUE_RESULT_LOCAL; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ooh323_update_capPrefsOrderForCall | 
					
						
							|  |  |  | 	(ooCallData *call, struct ast_codec_pref *prefs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i = 0; | 
					
						
							|  |  |  | 	int codec = ast_codec_pref_index(prefs, i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ooResetCapPrefs(call); | 
					
						
							|  |  |  | 	while (codec) { | 
					
						
							|  |  |  | 		ooAppendCapToCapPrefs(call, ooh323_convertAsteriskCapToH323Cap(codec)); | 
					
						
							|  |  |  | 		codec = ast_codec_pref_index(prefs, ++i); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 20:27:37 +00:00
										 |  |  | int ooh323_convertAsteriskCapToH323Cap(format_t cap) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	char formats[FORMAT_STRING_SIZE]; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	switch (cap) { | 
					
						
							|  |  |  | 	case AST_FORMAT_ULAW: | 
					
						
							|  |  |  | 		return OO_G711ULAW64K; | 
					
						
							|  |  |  | 	case AST_FORMAT_ALAW: | 
					
						
							|  |  |  | 		return OO_G711ALAW64K; | 
					
						
							|  |  |  | 	case AST_FORMAT_GSM: | 
					
						
							|  |  |  | 		return OO_GSMFULLRATE; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef AST_FORMAT_AMRNB
 | 
					
						
							|  |  |  | 	case AST_FORMAT_AMRNB: | 
					
						
							|  |  |  | 		return OO_AMRNB; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef AST_FORMAT_SPEEX
 | 
					
						
							|  |  |  | 	case AST_FORMAT_SPEEX: | 
					
						
							|  |  |  | 		return OO_SPEEX; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	case AST_FORMAT_G729A: | 
					
						
							|  |  |  | 		return OO_G729A; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	case AST_FORMAT_G726: | 
					
						
							|  |  |  | 		return OO_G726; | 
					
						
							|  |  |  | 	case AST_FORMAT_G726_AAL2: | 
					
						
							|  |  |  | 		return OO_G726AAL2; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	case AST_FORMAT_G723_1: | 
					
						
							|  |  |  | 		return OO_G7231; | 
					
						
							|  |  |  | 	case AST_FORMAT_H263: | 
					
						
							|  |  |  | 		return OO_H263VIDEO; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n",  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |                         ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 	 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* XXX Deal with Video */ | 
					
						
							|  |  |  | 	struct ooh323_pvt *p; | 
					
						
							|  |  |  | 	struct sockaddr_in them; | 
					
						
							|  |  |  | 	struct sockaddr_in us; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	struct ast_sockaddr tmp; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   ooh323_set_peer - %s\n", chan->name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!rtp) { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = (struct ooh323_pvt *) chan->tech_pvt; | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No Private Structure, this is bad\n"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	ast_rtp_instance_get_remote_address(rtp, &tmp); | 
					
						
							|  |  |  | 	ast_sockaddr_to_sin(&tmp, &them); | 
					
						
							|  |  |  | 	ast_rtp_instance_get_local_address(rtp, &tmp); | 
					
						
							|  |  |  | 	ast_sockaddr_to_sin(&tmp, &us); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct sockaddr_in us; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	struct ast_sockaddr tmp; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	ooMediaInfo mediaInfo; | 
					
						
							| 
									
										
										
										
											2009-12-01 20:27:37 +00:00
										 |  |  | 	int x; | 
					
						
							|  |  |  | 	format_t format = 0; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   configure_local_rtp\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->rtp) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs); | 
					
						
							|  |  |  | 		if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) { | 
					
						
							|  |  |  | 			ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); | 
					
						
							|  |  |  | 			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), | 
					
						
							|  |  |  | 				 p->rtp, p->dtmfcodec, "audio", "telephone-event", 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) { | 
					
						
							|  |  |  | 			ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1); | 
					
						
							|  |  |  | 			ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), | 
					
						
							|  |  |  | 				 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		/* figure out our local RTP port and tell the H.323 stack about it*/ | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 		ast_rtp_instance_get_local_address(p->rtp, &tmp); | 
					
						
							|  |  |  | 		ast_sockaddr_to_sin(&tmp, &us); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (p->rtptimeout) { | 
					
						
							|  |  |  | 			ast_rtp_instance_set_timeout(p->rtp, p->rtptimeout); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1); | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-14 14:42:59 +00:00
										 |  |  | 	if (p->rtdrcount) { | 
					
						
							|  |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 			ast_verbose("Setup RTDR info: %d, %d\n", p->rtdrinterval, p->rtdrcount); | 
					
						
							|  |  |  | 		call->rtdrInterval = p->rtdrinterval; | 
					
						
							|  |  |  | 		call->rtdrCount = p->rtdrcount; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_copy_string(mediaInfo.lMediaIP, ast_inet_ntoa(us.sin_addr), sizeof(mediaInfo.lMediaIP)); | 
					
						
							|  |  |  | 	mediaInfo.lMediaPort = ntohs(us.sin_port); | 
					
						
							|  |  |  | 	mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1; | 
					
						
							|  |  |  | 	for (x = 0; 0 != (format = ast_codec_pref_index(&p->prefs, x)); x++) { | 
					
						
							|  |  |  | 		strcpy(mediaInfo.dir, "transmit"); | 
					
						
							|  |  |  | 		mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format); | 
					
						
							|  |  |  | 		ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 		strcpy(mediaInfo.dir, "receive"); | 
					
						
							|  |  |  | 		ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 		if (mediaInfo.cap == OO_G729A) { | 
					
						
							|  |  |  | 			strcpy(mediaInfo.dir, "transmit"); | 
					
						
							|  |  |  | 			mediaInfo.cap = OO_G729; | 
					
						
							|  |  |  | 			ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 			strcpy(mediaInfo.dir, "receive"); | 
					
						
							|  |  |  | 			ooAddMediaInfo(call, mediaInfo); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			strcpy(mediaInfo.dir, "transmit"); | 
					
						
							|  |  |  | 			mediaInfo.cap = OO_G729B; | 
					
						
							|  |  |  | 			ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 			strcpy(mediaInfo.dir, "receive"); | 
					
						
							|  |  |  | 			ooAddMediaInfo(call, mediaInfo); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (p->udptl) { | 
					
						
							| 
									
										
										
										
											2010-07-23 15:52:37 +00:00
										 |  |  | 		struct ast_sockaddr us_tmp; | 
					
						
							|  |  |  | 		ast_sockaddr_from_sin(&us_tmp, &us); | 
					
						
							|  |  |  | 		ast_udptl_get_us(p->udptl, &us_tmp); | 
					
						
							|  |  |  | 		ast_sockaddr_to_sin(&us_tmp, &us); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_copy_string(mediaInfo.lMediaIP, ast_inet_ntoa(us.sin_addr), sizeof(mediaInfo.lMediaIP)); | 
					
						
							|  |  |  | 	mediaInfo.lMediaPort = ntohs(us.sin_port); | 
					
						
							|  |  |  | 	mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1; | 
					
						
							|  |  |  | 	mediaInfo.cap = OO_T38; | 
					
						
							|  |  |  | 	strcpy(mediaInfo.dir, "transmit"); | 
					
						
							|  |  |  | 	ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 	strcpy(mediaInfo.dir, "receive"); | 
					
						
							|  |  |  | 	ooAddMediaInfo(call, mediaInfo); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   configure_local_rtp\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void setup_rtp_connection(ooCallData *call, const char *remoteIp,  | 
					
						
							|  |  |  | 								  int remotePort) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct sockaddr_in them; | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	struct ast_sockaddr tmp; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_verbose("---   setup_rtp_connection %s:%d\n", remoteIp, remotePort); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Find the call or allocate a private structure if call not found */ | 
					
						
							|  |  |  | 	p = find_call(call);  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Something is wrong: rtp\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	them.sin_family = AF_INET; | 
					
						
							|  |  |  | 	them.sin_addr.s_addr = inet_addr(remoteIp); /* only works for IPv4 */ | 
					
						
							|  |  |  | 	them.sin_port = htons(remotePort); | 
					
						
							| 
									
										
										
										
											2010-07-08 23:23:17 +00:00
										 |  |  | 	ast_sockaddr_from_sin(&tmp, &them); | 
					
						
							| 
									
										
										
										
											2010-07-08 22:08:07 +00:00
										 |  |  | 	ast_rtp_instance_set_remote_address(p->rtp, &tmp); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	if (p->writeformat & AST_FORMAT_G726_AAL2)  | 
					
						
							|  |  |  |                 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2, | 
					
						
							|  |  |  | 							"audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_verbose("+++   setup_rtp_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void close_rtp_connection(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    if(gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_verbose("---   close_rtp_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |       ast_log(LOG_ERROR, "Couldn't find matching call to close rtp " | 
					
						
							|  |  |  |                          "connection\n"); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->rtp) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_rtp_instance_stop(p->rtp); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |    if(gH323Debug) | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		ast_verbose("+++   close_rtp_connection\n"); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  udptl handling functions | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p; | 
					
						
							|  |  |  | 	struct ast_udptl *udptl = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = chan->tech_pvt; | 
					
						
							|  |  |  | 	if (!p) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->udptl) | 
					
						
							|  |  |  | 		udptl = p->udptl; | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	return udptl; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = chan->tech_pvt; | 
					
						
							|  |  |  | 	if (!p) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							| 
									
										
										
										
											2010-07-23 15:52:37 +00:00
										 |  |  | 	if (udptl) { | 
					
						
							|  |  |  | 		struct ast_sockaddr udptl_addr; | 
					
						
							|  |  |  | 		ast_udptl_get_peer(udptl, &udptl_addr); | 
					
						
							|  |  |  | 		ast_sockaddr_to_sin(&udptl_addr, &p->udptlredirip); | 
					
						
							|  |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		memset(&p->udptlredirip, 0, sizeof(p->udptlredirip)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void setup_udptl_connection(ooCallData *call, const char *remoteIp,  | 
					
						
							|  |  |  | 								  int remotePort) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 	struct sockaddr_in them; | 
					
						
							| 
									
										
										
										
											2010-07-23 15:52:37 +00:00
										 |  |  | 	struct ast_sockaddr them_addr; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   setup_udptl_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Find the call or allocate a private structure if call not found */ | 
					
						
							|  |  |  | 	p = find_call(call);  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Something is wrong: rtp\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->owner) { | 
					
						
							|  |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	them.sin_family = AF_INET; | 
					
						
							|  |  |  | 	them.sin_addr.s_addr = inet_addr(remoteIp); /* only works for IPv4 */ | 
					
						
							|  |  |  | 	them.sin_port = htons(remotePort); | 
					
						
							| 
									
										
										
										
											2010-07-23 15:52:37 +00:00
										 |  |  | 	ast_sockaddr_from_sin(&them_addr, &them); | 
					
						
							|  |  |  | 	ast_udptl_set_peer(p->udptl, &them_addr); | 
					
						
							| 
									
										
										
										
											2011-03-15 01:48:25 +00:00
										 |  |  | 	ast_udptl_set_tag(p->udptl, "%s", p->owner->name); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	p->t38_tx_enable = 1; | 
					
						
							|  |  |  | 	p->lastTxT38 = time(NULL); | 
					
						
							|  |  |  | 	if (p->t38support == T38_ENABLED) { | 
					
						
							|  |  |  | 		struct ast_control_t38_parameters parameters = { .request_response = 0 }; | 
					
						
							|  |  |  | 		parameters.request_response = AST_T38_NEGOTIATED; | 
					
						
							| 
									
										
										
										
											2011-03-14 21:45:53 +00:00
										 |  |  | 		parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); | 
					
						
							|  |  |  | 		parameters.rate = AST_T38_RATE_14400; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  | 		ast_debug(1, "Receiving UDPTL  %s:%d\n", ast_inet_ntoa(them.sin_addr),  | 
					
						
							|  |  |  | 							 ntohs(them.sin_port)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_channel_unlock(p->owner); | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   setup_udptl_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void close_udptl_connection(ooCallData *call) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ooh323_pvt *p = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	if(gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("---   close_udptl_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  |       		ast_log(LOG_ERROR, "Couldn't find matching call to close udptl " | 
					
						
							|  |  |  |                          "connection\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 	if (p->owner) { | 
					
						
							|  |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p->t38_tx_enable = 0; | 
					
						
							|  |  |  | 	if (p->t38support == T38_ENABLED) { | 
					
						
							|  |  |  | 		struct ast_control_t38_parameters parameters = { .request_response = 0 }; | 
					
						
							|  |  |  | 		parameters.request_response = AST_T38_TERMINATED; | 
					
						
							|  |  |  | 		ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 	ast_channel_unlock(p->owner); | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    	if(gH323Debug) | 
					
						
							|  |  |  | 		ast_verbose("+++   close_udptl_connection\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | /* end of udptl handling */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int update_our_aliases(ooCallData *call, struct ooh323_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int updated = -1; | 
					
						
							|  |  |  | 	ooAliases *psAlias = NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	if (!call->ourAliases) | 
					
						
							|  |  |  | 		return updated; | 
					
						
							|  |  |  | 	for (psAlias = call->ourAliases; psAlias; psAlias = psAlias->next) { | 
					
						
							|  |  |  | 		if (psAlias->type == T_H225AliasAddress_h323_ID) { | 
					
						
							|  |  |  | 			ast_copy_string(p->callee_h323id, psAlias->value, sizeof(p->callee_h323id)); | 
					
						
							|  |  |  | 			updated = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (psAlias->type == T_H225AliasAddress_dialedDigits) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |          ast_copy_string(p->callee_dialedDigits, psAlias->value,  | 
					
						
							|  |  |  |                                         sizeof(p->callee_dialedDigits)); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			updated = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (psAlias->type == T_H225AliasAddress_url_ID) { | 
					
						
							|  |  |  | 			ast_copy_string(p->callee_url, psAlias->value, sizeof(p->callee_url)); | 
					
						
							|  |  |  | 			updated = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (psAlias->type == T_H225AliasAddress_email_ID) { | 
					
						
							|  |  |  | 			ast_copy_string(p->callee_email, psAlias->value, sizeof(p->callee_email)); | 
					
						
							|  |  |  | 			updated = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return updated; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Retrieve audio/etc from channel.  Assumes p->lock is already held. */ | 
					
						
							|  |  |  | 	struct ast_frame *f; | 
					
						
							|  |  |  | 	static struct ast_frame null_frame = { AST_FRAME_NULL, }; | 
					
						
							|  |  |  | 	switch (ast->fdno) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		f = ast_rtp_instance_read(p->rtp, 0);	/* RTP Audio */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		f = ast_rtp_instance_read(p->rtp, 1);	/* RTCP Control Channel */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		f = ast_rtp_instance_read(p->vrtp, 0);	/* RTP Video */ | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		f = ast_rtp_instance_read(p->vrtp, 1);	/* RTCP Control Channel for video */ | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 5: | 
					
						
							|  |  |  | 		f = ast_udptl_read(p->udptl);		/* UDPTL t.38 data */ | 
					
						
							|  |  |  | 		if (gH323Debug) ast_debug(1, "Got UDPTL %d/%d len %d for %s\n", | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 				f->frametype, f->subclass.integer, f->datalen, ast->name); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		f = &null_frame; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-02 16:19:19 +00:00
										 |  |  | 	if (f && p->owner) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 		/* We already hold the channel lock */ | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 		if (f->frametype == AST_FRAME_VOICE && !p->faxmode) { | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 			if (f->subclass.codec != p->owner->nativeformats) { | 
					
						
							|  |  |  |             			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(f->subclass.codec)); | 
					
						
							|  |  |  | 				p->owner->nativeformats = f->subclass.codec; | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				ast_set_read_format(p->owner, p->owner->readformat); | 
					
						
							|  |  |  | 				ast_set_write_format(p->owner, p->owner->writeformat); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad && | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  | 				(f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW || | 
					
						
							|  |  |  | 					f->subclass.codec == AST_FORMAT_ULAW)) { | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 				f = ast_dsp_process(p->owner, p->vad, f); | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  |             			if (f && (f->frametype == AST_FRAME_DTMF))  | 
					
						
							| 
									
										
										
										
											2009-11-04 22:22:51 +00:00
										 |  |  |                				ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer); | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | void onModeChanged(ooCallData *call, int t38mode) { | 
					
						
							|  |  |  |         struct ooh323_pvt *p; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p = find_call(call); | 
					
						
							|  |  |  | 	if (!p) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "No matching call found for %s\n", call->callToken); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&p->lock); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (gH323Debug) | 
					
						
							|  |  |  |        		ast_debug(1, "change mode to %d for %s\n", t38mode, call->callToken); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (t38mode == p->faxmode) { | 
					
						
							|  |  |  | 		if (gH323Debug) | 
					
						
							|  |  |  | 			ast_debug(1, "mode for %s is already %d\n", call->callToken, | 
					
						
							|  |  |  | 					t38mode); | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (p->owner) { | 
					
						
							|  |  |  | 		while (p->owner && ast_channel_trylock(p->owner)) { | 
					
						
							|  |  |  | 			ast_debug(1,"Failed to grab lock, trying again\n"); | 
					
						
							|  |  |  | 			DEADLOCK_AVOIDANCE(&p->lock); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (!p->owner) { | 
					
						
							|  |  |  | 			ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Channel has no owner\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (t38mode) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (p->t38support == T38_ENABLED) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* AST_T38_CONTROL mode */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			struct ast_control_t38_parameters parameters = { .request_response = 0 }; | 
					
						
							|  |  |  | 			parameters.request_response = AST_T38_REQUEST_NEGOTIATE; | 
					
						
							| 
									
										
										
										
											2011-03-14 21:45:53 +00:00
										 |  |  | 			if (call->T38FarMaxDatagram) { | 
					
						
							|  |  |  | 				ast_udptl_set_far_max_datagram(p->udptl, call->T38FarMaxDatagram); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				ast_udptl_set_far_max_datagram(p->udptl, 144); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (call->T38Version) { | 
					
						
							|  |  |  | 				parameters.version = call->T38Version; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); | 
					
						
							|  |  |  | 			parameters.rate = AST_T38_RATE_14400; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS,  | 
					
						
							|  |  |  | 							¶meters, sizeof(parameters)); | 
					
						
							|  |  |  | 			p->faxmode = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (p->t38support == T38_ENABLED) { | 
					
						
							|  |  |  | 			struct ast_control_t38_parameters parameters = { .request_response = 0 }; | 
					
						
							|  |  |  | 			parameters.request_response = AST_T38_REQUEST_TERMINATE; | 
					
						
							| 
									
										
										
										
											2011-03-14 21:45:53 +00:00
										 |  |  | 			parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); | 
					
						
							|  |  |  | 			parameters.rate = AST_T38_RATE_14400; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 			ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS,  | 
					
						
							|  |  |  | 							¶meters, sizeof(parameters)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		p->faxmode = 0; | 
					
						
							|  |  |  | 		p->t38_init = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	p->chmodepend = 0; | 
					
						
							|  |  |  | 	ast_channel_unlock(p->owner); | 
					
						
							|  |  |  | 	ast_mutex_unlock(&p->lock); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int ooh323_convert_hangupcause_asteriskToH323(int cause) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (cause) { | 
					
						
							|  |  |  | 	case AST_CAUSE_CALL_REJECTED: | 
					
						
							|  |  |  | 		return OO_REASON_REMOTE_REJECTED; | 
					
						
							|  |  |  | 	case AST_CAUSE_UNALLOCATED: | 
					
						
							|  |  |  | 		return OO_REASON_NOUSER; | 
					
						
							|  |  |  | 	case AST_CAUSE_BUSY: | 
					
						
							|  |  |  | 		return OO_REASON_REMOTE_BUSY; | 
					
						
							|  |  |  | 	case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: | 
					
						
							|  |  |  | 		return OO_REASON_NOCOMMON_CAPABILITIES; | 
					
						
							|  |  |  | 	case AST_CAUSE_CONGESTION: | 
					
						
							|  |  |  | 		return OO_REASON_REMOTE_BUSY; | 
					
						
							|  |  |  | 	case AST_CAUSE_NO_ANSWER: | 
					
						
							|  |  |  | 		return OO_REASON_REMOTE_NOANSWER; | 
					
						
							|  |  |  | 	case AST_CAUSE_NORMAL: | 
					
						
							|  |  |  | 		return OO_REASON_REMOTE_CLEARED; | 
					
						
							|  |  |  | 	case AST_CAUSE_FAILURE: | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return OO_REASON_UNKNOWN; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-11-04 22:10:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-30 16:40:38 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int ooh323_convert_hangupcause_h323ToAsterisk(int cause) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (cause) { | 
					
						
							|  |  |  | 	case OO_REASON_REMOTE_REJECTED: | 
					
						
							|  |  |  | 		return AST_CAUSE_CALL_REJECTED; | 
					
						
							|  |  |  | 	case OO_REASON_NOUSER:  | 
					
						
							|  |  |  | 		return AST_CAUSE_UNALLOCATED; | 
					
						
							|  |  |  | 	case OO_REASON_REMOTE_BUSY: | 
					
						
							|  |  |  | 	case OO_REASON_LOCAL_BUSY: | 
					
						
							|  |  |  | 		return AST_CAUSE_BUSY; | 
					
						
							|  |  |  | 	case OO_REASON_NOCOMMON_CAPABILITIES:	/* No codecs approved */ | 
					
						
							|  |  |  | 		return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; | 
					
						
							|  |  |  | 	case OO_REASON_REMOTE_CONGESTED: | 
					
						
							|  |  |  | 	case OO_REASON_LOCAL_CONGESTED: | 
					
						
							|  |  |  | 		return AST_CAUSE_CONGESTION; | 
					
						
							|  |  |  | 	case OO_REASON_REMOTE_NOANSWER: | 
					
						
							|  |  |  | 		return AST_CAUSE_NO_ANSWER; | 
					
						
							|  |  |  | 	case OO_REASON_UNKNOWN:  | 
					
						
							|  |  |  | 	case OO_REASON_INVALIDMESSAGE: | 
					
						
							|  |  |  | 	case OO_REASON_TRANSPORTFAILURE: | 
					
						
							|  |  |  | 		return AST_CAUSE_FAILURE; | 
					
						
							|  |  |  | 	case OO_REASON_REMOTE_CLEARED: | 
					
						
							|  |  |  | 		return AST_CAUSE_NORMAL; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return AST_CAUSE_NORMAL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/* Never reached */ | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | void ast_ooh323c_exit() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ooGkClientDestroy(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Objective Systems H323 Channel"); |