[asterisk-commits] wedhorn: branch wedhorn/packet-fragmentation r383309 - /team/wedhorn/packet-f...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 18 04:45:01 CDT 2013


Author: wedhorn
Date: Mon Mar 18 04:44:51 2013
New Revision: 383309

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383309
Log:
Revised skinny keepalives

Modified:
    team/wedhorn/packet-fragmentation/channels/chan_skinny.c

Modified: team/wedhorn/packet-fragmentation/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/wedhorn/packet-fragmentation/channels/chan_skinny.c?view=diff&rev=383309&r1=383308&r2=383309
==============================================================================
--- team/wedhorn/packet-fragmentation/channels/chan_skinny.c (original)
+++ team/wedhorn/packet-fragmentation/channels/chan_skinny.c Mon Mar 18 04:44:51 2013
@@ -81,6 +81,7 @@
 #include "asterisk/event.h"
 #include "asterisk/indications.h"
 #include "asterisk/linkedlists.h"
+#include "asterisk/time.h"
 
 /*** DOCUMENTATION
 	<manager name="SKINNYdevices" language="en_US">
@@ -1590,6 +1591,10 @@
 	pthread_t t;
 	ast_mutex_t lock;
 	time_t start;
+	struct timeval keepalive_next;
+	int keepalive_lastDelay;
+	int keepalive_totalmissed;
+	int keepalive_sched;
 	struct sockaddr_in sin;
 	int fd;
 	char inbuf[SKINNY_MAX_PACKET];
@@ -6948,6 +6953,49 @@
 	return 1;
 }
 
+static int keepalive_timeout_cb(const void *data)
+{
+	struct skinny_device *d = (struct skinny_device *)data;
+	struct skinnysession *s = d->session;
+	
+	if (!s) {
+		return 0;
+	}
+	
+	ast_log(LOG_NOTICE, "Device has not sent a keepalive for a while: %s\n", d->name);
+	skinny_unregister(NULL, s);
+	return 0;
+}
+
+//return ast_sched_del(sched, sched_id);
+//ret = ast_sched_add(sched, when, callback, sub);
+
+
+static int handle_keepalive_message(struct skinny_req *req, struct skinnysession *s)
+{
+	struct skinny_device *d = s->device;
+	struct timeval now = ast_tvnow();
+	
+	while (ast_sched_del(sched, s->keepalive_sched)) {
+		/* keepalive sched has gone, loop till we find one */
+		usleep(1);
+	}
+	if (ast_tvcmp(now, s->keepalive_next) > 0) {
+		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received KEEP_ALIVE_MESSAGE from %s, %d ms late\n",
+			d->name, (int)ast_tvdiff_ms(now, s->keepalive_next));
+		s->keepalive_lastDelay = (int)ast_tvdiff_ms(now, s->keepalive_next);
+		s->keepalive_totalmissed++;
+	} else {
+		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received KEEP_ALIVE_MESSAGE from %s, %d ms early\n",
+			d->name, (int)ast_tvdiff_ms(s->keepalive_next, now));
+		s->keepalive_lastDelay = 0;
+	}
+	transmit_keepaliveack(s->device);
+	s->keepalive_sched = ast_sched_add(sched, keep_alive*3*1000, keepalive_timeout_cb, s->device);
+	s->keepalive_next = ast_tvadd(ast_tvnow(), ast_tv(keep_alive, 0));
+	return 0;
+}
+
 static int handle_soft_key_event_message(struct skinny_req *req, struct skinnysession *s)
 {
 	struct skinny_device *d = s->device;
@@ -7304,14 +7352,16 @@
 
 	switch(letohl(req->e)) {
 	case KEEP_ALIVE_MESSAGE:
-		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received KEEP_ALIVE_MESSAGE from %s\n", d->name);
-		transmit_keepaliveack(s->device);
+		
+		res = handle_keepalive_message(req, s);
 		break;
 	case REGISTER_MESSAGE:
 		SKINNY_DEBUG(DEBUG_PACKET, 3, "Received REGISTER_MESSAGE from %s, name %s, type %d, protovers %d\n",
 			d->name, req->data.reg.name, letohl(req->data.reg.type), letohl(req->data.reg.protocolVersion));
 		if (skinny_register(req, s)) {
 			ast_atomic_fetchadd_int(&unauth_sessions, -1);
+			s->keepalive_next = ast_tvadd(ast_tvnow(), ast_tv(keep_alive, 0));
+			s->keepalive_sched = ast_sched_add(sched, keep_alive*3*1000000, keepalive_timeout_cb, s->device);
 			ast_verb(3, "Device '%s' successfully registered (protoVers %d)\n", s->device->name, s->device->protocolversion);
 			transmit_registerack(s->device);
 			transmit_capabilitiesreq(s->device);
@@ -7482,9 +7532,7 @@
 	fds[0].fd = s->fd;
 	fds[0].events = POLLIN;
 	fds[0].revents = 0;
-	res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */
-						 /* we add 10% to the keep_alive to deal */
-						 /* with network delays, etc */
+	res = ast_poll(fds, 1, -1); /* Block, the scheduler will kill us if needed */
 	if (res < 0) {
 		if (errno != EINTR) {
 			ast_log(LOG_WARNING, "Select returned error: %s\n", strerror(errno));




More information about the asterisk-commits mailing list