[Asterisk-cvs] asterisk/channels chan_iax2.c,1.91.2.4,1.91.2.5

markster at lists.digium.com markster at lists.digium.com
Wed Feb 18 11:18:32 CST 2004


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv11826/channels

Modified Files:
      Tag: v1-0_stable
	chan_iax2.c 
Log Message:
Backport IAX2 cleanups from cvs-head


Index: chan_iax2.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_iax2.c,v
retrieving revision 1.91.2.4
retrieving revision 1.91.2.5
diff -u -d -r1.91.2.4 -r1.91.2.5
--- chan_iax2.c	11 Feb 2004 06:30:33 -0000	1.91.2.4
+++ chan_iax2.c	18 Feb 2004 16:05:23 -0000	1.91.2.5
@@ -71,6 +71,8 @@
 
 #define BRIDGE_OPTIMIZATION 
 
+#define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
+#define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
 
 #define DEFAULT_RETRY_TIME 1000
 #define MEMORY_SIZE 100
@@ -480,7 +482,7 @@
 
 
 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
-static int send_command_locked(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
+static int send_command_locked(unsigned short callno, char, int, unsigned int, char *, int, int);
 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, char *, int, int);
 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, char *, int);
@@ -1499,30 +1501,35 @@
 
 static int iax2_digit(struct ast_channel *c, char digit)
 {
-	return send_command_locked(c->pvt->pvt, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
+	return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
 }
 
 static int iax2_sendtext(struct ast_channel *c, char *text)
 {
 	
-	return send_command_locked(c->pvt->pvt, AST_FRAME_TEXT,
+	return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_TEXT,
 		0, 0, text, strlen(text) + 1, -1);
 }
 
 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
 {
-	return send_command_locked(c->pvt->pvt, AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
+	return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
 }
 
 static int iax2_sendhtml(struct ast_channel *c, int subclass, char *data, int datalen)
 {
-	return send_command_locked(c->pvt->pvt, AST_FRAME_HTML, subclass, 0, data, datalen, -1);
+	return send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_HTML, subclass, 0, data, datalen, -1);
 }
 
 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
 {
-	struct chan_iax2_pvt *pvt = newchan->pvt->pvt;
-	pvt->owner = newchan;
+	unsigned short callno = PTR_TO_CALLNO(newchan->pvt->pvt);
+	ast_mutex_lock(&iaxsl[callno]);
+	if (iaxs[callno])
+		iaxs[callno]->owner = newchan;
+	else
+		ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
+	ast_mutex_unlock(&iaxsl[callno]);
 	return 0;
 }
 
@@ -1747,7 +1754,7 @@
 
 static int auto_congest(void *nothing)
 {
-	int callno = (int)(long)(nothing);
+	int callno = PTR_TO_CALLNO(nothing);
 	struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
 	ast_mutex_lock(&iaxsl[callno]);
 	if (iaxs[callno]) {
@@ -1791,7 +1798,7 @@
 	char context[AST_MAX_EXTENSION] ="";
 	char *portno = NULL;
 	char *opts = "";
-	struct chan_iax2_pvt *p = c->pvt->pvt;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
 	char *stringp=NULL;
 	char storedsecret[80];
 	if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
@@ -1863,7 +1870,7 @@
 		iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
 	if (n)
 		iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
-	if (p->sendani && c->ani) {
+	if (iaxs[callno]->sendani && c->ani) {
 		l = n = NULL;
 		strncpy(cid, c->ani, sizeof(cid) - 1);
 		ast_callerid_parse(cid, &n, &l);
@@ -1882,18 +1889,19 @@
 		iax_ie_append_str(&ied, IAX_IE_USERNAME, username);
 	if (!secret && strlen(storedsecret))
 		secret = storedsecret;
+	ast_mutex_lock(&iaxsl[callno]);
 	if (secret) {
 		if (secret[0] == '[') {
 			/* This is an RSA key, not a normal secret */
-			strncpy(p->outkey, secret + 1, sizeof(p->secret)-1);
-			if (strlen(p->outkey)) {
-				p->outkey[strlen(p->outkey) - 1] = '\0';
+			strncpy(iaxs[callno]->outkey, secret + 1, sizeof(iaxs[callno]->secret)-1);
+			if (strlen(iaxs[callno]->outkey)) {
+				iaxs[callno]->outkey[strlen(iaxs[callno]->outkey) - 1] = '\0';
 			}
 		} else
-			strncpy(p->secret, secret, sizeof(p->secret)-1);
+			strncpy(iaxs[callno]->secret, secret, sizeof(iaxs[callno]->secret)-1);
 	}
 	iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
-	iax_ie_append_int(&ied, IAX_IE_CAPABILITY, p->capability);
+	iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
 	iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
 	iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime());
 	/* Transmit the string in a "NEW" request */
@@ -1902,30 +1910,29 @@
 	if (option_verbose > 2)
 		ast_verbose(VERBOSE_PREFIX_3 "Calling using options '%s'\n", requeststr);
 #endif		
-	if (p->maxtime) {
+	if (iaxs[callno]->maxtime) {
 		/* Initialize pingtime and auto-congest time */
-		p->pingtime = p->maxtime / 2;
-		p->initid = ast_sched_add(sched, p->maxtime * 2, auto_congest, (void *)(long)p->callno);
+		iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
+		iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
 	}
-	send_command_locked(p, AST_FRAME_IAX,
+	send_command(iaxs[callno], AST_FRAME_IAX,
 		IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
+	ast_mutex_unlock(&iaxsl[callno]);
 	ast_setstate(c, AST_STATE_RINGING);
 	return 0;
 }
 
 static int iax2_hangup(struct ast_channel *c) 
 {
-	struct chan_iax2_pvt *pvt = c->pvt->pvt;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
 	int alreadygone;
-	int callno;
-	if (pvt) {
-		callno = pvt->callno;
-		ast_mutex_lock(&iaxsl[callno]);
+	ast_mutex_lock(&iaxsl[callno]);
+	if (callno && iaxs[callno]) {
 		ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
-		alreadygone = pvt->alreadygone;
+		alreadygone = iaxs[callno]->alreadygone;
 		/* Send the hangup unless we have had a transmission error or are already gone */
-		if (!pvt->error && !alreadygone) 
-			send_command_final(pvt, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
+		if (!iaxs[callno]->error && !alreadygone) 
+			send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, NULL, 0, -1);
 		/* Explicitly predestroy it */
 		iax2_predestroy_nolock(callno);
 		/* If we were already gone to begin with, destroy us now */
@@ -1933,8 +1940,8 @@
 			ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
 			iax2_destroy_nolock(callno);
 		}
-		ast_mutex_unlock(&iaxsl[callno]);
 	}
+	ast_mutex_unlock(&iaxsl[callno]);
 	if (option_verbose > 2) 
 		ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
 	return 0;
@@ -1949,7 +1956,7 @@
 		h->flag = AST_OPTION_FLAG_REQUEST;
 		h->option = htons(option);
 		memcpy(h->data, data, datalen);
-		res = send_command_locked((struct chan_iax2_pvt *)c->pvt->pvt, AST_FRAME_CONTROL,
+		res = send_command_locked(PTR_TO_CALLNO(c->pvt->pvt), AST_FRAME_CONTROL,
 			AST_CONTROL_OPTION, 0, (char *)h, datalen + sizeof(struct ast_option_header), -1);
 		free(h);
 		return res;
@@ -1957,6 +1964,7 @@
 		ast_log(LOG_WARNING, "Out of memory\n");
 	return -1;
 }
+
 static struct ast_frame *iax2_read(struct ast_channel *c) 
 {
 	static struct ast_frame f = { AST_FRAME_NULL, };
@@ -1964,49 +1972,47 @@
 	return &f;
 }
 
-static int iax2_start_transfer(struct ast_channel *c0, struct ast_channel *c1)
+static int iax2_start_transfer(unsigned short callno0, unsigned short callno1)
 {
 	int res;
 	struct iax_ie_data ied0;
 	struct iax_ie_data ied1;
-	struct chan_iax2_pvt *p0 = c0->pvt->pvt;
-	struct chan_iax2_pvt *p1 = c1->pvt->pvt;
 	unsigned int transferid = rand();
 	memset(&ied0, 0, sizeof(ied0));
-	iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &p1->addr);
-	iax_ie_append_short(&ied0, IAX_IE_CALLNO, p1->peercallno);
+	iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
+	iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
 	iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
 
 	memset(&ied1, 0, sizeof(ied1));
-	iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &p0->addr);
-	iax_ie_append_short(&ied1, IAX_IE_CALLNO, p0->peercallno);
+	iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
+	iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
 	iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
 	
-	res = send_command(p0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
+	res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
 	if (res)
 		return -1;
-	res = send_command(p1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
+	res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
 	if (res)
 		return -1;
-	p0->transferring = TRANSFER_BEGIN;
-	p1->transferring = TRANSFER_BEGIN;
+	iaxs[callno0]->transferring = TRANSFER_BEGIN;
+	iaxs[callno1]->transferring = TRANSFER_BEGIN;
 	return 0;
 }
 
-static void lock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1)
+static void lock_both(unsigned short callno0, unsigned short callno1)
 {
-	ast_mutex_lock(&iaxsl[p0->callno]);
-	while (ast_mutex_trylock(&iaxsl[p1->callno])) {
-		ast_mutex_unlock(&iaxsl[p0->callno]);
+	ast_mutex_lock(&iaxsl[callno0]);
+	while (ast_mutex_trylock(&iaxsl[callno1])) {
+		ast_mutex_unlock(&iaxsl[callno0]);
 		usleep(10);
-		ast_mutex_lock(&iaxsl[p0->callno]);
+		ast_mutex_lock(&iaxsl[callno0]);
 	}
 }
 
-static void unlock_both(struct chan_iax2_pvt *p0, struct chan_iax2_pvt *p1)
+static void unlock_both(unsigned short callno0, unsigned short callno1)
 {
-	ast_mutex_unlock(&iaxsl[p1->callno]);
-	ast_mutex_unlock(&iaxsl[p0->callno]);
+	ast_mutex_unlock(&iaxsl[callno1]);
+	ast_mutex_unlock(&iaxsl[callno0]);
 }
 
 static int iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
@@ -2017,15 +2023,15 @@
 	int res = -1;
 	int transferstarted=0;
 	struct ast_frame *f;
-	struct chan_iax2_pvt *p0 = c0->pvt->pvt;
-	struct chan_iax2_pvt *p1 = c1->pvt->pvt;
+	unsigned short callno0 = PTR_TO_CALLNO(c0->pvt->pvt);
+	unsigned short callno1 = PTR_TO_CALLNO(c1->pvt->pvt);
 	struct timeval waittimer = {0, 0}, tv;
 	
-	lock_both(p0, p1);
+	lock_both(callno0, callno1);
 	/* Put them in native bridge mode */
-	p0->bridgecallno = p1->callno;
-	p1->bridgecallno = p0->callno;
-	unlock_both(p0, p1);
+	iaxs[callno0]->bridgecallno = callno1;
+	iaxs[callno1]->bridgecallno = callno0;
+	unlock_both(callno0, callno1);
 
 	/* If not, try to bridge until we can execute a transfer, if we can */
 	cs[0] = c0;
@@ -2037,34 +2043,34 @@
 				ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
 			/* Remove from native mode */
 			if (c0->type == type) {
-				ast_mutex_lock(&iaxsl[p0->callno]);
-				p0->bridgecallno = 0;
-				ast_mutex_unlock(&iaxsl[p0->callno]);
+				ast_mutex_lock(&iaxsl[callno0]);
+				iaxs[callno0]->bridgecallno = 0;
+				ast_mutex_unlock(&iaxsl[callno0]);
 			}
 			if (c1->type == type) {
-				ast_mutex_lock(&iaxsl[p1->callno]);
-				p1->bridgecallno = 0;
-				ast_mutex_unlock(&iaxsl[p1->callno]);
+				ast_mutex_lock(&iaxsl[callno1]);
+				iaxs[callno1]->bridgecallno = 0;
+				ast_mutex_unlock(&iaxsl[callno1]);
 			}
 			return -2;
 		}
 		if (c0->nativeformats != c1->nativeformats) {
 			ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs, can't native bridge...\n");
 			/* Remove from native mode */
-			lock_both(p0, p1);
-			p0->bridgecallno = 0;
-			p1->bridgecallno = 0;
-			unlock_both(p0, p1);
+			lock_both(callno0, callno1);
+			iaxs[callno0]->bridgecallno = 0;
+			iaxs[callno1]->bridgecallno = 0;
+			unlock_both(callno0, callno1);
 			return -2;
 		}
 		/* check if transfered and if we really want native bridging */
-		if (!transferstarted && !p0->notransfer && !p1->notransfer) {
+		if (!transferstarted && !iaxs[callno0]->notransfer && !iaxs[callno1]->notransfer) {
 			/* Try the transfer */
-			if (iax2_start_transfer(c0, c1))
+			if (iax2_start_transfer(callno0, callno1))
 				ast_log(LOG_WARNING, "Unable to start the transfer\n");
 			transferstarted = 1;
 		}
-		if ((p0->transferring == TRANSFER_RELEASED) && (p1->transferring == TRANSFER_RELEASED)) {
+		if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
 			/* Call has been transferred.  We're no longer involved */
 			gettimeofday(&tv, NULL);
 			if (!waittimer.tv_sec && !waittimer.tv_usec) {
@@ -2150,32 +2156,32 @@
 		cs[0] = cs[1];
 		cs[1] = cs[2];
 	}
-	lock_both(p0, p1);
-	p0->bridgecallno = 0;
-	p1->bridgecallno = 0;
-	unlock_both(p0, p1);
+	lock_both(callno0, callno1);
+	iaxs[callno0]->bridgecallno = 0;
+	iaxs[callno1]->bridgecallno = 0;
+	unlock_both(callno0, callno1);
 	return res;
 }
 
 static int iax2_answer(struct ast_channel *c)
 {
-	struct chan_iax2_pvt *pvt = c->pvt->pvt;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Answering\n");
-	return send_command(pvt, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
+	return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
 }
 
 static int iax2_indicate(struct ast_channel *c, int condition)
 {
-	struct chan_iax2_pvt *pvt = c->pvt->pvt;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
-	return send_command(pvt, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
+	return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
 }
 	
 static int iax2_transfer(struct ast_channel *c, char *dest)
 {
-	struct chan_iax2_pvt *pvt = c->pvt->pvt;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
 	struct iax_ie_data ied;
 	char tmp[256] = "", *context;
 	strncpy(tmp, dest, sizeof(tmp) - 1);
@@ -2190,7 +2196,7 @@
 		iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
-	return send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
+	return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
 }
 	
 
@@ -2228,7 +2234,7 @@
 		tmp->nativeformats = capability;
 		tmp->readformat = 0;
 		tmp->writeformat = 0;
-		tmp->pvt->pvt = i;
+		tmp->pvt->pvt = CALLNO_TO_PTR(i->callno);
 		tmp->pvt->send_digit = iax2_digit;
 		tmp->pvt->send_text = iax2_sendtext;
 		tmp->pvt->send_image = iax2_sendimage;
@@ -2769,27 +2775,31 @@
 
 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
 {
-	struct chan_iax2_pvt *i = c->pvt->pvt;
-	if (!i)
-		return -1;
+	unsigned short callno = PTR_TO_CALLNO(c->pvt->pvt);
+	int res = -1;
+	ast_mutex_lock(&iaxsl[callno]);
+	if (iaxs[callno]) {
 	/* If there's an outstanding error, return failure now */
-	if (i->error) {
-		ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
-		return -1;
+		if (!iaxs[callno]->error) {
+			if (iaxs[callno]->alreadygone)
+				res = 0;
+				/* Don't waste bandwidth sending null frames */
+			else if (f->frametype == AST_FRAME_NULL)
+				res = 0;
+			else if ((f->frametype == AST_FRAME_VOICE) && iaxs[callno]->quelch)
+				res = 0;
+			else if (!(iaxs[callno]->state & IAX_STATE_STARTED))
+				res = 0;
+			else
+			/* Simple, just queue for transmission */
+				res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
+		} else {
+			ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
+		}
 	}
 	/* If it's already gone, just return */
-	if (i->alreadygone)
-		return 0;
-	/* Don't waste bandwidth sending null frames */
-	if (f->frametype == AST_FRAME_NULL)
-		return 0;
-	/* If we're quelching voice, don't bother sending it */
-	if ((f->frametype == AST_FRAME_VOICE) && i->quelch)
-		return 0;
-	if (!(i->state & IAX_STATE_STARTED))
-		return 0;
-	/* Simple, just queue for transmission */
-	return iax2_send(i, f, 0, -1, 0, 0, 0);
+	ast_mutex_unlock(&iaxsl[callno]);
+	return res;
 }
 
 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno, 
@@ -2812,12 +2822,12 @@
 	return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
 }
 
-static int send_command_locked(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
+static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, char *data, int datalen, int seqno)
 {
 	int res;
-	ast_mutex_lock(&iaxsl[i->callno]);
-	res = send_command(i, type, command, ts, data, datalen, seqno);
-	ast_mutex_unlock(&iaxsl[i->callno]);
+	ast_mutex_lock(&iaxsl[callno]);
+	res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
+	ast_mutex_unlock(&iaxsl[callno]);
 	return res;
 }
 




More information about the svn-commits mailing list