[svn-commits] wedhorn: trunk r340071 - /trunk/channels/chan_skinny.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Oct 9 19:57:09 CDT 2011


Author: wedhorn
Date: Sun Oct  9 19:57:06 2011
New Revision: 340071

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=340071
Log:
Add skinny version 17 protocol support.

Added some data to skinny packet structures to make compatible
with v17. Added protocolversion to device, set on registration
based on the version provided by device.

v17 includes some increased ip space for ip6. This patch increases
ip space in the packets but still only uses ip4. Some packet
structures duplicated (ip4 and ip6 types). ip4 type used unless
version is greater or equal to 17.

Tested by snuff and myself on 7961 with recent 8.5 firmware. Also
tested compatible with old 7960 and older 30VIPs.


Modified:
    trunk/channels/chan_skinny.c

Modified: trunk/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/trunk/channels/chan_skinny.c?view=diff&rev=340071&r1=340070&r2=340071
==============================================================================
--- trunk/channels/chan_skinny.c (original)
+++ trunk/channels/chan_skinny.c Sun Oct  9 19:57:06 2011
@@ -273,6 +273,9 @@
 	uint32_t ip;
 	uint32_t type;
 	uint32_t maxStreams;
+	uint32_t space;
+	uint8_t protocolVersion;
+	char space2[3] ;
 };
 
 #define IP_PORT_MESSAGE 0x0002
@@ -350,11 +353,18 @@
 };
 
 #define OPEN_RECEIVE_CHANNEL_ACK_MESSAGE 0x0022
-struct open_receive_channel_ack_message {
+struct open_receive_channel_ack_message_ip4 {
 	uint32_t status;
 	uint32_t ipAddr;
 	uint32_t port;
-	uint32_t passThruId;
+	uint32_t callReference;
+};
+struct open_receive_channel_ack_message_ip6 {
+	uint32_t status;
+	uint32_t space;
+	char ipAddr[16];
+	uint32_t port;
+	uint32_t callReference;
 };
 
 #define SOFT_KEY_SET_REQ_MESSAGE 0x0025
@@ -392,6 +402,7 @@
 struct stop_tone_message {
 	uint32_t instance;
 	uint32_t reference;
+	uint32_t space;
 };
 
 #define SET_RINGER_MESSAGE 0x0085
@@ -424,11 +435,11 @@
 struct media_qualifier {
 	uint32_t precedence;
 	uint32_t vad;
-	uint16_t packets;
+	uint32_t packets;
 	uint32_t bitRate;
 };
 
-struct start_media_transmission_message {
+struct start_media_transmission_message_ip4 {
 	uint32_t conferenceId;
 	uint32_t passThruPartyId;
 	uint32_t remoteIp;
@@ -436,7 +447,19 @@
 	uint32_t packetSize;
 	uint32_t payloadType;
 	struct media_qualifier qualifier;
-	uint32_t space[16];
+	uint32_t space[19];
+};
+
+struct start_media_transmission_message_ip6 {
+	uint32_t conferenceId;
+	uint32_t passThruPartyId;
+	uint32_t space;
+	char remoteIp[16];
+	uint32_t remotePort;
+	uint32_t packetSize;
+	uint32_t payloadType;
+	struct media_qualifier qualifier;
+	uint32_t space2[19];
 };
 
 #define STOP_MEDIA_TRANSMISSION_MESSAGE 0x008B
@@ -580,6 +603,9 @@
 
 #define CLEAR_NOTIFY_MESSAGE  0x0115
 #define CLEAR_DISPLAY_MESSAGE 0x009A
+struct clear_display_message {
+	uint32_t space;
+};
 
 #define CAPABILITIES_REQ_MESSAGE 0x009B
 
@@ -614,7 +640,7 @@
 	uint32_t capability;
 	uint32_t echo;
 	uint32_t bitrate;
-	uint32_t space[16];
+	uint32_t space[36];
 };
 
 #define CLOSE_RECEIVE_CHANNEL_MESSAGE 0x0106
@@ -1012,6 +1038,7 @@
 	struct version_res_message version;
 	struct button_template_res_message buttontemplate;
 	struct displaytext_message displaytext;
+	struct clear_display_message cleardisplay;
 	struct display_prompt_status_message displaypromptstatus;
 	struct clear_prompt_message clearpromptstatus;
 	struct definetimedate_message definetimedate;
@@ -1036,10 +1063,12 @@
 	struct set_speaker_message setspeaker;
 	struct set_microphone_message setmicrophone;
 	struct call_info_message callinfo;
-	struct start_media_transmission_message startmedia;
+	struct start_media_transmission_message_ip4 startmedia_ip4;
+	struct start_media_transmission_message_ip6 startmedia_ip6;
 	struct stop_media_transmission_message stopmedia;
 	struct open_receive_channel_message openreceivechannel;
-	struct open_receive_channel_ack_message openreceivechannelack;
+	struct open_receive_channel_ack_message_ip4 openreceivechannelack_ip4;
+	struct open_receive_channel_ack_message_ip6 openreceivechannelack_ip6;
 	struct close_receive_channel_message closereceivechannel;
 	struct display_notify_message displaynotify;
 	struct dialed_number_message dialednumber;
@@ -1382,6 +1411,7 @@
 	char version_id[16];					\
 	char vmexten[AST_MAX_EXTENSION];			\
 	int type;						\
+	int protocolversion;				\
 	int registered;						\
 	int hookstate;					\
 	int lastlineinstance;					\
@@ -2057,6 +2087,7 @@
 				&& ast_apply_ha(d->ha, &addr)) {
 			s->device = d;
 			d->type = letohl(req->data.reg.type);
+			d->protocolversion = letohl(req->data.reg.protocolVersion);
 			if (ast_strlen_zero(d->version_id)) {
 				ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
 			}
@@ -2582,7 +2613,7 @@
 static void transmit_clear_display_message(struct skinny_device *d, int instance, int reference)
 {
 	struct skinny_req *req;
-	if (!(req = req_alloc(0, CLEAR_DISPLAY_MESSAGE)))
+	if (!(req = req_alloc(sizeof(struct clear_display_message), CLEAR_DISPLAY_MESSAGE)))
 		return;
 
 	//what do we want hear CLEAR_DISPLAY_MESSAGE or CLEAR_PROMPT_STATUS???
@@ -2706,19 +2737,33 @@
 {
 	struct skinny_req *req;
 
-	if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
-		return;
-
-	req->data.startmedia.conferenceId = htolel(sub->callid);
-	req->data.startmedia.passThruPartyId = htolel(sub->callid);
-	req->data.startmedia.remoteIp = dest.sin_addr.s_addr;
-	req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port));
-	req->data.startmedia.packetSize = htolel(fmt.cur_ms);
-	req->data.startmedia.payloadType = htolel(codec_ast2skinny(&fmt.format));
-	req->data.startmedia.qualifier.precedence = htolel(127);
-	req->data.startmedia.qualifier.vad = htolel(0);
-	req->data.startmedia.qualifier.packets = htolel(0);
-	req->data.startmedia.qualifier.bitRate = htolel(0);
+	if (d->protocolversion < 17) {
+		if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip4), START_MEDIA_TRANSMISSION_MESSAGE)))
+			return;
+		req->data.startmedia_ip4.conferenceId = htolel(sub->callid);
+		req->data.startmedia_ip4.passThruPartyId = htolel(sub->callid);
+		req->data.startmedia_ip4.remoteIp = dest.sin_addr.s_addr;
+		req->data.startmedia_ip4.remotePort = htolel(ntohs(dest.sin_port));
+		req->data.startmedia_ip4.packetSize = htolel(fmt.cur_ms);
+		req->data.startmedia_ip4.payloadType = htolel(codec_ast2skinny(&fmt.format));
+		req->data.startmedia_ip4.qualifier.precedence = htolel(127);
+		req->data.startmedia_ip4.qualifier.vad = htolel(0);
+		req->data.startmedia_ip4.qualifier.packets = htolel(0);
+		req->data.startmedia_ip4.qualifier.bitRate = htolel(0);
+	} else {
+		if (!(req = req_alloc(sizeof(struct start_media_transmission_message_ip6), START_MEDIA_TRANSMISSION_MESSAGE)))
+			return;
+		req->data.startmedia_ip6.conferenceId = htolel(sub->callid);
+		req->data.startmedia_ip6.passThruPartyId = htolel(sub->callid);
+		memcpy(req->data.startmedia_ip6.remoteIp, &dest.sin_addr.s_addr, sizeof(dest.sin_addr.s_addr));
+		req->data.startmedia_ip6.remotePort = htolel(ntohs(dest.sin_port));
+		req->data.startmedia_ip6.packetSize = htolel(fmt.cur_ms);
+		req->data.startmedia_ip6.payloadType = htolel(codec_ast2skinny(&fmt.format));
+		req->data.startmedia_ip6.qualifier.precedence = htolel(127);
+		req->data.startmedia_ip6.qualifier.vad = htolel(0);
+		req->data.startmedia_ip6.qualifier.packets = htolel(0);
+		req->data.startmedia_ip6.qualifier.bitRate = htolel(0);
+	}
 	transmit_response(d, req);
 }
 
@@ -6181,25 +6226,33 @@
 	uint32_t addr;
 	int port;
 	int status;
-	int passthruid;
-
-	status = letohl(req->data.openreceivechannelack.status);
+	int callid;
+
+	status = (d->protocolversion<17)?letohl(req->data.openreceivechannelack_ip4.status):letohl(req->data.openreceivechannelack_ip6.status);
 	if (status) {
 		ast_log(LOG_ERROR, "Open Receive Channel Failure\n");
 		return 0;
 	}
-	addr = req->data.openreceivechannelack.ipAddr;
-	port = letohl(req->data.openreceivechannelack.port);
-	passthruid = letohl(req->data.openreceivechannelack.passThruId);
+	if (d->protocolversion<17) {
+		addr = req->data.openreceivechannelack_ip4.ipAddr;
+		port = letohl(req->data.openreceivechannelack_ip4.port);
+		callid = letohl(req->data.openreceivechannelack_ip4.callReference);
+	} else {
+		memcpy(&addr, &req->data.openreceivechannelack_ip6.ipAddr, sizeof(addr));
+		port = letohl(req->data.openreceivechannelack_ip6.port);
+		callid = letohl(req->data.openreceivechannelack_ip6.callReference);
+	}
 
 	sin.sin_family = AF_INET;
 	sin.sin_addr.s_addr = addr;
 	sin.sin_port = htons(port);
 
-	sub = find_subchannel_by_reference(d, passthruid);
-
-	if (!sub)
+	sub = find_subchannel_by_reference(d, callid);
+
+	if (!sub) {
+		ast_log(LOG_ERROR, "Open Receive Channel Failure - can't find sub for %d\n", callid);
 		return 0;
+	}
 
 	l = sub->line;
 
@@ -6602,7 +6655,7 @@
 	case REGISTER_MESSAGE:
 		if (skinny_register(req, s)) {
 			ast_atomic_fetchadd_int(&unauth_sessions, -1);
-			ast_verb(3, "Device '%s' successfully registered\n", s->device->name);
+			ast_verb(3, "Device '%s' successfully registered (protoVers %d)\n", s->device->name, s->device->protocolversion);
 			transmit_registerack(s->device);
 			transmit_capabilitiesreq(s->device);
 		} else {




More information about the svn-commits mailing list