diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 7c5ca907bccdfc18c417960ac4fdd9ade4efa2f9..070ad7b809fe4920c5077bdccd6ffb84b6e6ee46 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -273,6 +273,9 @@ struct register_message {
 	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 @@ struct alarm_message {
 };
 
 #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 start_tone_message {
 struct stop_tone_message {
 	uint32_t instance;
 	uint32_t reference;
+	uint32_t space;
 };
 
 #define SET_RINGER_MESSAGE 0x0085
@@ -424,11 +435,11 @@ struct set_microphone_message {
 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 @@ struct start_media_transmission_message {
 	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 @@ struct displaytext_message {
 
 #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 @@ struct open_receive_channel_message {
 	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 @@ union skinny_data {
 	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 @@ union skinny_data {
 	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 @@ struct skinny_addon {
 	char version_id[16];					\
 	char vmexten[AST_MAX_EXTENSION];			\
 	int type;						\
+	int protocolversion;				\
 	int registered;						\
 	int hookstate;					\
 	int lastlineinstance;					\
@@ -2057,6 +2087,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
 				&& 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_ringer_mode(struct skinny_device *d, int mode)
 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 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
 {
 	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 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
 	uint32_t addr;
 	int port;
 	int status;
-	int passthruid;
+	int callid;
 
-	status = letohl(req->data.openreceivechannelack.status);
+	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);
+	sub = find_subchannel_by_reference(d, callid);
 
-	if (!sub)
+	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 @@ static int handle_message(struct skinny_req *req, struct skinnysession *s)
 	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 {