Review Board 1.7.16


IAX2 Transfer Fix

Review Request #140 - Created Feb. 3, 2009 and submitted

David Vossel
1.6.0
0013468
Reviewers
asterisk-dev
russell
Asterisk
Fixes issue with IAX2 transfers not taking place.  As it was, a call that was being transfered would never be handed off correctly to the call ends because of how call numbers were stored in a hash table.  The hash table, "iax_peercallno_pvt", storing all the current call numbers did not take into account the complications associated with transferring a call, so a separate hash table was required.  This second hash table "iax_transfercallno_pvt" handles calls being transfered, once the call transfer is complete the call is removed from the transfer hash table and added to the peer hash table resuming normal operations. Addition functions were created to handle storing, removing, and comparing items in the iax_transfercallno_pvt table. 
this patch has been tested on both 1.6.0 and 1.4.  1.6.1 and trunk have issues of there own that must be fixed before this patch can be applied to them. 

Changes between revision 2 and 3

1 2 3
1 2 3

  1. /branches/1.6.0/channels/chan_iax2.c: Loading...
/branches/1.6.0/channels/chan_iax2.c
Diff Revision 2 Diff Revision 3
[20] 1673 lines
[+20] [+] static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
1674
 				.peercallno = callno,
1674
				.peercallno = callno,
1675
				.transfercallno = callno,
1675
				.transfercallno = callno,
1676
 				/* hack!! */
1676
				/* hack!! */
1677
 				.frames_received = check_dcallno,
1677
				.frames_received = check_dcallno,
1678
 			};
1678
			};
1679
 
1679

   
1680
 			memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
1680
			memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
1681
			/* this works for finding normal call numbers not involving transfering */
1681
			/* this works for finding normal call numbers not involving transfering */ 
1682
 			if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
1682
			if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
1683
 				if (return_locked) {
1683
				if (return_locked) {
1684
 					ast_mutex_lock(&iaxsl[pvt->callno]);
1684
					ast_mutex_lock(&iaxsl[pvt->callno]);
1685
 				}
1685
				}
1686
 				res = pvt->callno;
1686
				res = pvt->callno;
[+20] [20] 11 lines
[+20] static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
1698
 				res = pvt->callno;
1698
				res = pvt->callno;
1699
 				ao2_ref(pvt, -1);
1699
				ao2_ref(pvt, -1);
1700
 				pvt = NULL;
1700
				pvt = NULL;
1701
 				return res;
1701
				return res;
1702
 			}
1702
			}
1703

    
   

   
1704
 		}
1703
		}
1705
			/* This will occur on the first response to a message that we initiated,
1704
			/* This will occur on the first response to a message that we initiated,
1706
		 * such as a PING. */
1705
		 * such as a PING. */
1707
		if (dcallno) {
1706
		if (dcallno) {
1708
			ast_mutex_lock(&iaxsl[dcallno]);
1707
			ast_mutex_lock(&iaxsl[dcallno]);
[+20] [20] 637 lines
[+20] [+] retry:
2346

    
   
2345

   
2347
		if (pvt->peercallno) {
2346
		if (pvt->peercallno) {
2348
			remove_by_peercallno(pvt);
2347
			remove_by_peercallno(pvt);
2349
		}
2348
		}
2350

    
   
2349

   

    
   
2350
		if(pvt->transfercallno) {

    
   
2351
			remove_by_transfercallno(pvt);

    
   
2352
		}

    
   
2353

   
2351
		if (!owner) {
2354
		if (!owner) {
2352
			ao2_ref(pvt, -1);
2355
			ao2_ref(pvt, -1);
2353
			pvt = NULL;
2356
			pvt = NULL;
2354
		}
2357
		}
2355
	}
2358
	}
[+20] [20] 4255 lines
[+20] [+] static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
6611
	pvt->transferid = ies->transferid;
6614
	pvt->transferid = ies->transferid;
6612
	store_by_transfercallno(pvt);
6615
	store_by_transfercallno(pvt);
6613
	if (ies->transferid)
6616
	if (ies->transferid)
6614
		iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
6617
		iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
6615
	send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
6618
	send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
6616
	return 0; 
6619
	return 0;
6617
}
6620
}
6618

    
   
6621

   
6619
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
6622
static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
6620
{
6623
{
6621
	char exten[256] = "";
6624
	char exten[256] = "";
[+20] [20] 5552 lines
[+20] [+] static int __unload_module(void)
12174
	}
12177
	}
12175

    
   
12178

   
12176
	ao2_ref(peers, -1);
12179
	ao2_ref(peers, -1);
12177
	ao2_ref(users, -1);
12180
	ao2_ref(users, -1);
12178
	ao2_ref(iax_peercallno_pvts, -1);
12181
	ao2_ref(iax_peercallno_pvts, -1);
12179
	ao2_ref(iax_transfercallno_pvts, -1);
12182
	ao2_ref(iax_transfercallno_pvts, -1);	
12180
	con = ast_context_find(regcontext);
12183
	con = ast_context_find(regcontext);
12181
	if (con)
12184
	if (con)
12182
		ast_context_destroy(con, "IAX2");
12185
		ast_context_destroy(con, "IAX2");
12183
	
12186
	
12184
	return 0;
12187
	return 0;
[+20] [20] 46 lines
[+20] [+] static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
12231
	struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12234
	struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12232

    
   
12235

   
12233
	/* The frames_received field is used to hold whether we're matching
12236
	/* The frames_received field is used to hold whether we're matching
12234
	 * against a full frame or not ... */
12237
	 * against a full frame or not ... */
12235

    
   
12238

   
12236
	return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 
12239
	return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12237
		pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12240
		pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12238
}
12241
}
12239
/*! \brief Load IAX2 module, load configuraiton ---*/
12242
/*! \brief Load IAX2 module, load configuraiton ---*/
12240
static int load_module(void)
12243
static int load_module(void)
12241
{
12244
{
[+20] [20] 120 lines
  1. /branches/1.6.0/channels/chan_iax2.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.