[asterisk-commits] branch mogorman/asterisk-xmpp r21308 - in /team/mogorman/asterisk-xmpp: ./ ch...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Apr 18 22:48:29 MST 2006


Author: markster
Date: Wed Apr 19 00:48:28 2006
New Revision: 21308

URL: http://svn.digium.com/view/asterisk?rev=21308&view=rev
Log:
Improve duplexity :)

Modified:
    team/mogorman/asterisk-xmpp/channels/chan_jingle.c
    team/mogorman/asterisk-xmpp/include/asterisk/jingle.h
    team/mogorman/asterisk-xmpp/include/asterisk/rtp.h
    team/mogorman/asterisk-xmpp/rtp.c

Modified: team/mogorman/asterisk-xmpp/channels/chan_jingle.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/channels/chan_jingle.c?rev=21308&r1=21307&r2=21308&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/channels/chan_jingle.c (original)
+++ team/mogorman/asterisk-xmpp/channels/chan_jingle.c Wed Apr 19 00:48:28 2006
@@ -138,7 +138,6 @@
 };
 
 char externip[16];
-char localip[16];
 
 struct jingle_container jingles;
 
@@ -396,19 +395,18 @@
 	struct jingle_candidate *ours1 = NULL , *ours2 =NULL;
 	struct sockaddr_in sin;
 	struct sockaddr_in dest;
+	struct in_addr us;
 	char iabuf[INET_ADDRSTRLEN];
 
 	iks *iq, *jingle, *candidate;
 	char user[17], pass[17], preference[5], port[7];
 
-
-	tmp = client->ourcandidates;
 
 	iq = iks_new("iq");
 	jingle = iks_new(GOOGLE_NODE);
 	candidate = iks_new("candidate");
-	ours1 = (struct jingle_candidate *)malloc(sizeof(struct jingle_candidate));
-	ours2 = (struct jingle_candidate *)malloc(sizeof(struct jingle_candidate));
+	ours1 = (struct jingle_candidate *)ast_calloc(1, sizeof(struct jingle_candidate));
+	ours2 = (struct jingle_candidate *)ast_calloc(1, sizeof(struct jingle_candidate));
 	if (!iq || !jingle || !candidate ||!ours1 ||!ours2) {
 		ast_log(LOG_WARNING, "out of memory!\n");
 		goto safeout;
@@ -423,18 +421,55 @@
 		}
 		p = p->next;
 	}
+	
+	if (!p) {
+		ast_log(LOG_NOTICE, "No matching jingle session!\n");
+		goto safeout;
+	}
 
 	ast_rtp_get_us(p->rtp, &sin);
+	ast_find_ourip(&us, bindaddr);
+
+	/* Setup our jingle candidates */
+	ast_copy_string(ours1->name,"rtp",sizeof(ours1->name));
+	ours1->port= ntohs(sin.sin_port);
+	ours1->preference=1;
+	snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
+	snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
+	ast_copy_string(ours1->username,user,sizeof(ours1->username));
+	ast_copy_string(ours1->password,pass,sizeof(ours1->password));
+	ast_inet_ntoa(ours1->ip, sizeof(ours1->ip), us);
+	ours1->protocol=AJI_PROTOCOL_UDP;
+	ours1->type=AJI_CONNECT_LOCAL;
+	ours1->generation=0;
+	p->ourcandidates=ours1;
+	ours1 = NULL;
+
+	if (!ast_strlen_zero(externip)) {
+		/* XXX We should really stun for this one not just go with externip XXX */
+		snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
+		snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
+		ast_copy_string(ours2->username,user,sizeof(ours2->username));
+		ast_copy_string(ours2->password,pass,sizeof(ours2->password));
+		ast_copy_string(ours2->ip,externip,sizeof(ours2->ip));
+		ast_copy_string(ours2->name,"rtp",sizeof(ours1->name));
+		ours2->port= ntohs(sin.sin_port);
+		ours2->preference=0.9;
+		ours2->protocol=AJI_PROTOCOL_UDP;
+		ours2->type=AJI_CONNECT_STUN;
+		ours2->generation=0;
+		ours1->next=ours2;
+		ours2 = NULL;
+	}
+
 	dest.sin_addr = __ourip; /// THIS IS BAD NEED TO FIX
 	dest.sin_port = sin.sin_port;
 	
-	ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), __ourip), ntohs(sin.sin_port)); /// THIS IS BAD NEED TO FIX
-	snprintf(port, sizeof(port),"%d",ntohs(sin.sin_port));
-	snprintf(localip, sizeof(localip),"%s",ast_inet_ntoa(iabuf, sizeof(iabuf), __ourip)); // hack
-#if 0
+	ast_verbose("We're at %s port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), us), ntohs(sin.sin_port)); /// THIS IS BAD NEED TO FIX
+
+	tmp = p->ourcandidates;
 	while(tmp) { /*send standard candidates*/
-		snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand() ,thread_safe_rand());
-		snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(), thread_safe_rand());
+		snprintf(port, sizeof(port),"%d",tmp->port);
 		snprintf(preference,sizeof(preference),"%.2f",tmp->preference);
 		iks_insert_attrib(iq,"from", c->jid->full);
 		iks_insert_attrib(iq,"to", iks_find_attrib(pak->x,"from"));
@@ -446,11 +481,10 @@
 		iks_insert_attrib(jingle,"initiator",iks_find_attrib(pak->x,"from"));
 		iks_insert_attrib(jingle,"xmlns", GOOGLE_NS);
 		iks_insert_attrib(candidate, "name", tmp->name);
-		iks_insert_attrib(candidate, "address",localip); /*FIX ME*/
+		iks_insert_attrib(candidate, "address",tmp->ip);
 		iks_insert_attrib(candidate, "port", port);
-		iks_insert_attrib(candidate, "username", user);
-		iks_insert_attrib(candidate, "password", pass);
-
+		iks_insert_attrib(candidate, "username", tmp->username);
+		iks_insert_attrib(candidate, "password", tmp->password);
 		iks_insert_attrib(candidate, "preference", preference);
 		if(tmp->protocol == AJI_PROTOCOL_UDP)
 			iks_insert_attrib(candidate, "protocol", "udp");
@@ -467,79 +501,13 @@
 		iks_send(c->p,iq);
 		tmp=tmp->next;
 	}
-#endif
-	if(!p->theircandidates) { /*send default stun, and local, and relay */
-		snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		ast_copy_string(ours1->username,user,sizeof(ours1->username));
-		ast_copy_string(ours1->password,pass,sizeof(ours1->password));
-		iks_insert_attrib(iq,"from", c->jid->full);
-		iks_insert_attrib(iq,"to", iks_find_attrib(pak->x,"from"));
-		iks_insert_attrib(iq,"type", "set");
-		iks_insert_attrib(iq,"id", c->mid);
-		ast_aji_increment_mid(c->mid);
-		iks_insert_attrib(jingle,"type", "candidates");
-		iks_insert_attrib(jingle,"id", iks_find_attrib(pak->query,GOOGLE_SID));
-		iks_insert_attrib(jingle,"initiator",iks_find_attrib(pak->x,"from"));
-		iks_insert_attrib(jingle,"xmlns", GOOGLE_NS);
-		iks_insert_attrib(candidate, "name", "rtp");
-		ast_copy_string(ours1->name,"rtp",sizeof(ours1->name));
-		iks_insert_attrib(candidate, "address",localip);
-		ast_copy_string(ours1->ip,localip,sizeof(ours1->ip));
-		iks_insert_attrib(candidate, "port", port); /*FIX ME*/
-		ours1->port= ntohs(sin.sin_port);
-		iks_insert_attrib(candidate, "username", user);
-		iks_insert_attrib(candidate, "password", pass);
-		iks_insert_attrib(candidate, "preference", "1");
-		ours1->preference=1;
-		iks_insert_attrib(candidate, "protocol", "udp");
-		ours1->protocol=AJI_PROTOCOL_UDP;
-		iks_insert_attrib(candidate, "type", "local");
-		ours1->type=AJI_CONNECT_LOCAL;
-		iks_insert_attrib(candidate, "network", "0");
-		iks_insert_attrib(candidate, "generation", "0");
-		ours1->generation=0;
-		iks_send(c->p,iq);
-		p->ourcandidates=ours1;
-		ours1->next=ours2;
-		ours2->next=NULL;
-		
-		snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		ast_copy_string(ours2->username,user,sizeof(ours2->username));
-		ast_copy_string(ours2->password,pass,sizeof(ours2->password));
-		ast_copy_string(ours2->ip,externip,sizeof(ours2->ip));
-		ast_copy_string(ours2->name,"rtp",sizeof(ours1->name));
-		ours2->port= ntohs(sin.sin_port);
-		ours2->preference=0.9;
-		ours2->protocol=AJI_PROTOCOL_UDP;
-		ours2->type=AJI_CONNECT_STUN;
-		ours2->generation=0;
-		iks_insert_attrib(iq,"id", c->mid);
-		ast_aji_increment_mid(c->mid);
-		iks_insert_attrib(candidate, "address", externip);
-		iks_insert_attrib(candidate, "port", port);
-		iks_insert_attrib(candidate, "username", user);
-		iks_insert_attrib(candidate, "password", pass);
-		iks_insert_attrib(candidate, "preference", "0.9");
-		iks_insert_attrib(candidate, "type", "stun");
-		iks_send(c->p,iq);
-#if 0		
-		snprintf(user, sizeof(user),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		snprintf(pass, sizeof(pass),"%08x%08x",thread_safe_rand(),thread_safe_rand());
-		iks_insert_attrib(iq,"id", c->mid);
-		ast_aji_increment_mid(c->mid);
-		iks_insert_attrib(candidate, "address", localip);
-		iks_insert_attrib(candidate, "port", port); /*FIX ME*/
-		iks_insert_attrib(candidate, "username", user);
-		iks_insert_attrib(candidate, "password", pass);
-		iks_insert_attrib(candidate, "preference", "0.5");
-		iks_insert_attrib(candidate, "protocol", "ssltcp");
-		iks_insert_attrib(candidate, "type", "relay");
-		iks_send(c->p,iq); 
-#endif
-	}
+	p->laststun = 0;
+
 safeout:
+	if (ours1)
+		free(ours1);
+	if (ours2)
+		free(ours2);
 	if (iq)
 		iks_delete(iq);
 	if (jingle)
@@ -778,10 +746,10 @@
 			ast_verbose("yatta!!\n");
 			codec= iks_next(codec);
 		}
+		jingle_create_candidates(client, p, pak);
 		ast_mutex_unlock(&p->lock);
 		ast_setstate(chan, AST_STATE_RING);
 		res = ast_pbx_start(chan);
-		jingle_create_candidates(client, p, pak);
 
 		switch (res) {
 		case AST_PBX_FAILED:
@@ -803,6 +771,32 @@
 	return 1;
 }
 
+static int jingle_update_stun(struct jingle *client, struct jingle_pvt *p)
+{
+	struct jingle_candidate *tmp;
+	struct hostent *hp;
+	struct ast_hostent ahp;
+	struct sockaddr_in sin;
+
+	if (time(NULL) == p->laststun)
+		return 0;
+
+	tmp = p->theircandidates;
+	p->laststun = time(NULL);
+	while(tmp) {
+		char username[256]; 
+		hp = ast_gethostbyname(tmp->ip, &ahp);
+		sin.sin_family = AF_INET;
+		memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
+		sin.sin_port = htons(tmp->port);
+		snprintf(username, sizeof(username), "%s%s", tmp->username, p->ourcandidates->username);
+		
+		ast_rtp_stun_request(p->rtp, &sin, username);
+		tmp = tmp->next;
+	}
+	return 1;
+}
+
 static int jingle_add_candidate(struct jingle *client,ikspak *pak)
 {
 	struct jingle_pvt *p =NULL,*tmp = NULL;
@@ -814,7 +808,7 @@
 	char iabuf[INET_ADDRSTRLEN];
 	iks *candidate_node = NULL;
 	iks *receipt = NULL;
-	newcandidate = (struct jingle_candidate *)malloc(sizeof(struct jingle_candidate));
+	newcandidate = (struct jingle_candidate *)ast_calloc(1, sizeof(struct jingle_candidate));
 	if(!newcandidate)
 		return 0;
 	memset(newcandidate,0,sizeof(struct jingle_candidate));
@@ -853,17 +847,9 @@
 		ast_verbose("NO MATCH\n");
 		return -1;
 	} else {
-		hp = ast_gethostbyname(newcandidate->ip, &ahp);
-		sin.sin_family = AF_INET;
-		memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
-		sin.sin_port = htons(newcandidate->port);
-		if (p->rtp && sin.sin_port) {
-			/* ast_rtp_set_peer(p->rtp, &sin); */
-			ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(iabuf,sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
-		}
 		newcandidate->next = p->theircandidates;
 		p->theircandidates = newcandidate;
-		ast_verbose("sending\n");	
+		p->laststun = 0;
 		receipt = iks_new("iq");
 		iks_insert_attrib(receipt,"type","result");
 		iks_insert_attrib(receipt,"from",c->jid->full);
@@ -876,10 +862,6 @@
 	return 0;
 }
 
-static void check_bridge(struct jingle_pvt *p, int isoutbound)
-{
-}
-
 static struct ast_frame *jingle_rtp_read(struct ast_channel *ast, struct jingle_pvt *p)
 {
 	struct ast_frame *f;
@@ -887,7 +869,8 @@
 		return &ast_null_frame;
 	}
 	f = ast_rtp_read(p->rtp);
-        if (p->owner) {
+	jingle_update_stun(p->parent, p);
+	if (p->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
 			if (f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
@@ -903,7 +886,7 @@
 					ast_log(LOG_DEBUG, "* Detected inband DTMF '%c'\n", f->subclass);
 		        } */
 		}
-        }
+	}
 	return f;
 }
 
@@ -1102,7 +1085,7 @@
 	}
 	p = jingle_alloc(client, to, NULL);
 	if (p)
-		chan = jingle_new(client->connection, p, AST_STATE_DOWN, to);
+		chan = jingle_new(client, p, AST_STATE_DOWN, to);
 	return chan;
 }
 
@@ -1155,14 +1138,9 @@
 		/* New call */
 		jingle_newcall(client, pak);
 	} else if (iks_find_with_attrib(pak->x,GOOGLE_NODE,"type",GOOGLE_NEGOTIATE)) {
+		ast_log(LOG_DEBUG, "About to add candidate!\n");
 		jingle_add_candidate(client,pak);
-		if(flipflop == 2) {
-			flipflop = 0;
-		}
-		else {
-			ast_verbose("COUNT IS %d\n",flipflop);
-			flipflop++;
-		}
+		ast_log(LOG_DEBUG, "Candidate Added!\n");
 	} else if(iks_find_with_attrib(pak->x,GOOGLE_NODE,"type","terminate")) {
 		jingle_hangup_farend(client, pak);
 	}
@@ -1227,7 +1205,9 @@
 	member->allowguest=allowguest;
 	member->prefs=prefs;
 	while(var) {
+#if 0
 		struct jingle_candidate *candidate=NULL;
+#endif		
 		if(!strcasecmp(var->name,"username"))
 			ast_copy_string(member->user, var->value, sizeof(member->user));
 		else if(!strcasecmp(var->name,"disallow"))
@@ -1236,6 +1216,7 @@
 			ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
 		else if (!strcasecmp(var->name, "context"))
 			ast_copy_string(member->context,var->value,sizeof(member->context));
+#if 0
 		else if (!strcasecmp(var->name, "candidate")) {
 			candidate = jingle_create_candidate(var->value);
 			if(candidate) {
@@ -1243,6 +1224,7 @@
 				member->ourcandidates = candidate;
 			}
 		}
+#endif		
 		else if (!strcasecmp(var->name, "connection")) {
 			if((client = ast_aji_get_client(var->value))) {
 		//		client->jingle=member;
@@ -1295,6 +1277,7 @@
 			ast_copy_string(context,var->value,sizeof(context));
 		else if (!strcasecmp(var->name, "externip"))
 			ast_copy_string(externip,var->value,sizeof(externip));
+#if 0
 		else if (!strcasecmp(var->name, "candidate")) {
 			candidate = jingle_create_candidate(var->value);
 			if(candidate) {
@@ -1302,7 +1285,7 @@
 				global_candidates = candidate;
 			}
 		}
-
+#endif
 	}
 	while(cat) {
 		struct jingle_candidate *candidate = NULL;
@@ -1317,7 +1300,9 @@
 				ast_copy_string(member->user, "guest", sizeof(member->user));
 				ast_copy_string(member->context, context, sizeof(member->context));
 				member->allowguest=allowguest;
+#if 0
 				member->ourcandidates = jingle_dup_candidates(global_candidates);
+#endif				
 				member->prefs=prefs;
 				while(var) {
 					if(!strcasecmp(var->name,"disallow"))
@@ -1326,6 +1311,7 @@
 						ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
 					else if (!strcasecmp(var->name, "context"))
 						ast_copy_string(member->context,var->value,sizeof(member->context));
+#if 0
 					else if (!strcasecmp(var->name, "candidate")) {
 						candidate = jingle_create_candidate(var->value);
 						if(candidate) {
@@ -1333,7 +1319,7 @@
 							member->ourcandidates = candidate;
 						}
 					}
-
+#endif
 					var = var->next;
 				}
 				ASTOBJ_UNLOCK(member);

Modified: team/mogorman/asterisk-xmpp/include/asterisk/jingle.h
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/include/asterisk/jingle.h?rev=21308&r1=21307&r2=21308&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/include/asterisk/jingle.h (original)
+++ team/mogorman/asterisk-xmpp/include/asterisk/jingle.h Wed Apr 19 00:48:28 2006
@@ -51,6 +51,7 @@
 
 struct jingle_pvt {
 	ast_mutex_t lock;			/* Channel private lock */
+	time_t laststun;
 	struct jingle *parent;		/* Parent client */
 	char sid[100];
 	char from[100];
@@ -73,7 +74,6 @@
 
 struct jingle {
 	ASTOBJ_COMPONENTS(struct jingle);
-	struct jingle_candidate *ourcandidates;
 	struct aji_client *connection;
 	struct jingle_pvt *p;
 	struct ast_codec_pref prefs;

Modified: team/mogorman/asterisk-xmpp/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/include/asterisk/rtp.h?rev=21308&r1=21307&r2=21308&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/include/asterisk/rtp.h (original)
+++ team/mogorman/asterisk-xmpp/include/asterisk/rtp.h Wed Apr 19 00:48:28 2006
@@ -105,6 +105,8 @@
 
 void ast_rtp_reset(struct ast_rtp *rtp);
 
+void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username);
+
 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback);
 
 void ast_rtp_set_data(struct ast_rtp *rtp, void *data);

Modified: team/mogorman/asterisk-xmpp/rtp.c
URL: http://svn.digium.com/view/asterisk/team/mogorman/asterisk-xmpp/rtp.c?rev=21308&r1=21307&r2=21308&view=diff
==============================================================================
--- team/mogorman/asterisk-xmpp/rtp.c (original)
+++ team/mogorman/asterisk-xmpp/rtp.c Wed Apr 19 00:48:28 2006
@@ -293,9 +293,37 @@
 	}
 }
 
-static int stun_send_response(int s, struct sockaddr_in *dst, struct stun_header *resp)
+static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
 {
 	return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0, dst, sizeof(*dst));
+}
+
+static void stun_req_id(struct stun_header *req)
+{
+	int x;
+	for (x=0;x<4;x++)
+		req->id.id[x] = ast_random();
+}
+
+void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username)
+{
+	struct stun_header *req;
+	unsigned char reqdata[1024];
+	int reqlen, reqleft;
+	struct stun_attr *attr;
+
+	req = (struct stun_header *)reqdata;
+	stun_req_id(req);
+	reqlen = 0;
+	reqleft = sizeof(reqdata) - sizeof(struct stun_header);
+	req->msgtype = 0;
+	req->msglen = 0;
+	attr = (struct stun_attr *)req->ies;
+	if (username)
+		append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft);
+	req->msglen = htons(reqlen);
+	req->msgtype = htons(STUN_BINDREQ);
+	stun_send(rtp->s, suggestion, req);
 }
 
 static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, int len)
@@ -358,7 +386,7 @@
 			append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
 			resp->msglen = htons(resplen);
 			resp->msgtype = htons(STUN_BINDRESP);
-			stun_send_response(s, src, resp);
+			stun_send(s, src, resp);
 			ret = STUN_ACCEPT;
 			break;
 		default:



More information about the asterisk-commits mailing list