[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