[Asterisk-cvs] asterisk/channels chan_sip.c,1.510.2.11,1.510.2.12
russell at lists.digium.com
russell at lists.digium.com
Tue Nov 2 07:53:45 CST 2004
Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv27455/channels
Modified Files:
Tag: v1-0
chan_sip.c
Log Message:
prevent seg fault with attempt_transfer (bug #2741)
Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.510.2.11
retrieving revision 1.510.2.12
diff -u -d -r1.510.2.11 -r1.510.2.12
--- chan_sip.c 25 Oct 2004 17:57:25 -0000 1.510.2.11
+++ chan_sip.c 2 Nov 2004 12:56:15 -0000 1.510.2.12
@@ -7007,54 +7007,69 @@
return -1;
}
+static void ast_quiet_chan(struct ast_channel *chan) {
+ if(chan && chan->_state == AST_STATE_UP) {
+ if(chan->generatordata)
+ ast_deactivate_generator(chan);
+ }
+}
/*--- attempt_transfer: Attempt transfer of SIP call ---*/
static int attempt_transfer(struct sip_pvt *p1, struct sip_pvt *p2)
{
+ int res = 0;
+ struct ast_channel
+ *chana = NULL,
+ *chanb = NULL,
+ *bridgea = NULL,
+ *bridgeb = NULL,
+ *peera = NULL,
+ *peerb = NULL,
+ *peerc = NULL;
+
if (!p1->owner || !p2->owner) {
ast_log(LOG_WARNING, "Transfer attempted without dual ownership?\n");
return -1;
}
- if (p1->owner->bridge) {
- if (p2->owner->bridge)
- ast_moh_stop(p2->owner->bridge);
- ast_moh_stop(p1->owner->bridge);
- ast_moh_stop(p1->owner);
- ast_moh_stop(p2->owner);
- if (p1->owner->cdr) {
- p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->cdr);
- p1->owner->cdr = NULL;
- }
- if (p1->owner->bridge->cdr) {
- p2->owner->cdr = ast_cdr_append(p2->owner->cdr, p1->owner->bridge->cdr);
- p1->owner->bridge->cdr = NULL;
- }
- if (ast_channel_masquerade(p2->owner, p1->owner->bridge)) {
- ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p2->owner->name, p1->owner->bridge->name);
- return -1;
- }
- } else if (p2->owner->bridge) {
- ast_moh_stop(p2->owner->bridge);
- ast_moh_stop(p2->owner);
- ast_moh_stop(p1->owner);
- if (p2->owner->cdr) {
- p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->cdr);
- p2->owner->cdr = NULL;
+ chana = p1->owner;
+ chanb = p2->owner;
+ bridgea = p1->owner->bridge;
+ bridgeb = p2->owner->bridge;
+
+ if (bridgea) {
+ peera = chana;
+ peerb = chanb;
+ peerc = bridgea;
+ } else if(bridgeb) {
+ peera = chanb;
+ peerb = chana;
+ peerc = bridgeb;
+ }
+
+ if(peera && peerb && peerc) {
+ ast_quiet_chan(peera);
+ ast_quiet_chan(peerb);
+ ast_quiet_chan(peerc);
+
+ if (peera->cdr && peerb->cdr) {
+ peerb->cdr = ast_cdr_append(peerb->cdr, peera->cdr);
+ } else if(peera->cdr) {
+ peerb->cdr = peera->cdr;
}
- if (p2->owner->bridge->cdr) {
- p1->owner->cdr = ast_cdr_append(p1->owner->cdr, p2->owner->bridge->cdr);
- p2->owner->bridge->cdr = NULL;
+ peera->cdr = NULL;
+
+ if (peerb->cdr && peerc->cdr) {
+ peerb->cdr = ast_cdr_append(peerb->cdr, peerc->cdr);
+ } else if(peerc->cdr) {
+ peerb->cdr = peerc->cdr;
}
- if (ast_channel_masquerade(p1->owner, p2->owner->bridge)) {
- ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", p1->owner->name, p2->owner->bridge->name);
- return -1;
+ peerc->cdr = NULL;
+ if (ast_channel_masquerade(peerb, peerc)) {
+ ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
+ res = -1;
}
+ return res;
} else {
- ast_log(LOG_NOTICE, "Transfer attempted with no bridged calls to transfer\n");
- if (p1->owner)
- ast_softhangup_nolock(p1->owner, AST_SOFTHANGUP_DEV);
- if (p2->owner)
- ast_softhangup_nolock(p2->owner, AST_SOFTHANGUP_DEV);
return -1;
}
return 0;
More information about the svn-commits
mailing list