[asterisk-commits] branch oej/02-labarea r22162 - in /team/oej/02-labarea: ./ channels/ formats/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Apr 22 23:09:08 MST 2006


Author: oej
Date: Sun Apr 23 01:09:07 2006
New Revision: 22162

URL: http://svn.digium.com/view/asterisk?rev=22162&view=rev
Log:
Update to trunk

Modified:
    team/oej/02-labarea/   (props changed)
    team/oej/02-labarea/Makefile
    team/oej/02-labarea/channel.c
    team/oej/02-labarea/channels/chan_iax2.c
    team/oej/02-labarea/channels/chan_sip.c
    team/oej/02-labarea/formats/format_h263.c
    team/oej/02-labarea/funcs/func_odbc.c
    team/oej/02-labarea/include/asterisk/res_odbc.h
    team/oej/02-labarea/include/asterisk/translate.h
    team/oej/02-labarea/pbx.c
    team/oej/02-labarea/res/res_config_odbc.c
    team/oej/02-labarea/res/res_odbc.c
    team/oej/02-labarea/rtp.c
    team/oej/02-labarea/translate.c

Propchange: team/oej/02-labarea/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Propchange: team/oej/02-labarea/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Apr 23 01:09:07 2006
@@ -1,1 +1,1 @@
-/trunk:1-21109
+/trunk:1-21291

Modified: team/oej/02-labarea/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/Makefile?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/Makefile (original)
+++ team/oej/02-labarea/Makefile Sun Apr 23 01:09:07 2006
@@ -394,8 +394,8 @@
   SOLINK=-dynamic -bundle -undefined suppress -force_flat_namespace
   # Mac on Intel CoreDuo does not need poll compatibility layer
   ifneq ($(PROC),i386)
-    OBJS+=poll.o
-    ASTCFLAGS+=-DPOLLCOMPAT
+    #OBJS+=poll.o
+    #ASTCFLAGS+=-DPOLLCOMPAT
   endif
 else
 # These are used for all but Darwin

Modified: team/oej/02-labarea/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/channel.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/channel.c (original)
+++ team/oej/02-labarea/channel.c Sun Apr 23 01:09:07 2006
@@ -3461,10 +3461,10 @@
 			if (time_left_ms < to)
 				to = time_left_ms;
 
-			if (time_left_ms <= 0 && config->end_sound) {
-				if (caller_warning)
+			if (time_left_ms <= 0) {
+				if (caller_warning && config->end_sound)
 					bridge_playfile(c0, c1, config->end_sound, 0);
-				if (callee_warning)
+				if (callee_warning && config->end_sound)
 					bridge_playfile(c1, c0, config->end_sound, 0);
 				*fo = NULL;
 				if (who)

Modified: team/oej/02-labarea/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/channels/chan_iax2.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/channels/chan_iax2.c (original)
+++ team/oej/02-labarea/channels/chan_iax2.c Sun Apr 23 01:09:07 2006
@@ -3337,7 +3337,7 @@
 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
 {
 	struct ast_channel *cs[3];
-	struct ast_channel *who;
+	struct ast_channel *who, *other;
 	int to = -1;
 	int res = -1;
 	int transferstarted=0;
@@ -3443,49 +3443,27 @@
 			res =  AST_BRIDGE_COMPLETE;
 			break;
 		}
+		other = (who == c0) ? c1 : c0;  /* the 'other' channel */
 		if ((f->frametype == AST_FRAME_VOICE) ||
 		    (f->frametype == AST_FRAME_TEXT) ||
 		    (f->frametype == AST_FRAME_VIDEO) || 
 		    (f->frametype == AST_FRAME_IMAGE) ||
 		    (f->frametype == AST_FRAME_DTMF)) {
-			if ((f->frametype == AST_FRAME_DTMF) && 
-			    (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
-				if ((who == c0)) {
-					if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
-						*rc = c0;
-						*fo = f;
-						res = AST_BRIDGE_COMPLETE;
-						/* Remove from native mode */
-						break;
-					} else 
-						goto tackygoto;
-				} else
-				if ((who == c1)) {
-					if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
-						*rc = c1;
-						*fo = f;
-						res =  AST_BRIDGE_COMPLETE;
-						break;
-					} else
-						goto tackygoto;
-				}
-			} else {
-#if 0
-				if (iaxdebug && option_debug)
-					ast_log(LOG_DEBUG, "Read from %s\n", who->name);
-				if (who == last) 
-					ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
-				last = who;
-#endif
-tackygoto:
-				if (who == c0) 
-					ast_write(c1, f);
-				else 
-					ast_write(c0, f);
+			/* monitored dtmf take out of the bridge.
+			 * check if we monitor the specific source.
+			 */
+			int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
+			if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
+				*rc = who;
+				*fo = f;
+				res = AST_BRIDGE_COMPLETE;
+				/* Remove from native mode */
+				break;
 			}
-			ast_frfree(f);
-		} else
-			ast_frfree(f);
+			/* everything else goes to the other side */
+			ast_write(other, f);
+		}
+		ast_frfree(f);
 		/* Swap who gets priority */
 		cs[2] = cs[0];
 		cs[0] = cs[1];

Modified: team/oej/02-labarea/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/channels/chan_sip.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/channels/chan_sip.c (original)
+++ team/oej/02-labarea/channels/chan_sip.c Sun Apr 23 01:09:07 2006
@@ -256,7 +256,7 @@
 	{ CPIM_PIDF_XML,   "presence", "application/cpim-pidf+xml",   "cpim-pidf+xml" },  /* RFC 3863 */
 	{ PIDF_XML,        "presence", "application/pidf+xml",        "pidf+xml" },       /* RFC 3863 */
 	{ XPIDF_XML,       "presence", "application/xpidf+xml",       "xpidf+xml" },       /* Pre-RFC 3863 with MS additions */
-	{ MWI_NOTIFICATION,	"message-summary", "application/simple-message-summary", "mwi" } /* Mailbox notification */
+	{ MWI_NOTIFICATION,	"message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
 };
 
 enum sipmethod {
@@ -1136,6 +1136,7 @@
 /*------Response handling functions */
 static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno);
 static void handle_response_refer(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno);
+static int handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req);
 
 /*----- RTP interface functions */
 static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active);
@@ -2386,6 +2387,8 @@
 		ast_rtp_destroy(p->rtp);
 	if (p->vrtp)
 		ast_rtp_destroy(p->vrtp);
+	if (p->refer)
+		free(p->refer);
 	if (p->route) {
 		free_old_route(p->route);
 		p->route = NULL;
@@ -3164,7 +3167,8 @@
 	for (v = i->chanvars ; v ; v = v->next)
 		pbx_builtin_setvar_helper(tmp,v->name,v->value);
 
-	append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
+	if (recordhistory)
+		append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
 				
 	return tmp;
 }
@@ -4481,6 +4485,7 @@
 	}
 
 	ot = get_header(orig, "To");
+	//SKREp
 	of = get_header(orig, "From");
 
 	/* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
@@ -4792,7 +4797,7 @@
 	if ((p->vrtp) &&
 	    (!ast_test_flag(&p->flags[0], SIP_NOVIDEO)) &&
 	    (capability & VIDEO_CODEC_MASK)) /* only if video response is appropriate */
-		snprintf(b, sizeof(b), "b=CT:%d\r\n", p->maxcallbitrate);	
+		snprintf(b, sizeof(b), "b=CT:%d\r\n", p->maxcallbitrate ? p->maxcallbitrate : DEFAULT_MAX_CALL_BITRATE );	
 	snprintf(t, sizeof(t), "t=0 0\r\n");
 
 	ast_build_string(&m_audio_next, &m_audio_left, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
@@ -5509,13 +5514,17 @@
 		break;
 	case DIALOG_INFO_XML: /* SNOM subscribes in this format */
 		ast_build_string(&t, &maxbytes, "<?xml version=\"1.0\"?>\n");
-		ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
-		if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
-		else
-			ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
-		ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
-		ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
+		if (p->dialogver == 0 && state == AST_EXTENSION_NOT_INUSE ) {
+			ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"0\" state=\"full\" entity=\"%s\" />\n",  mto);
+		} else {
+			ast_build_string(&t, &maxbytes, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
+			if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
+				ast_build_string(&t, &maxbytes, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
+			else
+				ast_build_string(&t, &maxbytes, "<dialog id=\"%s\">\n", p->exten);
+			ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
+			ast_build_string(&t, &maxbytes, "</dialog>\n</dialog-info>\n");
+		}
 		break;
 	case NONE:
 	default:
@@ -5579,20 +5588,26 @@
 	return send_request(p, req, 0, p->ocseq);
 }
 
-/*! \brief Notify a transferring party of the status of transfer
- */
-static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message)
+/*! \brief Notify a transferring party of the status of transfer */
+static int transmit_notify_with_sipfrag(struct sip_pvt *p, int cseq, char *message, int terminate)
 {
 	struct sip_request req;
-	char tmp[50];
+	char tmp[BUFSIZ/2];
+
 
 	reqprep(&req, p, SIP_NOTIFY, 0, TRUE);
 	snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
 	add_header(&req, "Event", tmp);
-	add_header(&req, "Subscription-state", "terminated;reason=noresource");
+	if (terminate)
+		add_header(&req, "Subscription-state", "terminated;reason=noresource");
 	add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
 	add_header(&req, "Allow", ALLOWED_METHODS);
 	add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
+
+	snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
+	add_header_contentLength(&req, strlen(tmp));
+	add_line(&req, tmp);
+
 
 	snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
 	add_header_contentLength(&req, strlen(tmp));
@@ -5902,8 +5917,8 @@
 
 /*! \brief Allocate SIP refer structure */
 int sip_refer_allocate(struct sip_pvt *p) {
-   p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
-   return p->refer ? 1 : 0;
+	p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
+	return p->refer ? 1 : 0;
 }
 
 /*! \brief Transmit SIP REFER message */
@@ -5914,12 +5929,23 @@
 	const char *of;
 	char *c;
 	char referto[256];
-
-	/* Are we transfering an inbound or outbound call? */
-	if (ast_test_flag(&p->flags[0], SIP_OUTGOING))
+	char *ttag, *ftag;
+	char *theirtag = ast_strdupa(p->theirtag);
+
+	if (option_debug || sipdebug)
+		ast_log(LOG_DEBUG, "SIP transfer of %s to %s\n", p->callid, dest);
+
+	/* Are we transfering an inbound or outbound call ? */
+	if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
 		of = get_header(&p->initreq, "To");
-	else
+		ttag = theirtag;
+		ftag = p->tag;
+	} else {
 		of = get_header(&p->initreq, "From");
+		ftag = theirtag;
+		ttag = p->tag;
+	}
+
 	ast_copy_string(from, of, sizeof(from));
 	of = get_in_brackets(from);
 	ast_string_field_set(p, from, of);
@@ -5932,17 +5958,18 @@
 		c = NULL;
 	else if ((c = strchr(of, '@')))
 		*c++ = '\0';
-	if (c) {
+	if (c) 
 		snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
-	} else {
+	else
 		snprintf(referto, sizeof(referto), "<sip:%s>", dest);
-	}
 
 	add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
 
 	/* save in case we get 407 challenge */
-	ast_string_field_set(p, refer_to, referto);
-	ast_string_field_set(p, referred_by, p->our_contact);
+	sip_refer_allocate(p);
+	ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
+	ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
+	p->refer->status = REFER_SENT;   /* Set refer status */
 
 	reqprep(&req, p, SIP_REFER, 0, TRUE);
 	add_header(&req, "Refer-To", referto);
@@ -5951,7 +5978,10 @@
 	if (!ast_strlen_zero(p->our_contact))
 		add_header(&req, "Referred-By", p->our_contact);
 	add_blank_header(&req);
+
 	return send_request(p, &req, 1, p->ocseq);
+	/* We should propably wait for a NOTIFY here until we ack the transfer */
+	/* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
 
 	/*! \todo In theory, we should hang around and wait for a reply, before
 	returning to the dial plan here. Don't know really how that would
@@ -5959,6 +5989,7 @@
 	useful we should have a STATUS code on transfer().
 	*/
 }
+
 
 /*! \brief Send SIP INFO dtmf message, see Cisco documentation on cisco.com */
 static int transmit_info_with_digit(struct sip_pvt *p, char digit)
@@ -7332,7 +7363,7 @@
 	int res = 0;
 	char *t;
 	char calleridname[50];
-	int debug=sip_debug_test_addr(sin);
+	int debug = sip_debug_test_addr(sin);
 	struct ast_variable *tmpvar = NULL, *v = NULL;
 	int usenatroute;
 
@@ -7474,6 +7505,8 @@
 			p->capability = user->capability;
 			p->jointcapability = user->capability;
 			p->maxcallbitrate = user->maxcallbitrate;
+			if (option_debug > 2)
+				ast_log(LOG_DEBUG, "User maxcallbitrate used : %d\n", user->maxcallbitrate);
 			if (!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
 				ast_rtp_destroy(p->vrtp);
 				p->vrtp = NULL;
@@ -7608,6 +7641,8 @@
 				if (p->peercapability)
 					p->jointcapability &= p->peercapability;
 				p->maxcallbitrate = peer->maxcallbitrate;
+				if (option_debug > 2)
+					ast_log(LOG_DEBUG, "Peer maxcallbitrate used : %d\n", peer->maxcallbitrate);
 				if (!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && p->vrtp) {
 					ast_rtp_destroy(p->vrtp);
 					p->vrtp = NULL;
@@ -8750,10 +8785,12 @@
 {
 #define FORMAT3 "%-15.15s  %-10.10s  %-11.11s  %-15.15s  %-13.13s  %-15.15s %-10.10s\n"
 #define FORMAT2 "%-15.15s  %-10.10s  %-11.11s  %-11.11s  %-4.4s  %-7.7s  %-15.15s\n"
-#define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s\n"
+#define FORMAT  "%-15.15s  %-10.10s  %-11.11s  %5.5d/%5.5d  %-4.4s  %-3.3s %-3.3s  %-15.15s %-10.10s\n"
 	struct sip_pvt *cur;
 	char iabuf[INET_ADDRSTRLEN];
 	int numchans = 0;
+	char *referstatus = NULL;
+
 	if (argc != 3)
 		return RESULT_SHOWUSAGE;
 	ast_mutex_lock(&iflock);
@@ -8763,6 +8800,10 @@
 	else 
 		ast_cli(fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox");
 	for (; cur; cur = cur->next) {
+		referstatus = "";
+		if (cur->refer) { /* SIP transfer in progress */
+			referstatus = referstatus2str(cur->refer->status);
+		}
 		if (cur->subscribed == NONE && !subscriptions) {
 			ast_cli(fd, FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), 
 				S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
@@ -8771,7 +8812,9 @@
 				ast_getformatname(cur->owner ? cur->owner->nativeformats : 0), 
 				ast_test_flag(&cur->flags[0], SIP_CALL_ONHOLD) ? "Yes" : "No",
 				ast_test_flag(&cur->flags[0], SIP_NEEDDESTROY) ? "(d)" : "",
-				cur->lastmsg );
+				cur->lastmsg ,
+				referstatus
+			);
 			numchans++;
 		}
 		if (cur->subscribed != NONE && subscriptions) {
@@ -8932,7 +8975,7 @@
 static int sip_show_channel(int fd, int argc, char *argv[])
 {
 	struct sip_pvt *cur;
-	char iabuf[INET_ADDRSTRLEN];
+	char iabuf[BUFSIZ];
 	size_t len;
 	int found = 0;
 
@@ -8953,7 +8996,7 @@
 			ast_cli(fd, "  Non-Codec Capability:   %d\n", cur->noncodeccapability);
 			ast_cli(fd, "  Their Codec Capability:   %d\n", cur->peercapability);
 			ast_cli(fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
-			ast_cli(fd, "  Format                  %s\n", ast_getformatname(cur->owner ? cur->owner->nativeformats : 0) );
+			ast_cli(fd, "  Format                  %s\n", ast_getformatname_multiple(iabuf, sizeof(iabuf), cur->owner ? cur->owner->nativeformats : 0) );
 			ast_cli(fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->sa.sin_addr), ntohs(cur->sa.sin_port));
 			ast_cli(fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), cur->recv.sin_addr), ntohs(cur->recv.sin_port));
 			ast_cli(fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
@@ -10220,7 +10263,7 @@
 }
 
 /*! \brief Handle qualification responses (OPTIONS) */
-static int handle_response_peerpoke(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno, int sipmethod)
+static int handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
 {
 	struct sip_peer *peer;
 	int pingtime;
@@ -10262,8 +10305,6 @@
 
 		if (peer->pokeexpire > -1)
 			ast_sched_del(sched, peer->pokeexpire);
-		if (sipmethod == SIP_INVITE)	/* Does this really happen? */
-			transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
 		ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
 
 		/* Try again eventually */
@@ -10314,7 +10355,7 @@
 		   Well, as long as it's not a 100 response...  since we might
 		   need to hang around for something more "definitive" */
 
-		res = handle_response_peerpoke(p, resp, rest, req, ignore, seqno, sipmethod);
+		res = handle_response_peerpoke(p, resp, req);
 	} else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 		switch(resp) {
 		case 100:	/* 100 Trying */
@@ -10334,6 +10375,8 @@
 			if (sipmethod == SIP_MESSAGE) {
 				/* We successfully transmitted a message */
 				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
+			} else if (sipmethod == SIP_INVITE) {
+				handle_response_invite(p, resp, rest, req, seqno);
 			} else if (sipmethod == SIP_NOTIFY) {
 				/* They got the notify, this is the end */
 				if (p->owner) {
@@ -10344,9 +10387,7 @@
 						ast_set_flag(&p->flags[0], SIP_NEEDDESTROY); 
 					}
 				}
-			} else if (sipmethod == SIP_INVITE)
-				handle_response_invite(p, resp, rest, req, seqno);
-			else if (sipmethod == SIP_REGISTER)
+			} else if (sipmethod == SIP_REGISTER)
 				res = handle_response_register(p, resp, rest, req, ignore, seqno);
 			break;
 		case 202:   /* Transfer accepted */
@@ -10402,6 +10443,35 @@
 			} else	/* We can't handle this, giving up in a bad way */
 				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);	
 
+			break;
+		case 481: /* Call leg does not exist */
+			if (sipmethod == SIP_INVITE) {
+				/* First we ACK */
+				transmit_request(p, SIP_ACK, seqno, 0, 0);
+					ast_log(LOG_WARNING, "INVITE with REPLACEs failed to '%s'\n", get_header(&p->initreq, "From"));
+				if (owner)
+					ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+				sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
+			} else if (sipmethod == SIP_REFER) {
+				/* A transfer with Replaces did not work */
+				/* OEJ: We should Set flag, cancel the REFER, go back
+				to original call - but right now we can't */
+				ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
+				if (owner)
+					ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+			} else if (sipmethod == SIP_BYE) {
+				/* The other side has no transaction to bye,
+				just assume it's all right then */
+				ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
+			} else if (sipmethod == SIP_CANCEL) {
+				/* The other side has no transaction to cancel,
+				just assume it's all right then */
+				ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
+			} else {
+				ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
+				/* Guessing that this is not an important request */
+			}
 			break;
 		case 491: /* Pending */
 			if (sipmethod == SIP_INVITE)
@@ -10603,85 +10673,124 @@
 /*! \brief Park SIP call support function */
 static void *sip_park_thread(void *stuff)
 {
-	struct ast_channel *chan1, *chan2;
+	struct ast_channel *transferee, *transferer;	/* Chan1: The transferee, Chan2: The transferer */
 	struct sip_dual *d;
 	struct sip_request req;
 	int ext;
 	int res;
+
 	d = stuff;
-	chan1 = d->chan1;
-	chan2 = d->chan2;
+	transferee = d->chan1;
+	transferer = d->chan2;
 	copy_request(&req, &d->req);
 	free(d);
-	ast_channel_lock(chan1);
-	ast_do_masquerade(chan1);
-	ast_channel_unlock(chan1);
-	res = ast_park_call(chan1, chan2, 0, &ext);
-	/* Then hangup */
-	ast_hangup(chan2);
-	if (option_debug > 1)
-		ast_log(LOG_DEBUG, "Parked on extension '%d'\n", ext);
+	ast_channel_lock(transferee);
+	if (ast_do_masquerade(transferee)) {
+		ast_log(LOG_WARNING, "Masquerade failed.\n");
+		transmit_response(transferer->tech_pvt, "503 Internal error", &req);
+		ast_channel_unlock(transferee);
+		return NULL;
+	} 
+	ast_channel_unlock(transferee);
+
+	res = ast_park_call(transferee, transferer, 0, &ext);
+
+#ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
+	if (!res) {
+		transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
+	} else {
+		/* Then tell the transferer what happened */
+		sprintf(buf, "Call parked on extension '%d'", ext);
+		transmit_message_with_text(transferer->tech_pvt, buf);
+	}
+#endif
+
+	/* Any way back to the current call??? */
+	transmit_response(transferer->tech_pvt, "202 Accepted", &req);
+	if (!res)	{
+		/* Transfer succeeded */
+		transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", 1);
+		transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
+		ast_hangup(transferer); /* This will cause a BYE */
+		if (option_debug)
+			ast_log(LOG_DEBUG, "SIP Call parked on extension '%d'\n", ext);
+	} else {
+		transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", 1);
+		if (option_debug)
+			ast_log(LOG_DEBUG, "SIP Call parked failed \n");
+		/* Do not hangup call */
+	}
 	return NULL;
 }
 
 /*! \brief Park a call */
-static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req)
+static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 {
 	struct sip_dual *d;
-	struct ast_channel *chan1m, *chan2m;
+	struct ast_channel *transferee, *transferer;
+		/* Chan2m: The transferer, chan1m: The transferee */
 	pthread_t th;
-	chan1m = ast_channel_alloc(0);
-	chan2m = ast_channel_alloc(0);
-	if ((!chan2m) || (!chan1m)) {
-		if (chan1m) {
-			chan1m->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
-			ast_hangup(chan1m);
-		}
-		if (chan2m) {
-			chan2m->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
-			ast_hangup(chan2m);
+
+	transferee = ast_channel_alloc(0);
+	transferer = ast_channel_alloc(0);
+	if ((!transferer) || (!transferee)) {
+		if (transferee) {
+			transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+			ast_hangup(transferee);
+		}
+		if (transferer) {
+			transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+			ast_hangup(transferer);
 		}
 		return -1;
 	}
-	ast_string_field_build(chan1m, name, "Parking/%s", chan1->name);
+	ast_string_field_build(transferee, name,  "Parking/%s", chan1->name);
+
 	/* Make formats okay */
-	chan1m->readformat = chan1->readformat;
-	chan1m->writeformat = chan1->writeformat;
-	ast_channel_masquerade(chan1m, chan1);
+	transferee->readformat = chan1->readformat;
+	transferee->writeformat = chan1->writeformat;
+	ast_channel_masquerade(transferee, chan1);
+
 	/* Setup the extensions and such */
-	ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
-	ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
-	chan1m->priority = chan1->priority;
+	ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
+	ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
+	transferee->priority = chan1->priority;
 		
 	/* We make a clone of the peer channel too, so we can play
 	   back the announcement */
-	ast_string_field_build(chan2m, name, "SIPPeer/%s",chan2->name);
+	ast_string_field_build(transferer, name, "SIPPeer/%s", chan2->name);
+
 	/* Make formats okay */
-	chan2m->readformat = chan2->readformat;
-	chan2m->writeformat = chan2->writeformat;
-	ast_channel_masquerade(chan2m, chan2);
+	transferer->readformat = chan2->readformat;
+	transferer->writeformat = chan2->writeformat;
+	ast_channel_masquerade(transferer, chan2);
+
 	/* Setup the extensions and such */
-	ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
-	ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
-	chan2m->priority = chan2->priority;
-	ast_channel_lock(chan2m);
-	if (ast_do_masquerade(chan2m)) {
+	ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
+	ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
+	transferer->priority = chan2->priority;
+
+	ast_channel_lock(transferer);
+	if (ast_do_masquerade(transferer)) {
 		ast_log(LOG_WARNING, "Masquerade failed :(\n");
-		ast_channel_unlock(chan2m);
-		chan2m->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
-		ast_hangup(chan2m);
+		ast_channel_unlock(transferer);
+		transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
+		ast_hangup(transferer);
 		return -1;
 	}
-	ast_channel_unlock(chan2m);
+	ast_channel_unlock(transferer);
 	if ((d = ast_calloc(1, sizeof(*d)))) {
 		/* Save original request for followup */
 		copy_request(&d->req, req);
-		d->chan1 = chan1m;
-		d->chan2 = chan2m;
-		if (!ast_pthread_create(&th, NULL, sip_park_thread, d))
+		d->chan1 = transferee;	/* Transferee */
+		d->chan2 = transferer;	/* Transferer */
+		d->seqno = seqno;
+		if (!ast_pthread_create(&th, NULL, sip_park_thread, d)) {
+			free(d);
 			return 0;
+		}
 		free(d);
-	}
+	} 
 	return -1;
 }
 
@@ -10785,7 +10894,7 @@
 	}
 	if (!ast_strlen_zero(thetag))
 		ast_copy_string(tagbuf, thetag, tagbufsize);
-	return tagbuf;	
+	return tagbuf;
 }
 
 /*! \brief Handle incoming notifications */
@@ -11284,7 +11393,7 @@
 							    be accessible after the transfer! */
 							*nounlock = 1;
 							ast_channel_unlock(c);
-							sip_park(transfer_to, c, req);
+							sip_park(transfer_to, c, req, seqno);
 							nobye = 1;
 						} else {
 							/* Must release c's lock now, because it will not longer
@@ -11301,7 +11410,7 @@
 				ast_set_flag(&p->flags[0], SIP_GOTREFER);	
 			}
 			transmit_response(p, "202 Accepted", req);
-			transmit_notify_with_sipfrag(p, seqno, "200 OK");
+			transmit_notify_with_sipfrag(p, seqno, "200 OK", 1);
 			/* Always increment on a BYE */
 			if (!nobye) {
 				/*! \note XXX Should this really be a new branch?? */
@@ -11795,13 +11904,40 @@
 			if ((s = strchr(tag, ';')))
 				*s = '\0';
 			tag += 8;
-			ast_log(LOG_DEBUG, "### Comparing our branch %s with request branch %s\n", p->viabranchtag, tag);
+			ast_log(LOG_DEBUG, "### Comparing our branch %s with request branch %s\n", p->ourbranch, tag);
 				
 		}
 		ok = TRUE;
 		//SKREP
 		ast_log(LOG_DEBUG, "**** Our initial VIA %s - This req VIA %s\n", p->initreq.via, req->via);
 		//if (strcasecmp(p->viabranchtag, ???? )
+		if (strcasecmp(p->ourbranch, tag)) {	/* Compare the branch tags */
+			struct sip_pvt *newbranch;
+			/* This is NOT our call, it is a new branch */
+			ast_log(LOG_DEBUG, "**** THIS IS A NEW CALL!!!!!\n");
+#ifdef SKREPOLLE
+			if (0 &&(newbranch = sip_alloc(req->callid, &p->sa, 1, SIP_INVITE))) {	/* Allocate new call */
+				ast_log(LOG_DEBUG, "**** Created new PVT !!!!!\n");
+				ast_mutex_lock(&newbranch->lock);		/* Lock this new PVT while we are in action */
+				find_via_branch(newbranch, req);		/* Find the branch and store it */
+				append_history(p, "NewBranch", "Forking to another sip_pvt Our branch tag: %s\n", p->ourbranch);
+				ast_mutex_unlock(&p->lock);			/* Unlock this PVT - we're done */
+				p = newbranch;					/* Quickly move to the new pvt 												  and leave the old one alone */
+
+				append_history(p, "NewBranch", "Creation caused by branch tag: %s\n", p->ourbranch);
+				ignore = 0;
+				ast_clear_flag(req, SIP_PKT_IGNORE);
+				ast_clear_flag(req, SIP_PKT_IGNORE_REQ);
+			} else {
+				/* We could not allocate new call */
+				transmit_response(p, "503 Internal error", req);
+				ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+				return -1; 	/* Failure to handle this call */
+			}
+#endif
+		
+		}
+		
 	} else {
 		//SKREP
 		if (req->method == SIP_INVITE)
@@ -12333,8 +12469,6 @@
 	if ((tmp = strchr(host, '@')))
 		host = tmp + 1;
 
-	if (option_debug > 2) 
-		ast_log(LOG_DEBUG, "Checking device state for peer %s\n", host);
 
 	if ((p = find_peer(host, NULL, 1))) {
 		if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
@@ -12362,6 +12496,8 @@
 		if (hp)
 			res = AST_DEVICE_UNKNOWN;
 	}
+	if (option_debug > 2) 
+		ast_log(LOG_DEBUG, "Checking device state for peer %s - state %d %s\n", host, res, devstate2str(res));
 
 	return res;
 }

Modified: team/oej/02-labarea/formats/format_h263.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/formats/format_h263.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/formats/format_h263.c (original)
+++ team/oej/02-labarea/formats/format_h263.c Sun Apr 23 01:09:07 2006
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster at digium.com>
  *

Modified: team/oej/02-labarea/funcs/func_odbc.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/funcs/func_odbc.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/funcs/func_odbc.c (original)
+++ team/oej/02-labarea/funcs/func_odbc.c Sun Apr 23 01:09:07 2006
@@ -77,7 +77,7 @@
  */
 static int acf_odbc_write(struct ast_channel *chan, char *cmd, char *s, const char *value)
 {
-	odbc_obj *obj;
+	struct odbc_obj *obj;
 	struct acf_odbc_query *query;
 	char *t, *arg, buf[2048]="", varname[15];
 	int res, argcount=0, valcount=0, i, retry=0;
@@ -104,10 +104,10 @@
 		return -1;
 	}
 
-	obj = fetch_odbc_obj(query->dsn, 0);
+	obj = odbc_request_obj(query->dsn, 0);
 
 	if (!obj) {
-		ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
+		ast_log(LOG_ERROR, "No such DSN registered (or out of connections): %s (check res_odbc.conf)\n", query->dsn);
 		ast_mutex_unlock(&query_lock);
 		return -1;
 	}
@@ -204,9 +204,9 @@
 			}
 		}
 		SQLFreeHandle(SQL_HANDLE_STMT, stmt);
-		odbc_obj_disconnect(obj);
+		odbc_release_obj(obj);
 		/* All handles are now invalid (after a disconnect), so we gotta redo all handles */
-		odbc_obj_connect(obj);
+		obj = odbc_request_obj("asterisk", 1);
 		if (!retry) {
 			retry = 1;
 			goto retry_write;
@@ -235,7 +235,7 @@
 
 static int acf_odbc_read(struct ast_channel *chan, char *cmd, char *s, char *buf, size_t len)
 {
-	odbc_obj *obj;
+	struct odbc_obj *obj;
 	struct acf_odbc_query *query;
 	char *arg, sql[2048] = "", varname[15];
 	int count=0, res, x;
@@ -260,10 +260,10 @@
 		return -1;
 	}
 
-	obj = fetch_odbc_obj(query->dsn, 0);
+	obj = odbc_request_obj(query->dsn, 0);
 
 	if (!obj) {
-		ast_log(LOG_ERROR, "No such DSN registered: %s (check res_odbc.conf)\n", query->dsn);
+		ast_log(LOG_ERROR, "No such DSN registered (or out of connections): %s (check res_odbc.conf)\n", query->dsn);
 		ast_mutex_unlock(&query_lock);
 		return -1;
 	}
@@ -331,7 +331,7 @@
 		goto acf_out;
 	}
 
-	for (x=0; x<colcount; x++) {
+	for (x = 0; x < colcount; x++) {
 		int buflen, coldatalen;
 		char coldata[256];
 

Modified: team/oej/02-labarea/include/asterisk/res_odbc.h
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/include/asterisk/res_odbc.h?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/include/asterisk/res_odbc.h (original)
+++ team/oej/02-labarea/include/asterisk/res_odbc.h Sun Apr 23 01:09:07 2006
@@ -3,9 +3,11 @@
  *
  * Copyright (C) 1999 - 2005, Digium, Inc.
  * Copyright (C) 2004 - 2005, Anthony Minessale II
+ * Copyright (C) 2006, Tilghman Lesher
  *
  * Mark Spencer <markster at digium.com>
  * Anthony Minessale <anthmct at yahoo.com>
+ * Tilghman Lesher <res_odbc_200603 at the-tilghman.com>
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -29,34 +31,66 @@
 #include <sqlext.h>
 #include <sqltypes.h>
 
-typedef struct odbc_obj odbc_obj;
-
-typedef enum { ODBC_SUCCESS=0,ODBC_FAIL=-1} odbc_status;
+typedef enum { ODBC_SUCCESS=0, ODBC_FAIL=-1} odbc_status;
 
 struct odbc_obj {
-	char *name;
-	char *dsn;
-	char *username;
-	char *password;
-	SQLHENV  env;                   /* ODBC Environment */
+	ast_mutex_t lock;
 	SQLHDBC  con;                   /* ODBC Connection Handle */
-	SQLHSTMT stmt;                  /* ODBC Statement Handle */
-	ast_mutex_t lock;
-	int up;
-
+	struct odbc_class *parent;      /* Information about the connection is protected */
+	unsigned int used:1;
+	unsigned int up:1;
+	AST_LIST_ENTRY(odbc_obj) list;
 };
 
 /* functions */
-odbc_obj *new_odbc_obj(char *name,char *dsn,char *username, char *password);
-odbc_status odbc_obj_connect(odbc_obj *obj);
-odbc_status odbc_obj_disconnect(odbc_obj *obj);
-void destroy_odbc_obj(odbc_obj **obj);
-int register_odbc_obj(char *name,odbc_obj *obj);
-odbc_obj *fetch_odbc_obj(const char *name, int check);
-int odbc_dump_fd(int fd,odbc_obj *obj);
-int odbc_sanity_check(odbc_obj *obj);
-SQLHSTMT odbc_prepare_and_execute(odbc_obj *obj, SQLHSTMT (*prepare_cb)(odbc_obj *obj, void *data), void *data);
-int odbc_smart_execute(odbc_obj *obj, SQLHSTMT stmt);
-int odbc_smart_direct_execute(odbc_obj *obj, SQLHSTMT stmt, char *sql);
+
+/*! \brief Executes a prepared statement handle
+ * \param obj The non-NULL result of odbc_request_obj()
+ * \param stmt The prepared statement handle
+ * \return Returns 0 on success or -1 on failure
+ *
+ * This function was originally designed simply to execute a prepared
+ * statement handle and to retry if the initial execution failed.
+ * Unfortunately, it did this by disconnecting and reconnecting the database
+ * handle which on most databases causes the statement handle to become
+ * invalid.  Therefore, this method has been deprecated in favor of
+ * odbc_prepare_and_execute() which allows the statement to be prepared
+ * multiple times, if necessary, in case of a loss of connection.
+ *
+ * This function really only ever worked with MySQL, where the statement handle is
+ * not prepared on the server.  If you are not using MySQL, you should avoid it.
+ */
+int odbc_smart_execute(struct odbc_obj *obj, SQLHSTMT stmt); /* DEPRECATED */
+
+/*! \brief Retrieves a connected ODBC object
+ * \param name The name of the ODBC class for which a connection is needed.
+ * \param check Whether to ensure that a connection is valid before returning the handle.  Usually unnecessary.
+ * \return Returns an ODBC object or NULL if there is no connection available with the requested name.
+ *
+ * Connection classes may, in fact, contain multiple connection handles.  If
+ * the connection is pooled, then each connection will be dedicated to the
+ * thread which requests it.  Note that all connections should be released
+ * when the thread is done by calling odbc_release_obj(), below.
+ */
+struct odbc_obj *odbc_request_obj(const char *name, int check);
+
+/*! \brief Releases an ODBC object previously allocated by odbc_request_obj()
+ * \param obj The ODBC object
+ */
+void odbc_release_obj(struct odbc_obj *obj);
+
+/*! \brief Checks an ODBC object to ensure it is still connected
+ * \param obj The ODBC object
+ * \return Returns 0 if connected, -1 otherwise.
+ */
+int odbc_sanity_check(struct odbc_obj *obj);
+
+/*! \brief Prepares, executes, and returns the resulting statement handle.
+ * \param obj The ODBC object
+ * \param prepare_cb A function callback, which, when called, should return a statement handle prepared, with any necessary parameters or result columns bound.
+ * \param data A parameter to be passed to the prepare_cb parameter function, indicating which statement handle is to be prepared.
+ * \return Returns a statement handle or NULL on error.
+ */
+SQLHSTMT odbc_prepare_and_execute(struct odbc_obj *obj, SQLHSTMT (*prepare_cb)(struct odbc_obj *obj, void *data), void *data);
 
 #endif /* _ASTERISK_RES_ODBC_H */

Modified: team/oej/02-labarea/include/asterisk/translate.h
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/include/asterisk/translate.h?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/include/asterisk/translate.h (original)
+++ team/oej/02-labarea/include/asterisk/translate.h Sun Apr 23 01:09:07 2006
@@ -65,8 +65,10 @@
  */
 struct ast_translator {
 	const char name[80];		/*! Name of translator */
-	int srcfmt;			/*! Source format (note: bit position) */
-	int dstfmt;			/*! Destination format (note: bit position) */
+	int srcfmt;			/*! Source format (note: bit position,
+					  converted to index during registration) */
+	int dstfmt;			/*! Destination format (note: bit position,
+					  converted to index during registration) */
 
 	/*! initialize private data associated with the translator */
 	void *(*newpvt)(struct ast_trans_pvt *);

Modified: team/oej/02-labarea/pbx.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/pbx.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/pbx.c (original)
+++ team/oej/02-labarea/pbx.c Sun Apr 23 01:09:07 2006
@@ -1343,9 +1343,10 @@
 			needsub = 0;
 
 			/* Find the end of it */
-			while(brackets && *vare) {
+			while (brackets && *vare) {
 				if ((vare[0] == '$') && (vare[1] == '{')) {
 					needsub++;
+				} else if (vare[0] == '{') {
 					brackets++;
 				} else if (vare[0] == '}') {
 					brackets--;

Modified: team/oej/02-labarea/res/res_config_odbc.c
URL: http://svn.digium.com/view/asterisk/team/oej/02-labarea/res/res_config_odbc.c?rev=22162&r1=22161&r2=22162&view=diff
==============================================================================
--- team/oej/02-labarea/res/res_config_odbc.c (original)
+++ team/oej/02-labarea/res/res_config_odbc.c Sun Apr 23 01:09:07 2006
@@ -52,7 +52,7 @@
 
 static struct ast_variable *realtime_odbc(const char *database, const char *table, va_list ap)
 {
-	odbc_obj *obj;
+	struct odbc_obj *obj;
 	SQLHSTMT stmt;
 	char sql[1024];
 	char coltitle[256];
@@ -79,19 +79,21 @@
 	if (!table)
 		return NULL;
 
-	obj = fetch_odbc_obj(database, 0);
+	obj = odbc_request_obj(database, 0);
 	if (!obj)
 		return NULL;
 
 	res = SQLAllocHandle (SQL_HANDLE_STMT, obj->con, &stmt);
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 		ast_log(LOG_WARNING, "SQL Alloc Handle failed!\n");
+		odbc_release_obj(obj);
 		return NULL;
 	}
 
 	newparam = va_arg(aq, const char *);
 	if (!newparam)  {
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+		odbc_release_obj(obj);
 		return NULL;
 	}
 	newval = va_arg(aq, const char *);
@@ -107,6 +109,7 @@
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
 		ast_log(LOG_WARNING, "SQL Prepare failed![%s]\n", sql);
 		SQLFreeHandle (SQL_HANDLE_STMT, stmt);
+		odbc_release_obj(obj);
 		return NULL;
 	}
 	
@@ -123,6 +126,7 @@
 	if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {

[... 1375 lines stripped ...]


More information about the asterisk-commits mailing list