Index: channels/chan_skinny.c
===================================================================
--- channels/chan_skinny.c	(revision 78336)
+++ channels/chan_skinny.c	(working copy)
@@ -1861,30 +1861,36 @@
 	transmit_response(s, req);
 }
 
-static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid)
+static void transmit_closereceivechannel(struct skinnysession *s, unsigned callid)
 {
 	struct skinny_req *req;
 
-	if (state == SKINNY_ONHOOK) {
-		if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
-			return;
+	if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
+		return;
 
-		req->data.closereceivechannel.conferenceId = htolel(callid);
-		req->data.closereceivechannel.partyId = htolel(callid);
-		transmit_response(s, req);
+	req->data.closereceivechannel.conferenceId = htolel(callid);
+	req->data.closereceivechannel.partyId = htolel(callid);
 
-		if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
-			return;
+	transmit_response(s, req);
+}
 
-		req->data.stopmedia.conferenceId = htolel(callid);
-		req->data.stopmedia.passThruPartyId = htolel(callid);
-		transmit_response(s, req);
+static void transmit_stopmediatransmission(struct skinnysession *s, unsigned callid)
+{
+	struct skinny_req *req;
 
-		transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+	if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
+		return;
 
-		transmit_displaypromptstatus(s, NULL, 0, instance, callid);
-	}
+	req->data.stopmedia.conferenceId = htolel(callid);
+	req->data.stopmedia.passThruPartyId = htolel(callid);
+	
+	transmit_response(s, req);
+}
 
+static void transmit_callstatemessage(struct skinnysession *s, int instance, int state, unsigned callid)
+{
+	struct skinny_req *req;
+
 	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
 		return;
 
@@ -1892,18 +1898,17 @@
 	req->data.callstate.lineInstance = htolel(instance);
 	req->data.callstate.callReference = htolel(callid);
 	transmit_response(s, req);
+}
 
-	if (state == SKINNY_ONHOOK) {
-		transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
-	}
+static void transmit_activatecallplane(struct skinnysession *s, int instance)
+{
+	struct skinny_req *req;
 
-	if (state == SKINNY_OFFHOOK || state == SKINNY_ONHOOK) {
-		if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
-			return;
+	if (!(req = req_alloc(sizeof(struct activate_call_plane_message), ACTIVATE_CALL_PLANE_MESSAGE)))
+		return;
 
-		req->data.activatecallplane.lineInstance = htolel(instance);
-		transmit_response(s, req);
-	}
+	req->data.activatecallplane.lineInstance = htolel(instance);
+	transmit_response(s, req);
 }
 
 static int skinny_extensionstate_cb(char *context, char *exten, int state, void *data)
@@ -1912,48 +1917,66 @@
 	struct skinny_device *d = sd->parent;
 	struct skinnysession *s = d->session;
 	char hint[AST_MAX_EXTENSION];
-	int callstate = SKINNY_CALLREMOTEMULTILINE;
-	int lamp = SKINNY_LAMP_OFF;
 
-	switch (state) {
-	case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
-	case AST_EXTENSION_REMOVED:     /* Extension is gone */
-		ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
-		sd->stateid = -1;
-		callstate = SKINNY_ONHOOK;
-		lamp = SKINNY_LAMP_OFF;
-		break;
-	case AST_EXTENSION_RINGING:
-	case AST_EXTENSION_UNAVAILABLE:
-		callstate = SKINNY_RINGIN;
-		lamp = SKINNY_LAMP_BLINK;
-		break;
-	case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */
-	case AST_EXTENSION_INUSE:
-		callstate = SKINNY_CALLREMOTEMULTILINE;
-		lamp = SKINNY_LAMP_ON;
-		break;
-	case AST_EXTENSION_ONHOLD:
-		callstate = SKINNY_HOLD;
-		lamp = SKINNY_LAMP_WINK;
-		break;
-	case AST_EXTENSION_NOT_INUSE:
-	default:
-		callstate = SKINNY_ONHOOK;
-		lamp = SKINNY_LAMP_OFF;
-		break;
-	}
-
 	if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, sd->context, sd->exten)) {
 		/* If they are not registered, we will override notification and show no availability */
 		if (ast_device_state(hint) == AST_DEVICE_UNAVAILABLE) {
-			callstate = SKINNY_ONHOOK;
-			lamp = SKINNY_LAMP_FLASH;
+			if (state == AST_EXTENSION_DEACTIVATED || AST_EXTENSION_REMOVED) {
+				ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
+				sd->stateid = -1;
+			}
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(s, 0);
+			transmit_stopmediatransmission(s, 0);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(s, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, sd->instance);
 		}
+	} else {
+		switch (state) {
+		case AST_EXTENSION_DEACTIVATED: /* Retry after a while */
+		case AST_EXTENSION_REMOVED:     /* Extension is gone */
+			ast_verb(2, "Extension state: Watcher for hint %s %s. Notify Device %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", d->name);
+			sd->stateid = -1;
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(s, 0);
+			transmit_stopmediatransmission(s, 0);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(s, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, sd->instance);
+			break;
+		case AST_EXTENSION_RINGING:
+		case AST_EXTENSION_UNAVAILABLE:
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_BLINK);
+			transmit_callstatemessage(s, sd->instance, SKINNY_RINGIN, 0);
+			break;
+		case AST_EXTENSION_BUSY: /* callstate = SKINNY_BUSY wasn't wanting to work - I'll settle for this */
+		case AST_EXTENSION_INUSE:
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_ON);
+			transmit_callstatemessage(s, sd->instance, SKINNY_CALLREMOTEMULTILINE, 0);
+			break;
+		case AST_EXTENSION_ONHOLD:
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_WINK);
+			transmit_callstatemessage(s, sd->instance, SKINNY_HOLD, 0);
+			break;
+		case AST_EXTENSION_NOT_INUSE:
+		default:
+			transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(s, 0);
+			transmit_stopmediatransmission(s, 0);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(s, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, sd->instance);
+			break;
+		}
 	}
 
-	transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, lamp);
-	transmit_callstate(s, sd->instance, callstate, 0);
 	sd->laststate = state;
 
 	return 0;
@@ -2695,7 +2718,7 @@
 		break;
 	}
 
-	transmit_callstate(s, l->instance, SKINNY_RINGIN, sub->callid);
+	transmit_callstatemessage(s, l->instance, SKINNY_RINGIN, sub->callid);
 	transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGIN);
 	transmit_displaypromptstatus(s, "Ring-In", 0, l->instance, sub->callid);
 	transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
@@ -2728,12 +2751,24 @@
 	if (d->registered) {
 		if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_OFFHOOK)) {
 			l->hookstate = SKINNY_ONHOOK;
-			transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_closereceivechannel(s, sub->callid);
+			transmit_stopmediatransmission(s, sub->callid);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, l->instance);
 			transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
 			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
 		} else if ((l->type = TYPE_LINE) && (l->hookstate == SKINNY_ONHOOK)) {
 			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_closereceivechannel(s, sub->callid);
+			transmit_stopmediatransmission(s, sub->callid);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, l->instance);
 			transmit_ringer_mode(s, SKINNY_RING_OFF);
 			transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
 			do_housekeeping(s);
@@ -2775,10 +2810,10 @@
 
 	transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
 	/* order matters here...
-	   for some reason, transmit_callinfo must be before transmit_callstate,
+	   for some reason, transmit_callinfo must be before change_callstate,
 	   or you won't get keypad messages in some situations. */
 	transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2);
-	transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
+	transmit_callstatemessage(s, l->instance, SKINNY_CONNECTED, sub->callid);
 	transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
 	transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
 	return res;
@@ -2972,7 +3007,7 @@
 		if (ast->_state != AST_STATE_UP) {
 			if (!sub->progress) {
 				transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
-				transmit_callstate(s, l->instance, SKINNY_RINGOUT, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_RINGOUT, sub->callid);
 				transmit_dialednumber(s, exten, l->instance, sub->callid);
 				transmit_displaypromptstatus(s, "Ring Out", 0, l->instance, sub->callid);
 				transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
@@ -2984,7 +3019,7 @@
 	case AST_CONTROL_BUSY:
 		if (ast->_state != AST_STATE_UP) {
 			transmit_tone(s, SKINNY_BUSYTONE, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_BUSY, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_BUSY, sub->callid);
 			sub->alreadygone = 1;
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
@@ -2993,7 +3028,7 @@
 	case AST_CONTROL_CONGESTION:
 		if (ast->_state != AST_STATE_UP) {
 			transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_CONGESTION, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_CONGESTION, sub->callid);
 			sub->alreadygone = 1;
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
@@ -3002,7 +3037,7 @@
 	case AST_CONTROL_PROGRESS:
 		if ((ast->_state != AST_STATE_UP) && !sub->progress && !sub->outgoing) {
 			transmit_tone(s, SKINNY_ALERT, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_PROGRESS, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_PROGRESS, sub->callid);
 			transmit_displaypromptstatus(s, "Call Progress", 0, l->instance, sub->callid);
 			transmit_callinfo(s, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
 			sub->progress = 1;
@@ -3358,7 +3393,13 @@
 			ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n");
 			l->hookstate = SKINNY_ONHOOK;
 			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
-			transmit_callstate(s, l->instance, SKINNY_ONHOOK, instance);
+			transmit_closereceivechannel(s, sub->callid);
+			transmit_stopmediatransmission(s, sub->callid);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, l->instance);
 			break;
 		}
 
@@ -3370,7 +3411,8 @@
 			l = sub->parent;
 			if (l->hookstate == SKINNY_ONHOOK) {
 				l->hookstate = SKINNY_OFFHOOK;
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 			}
 			if (skinnydebug)
 				ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
@@ -3411,7 +3453,8 @@
 			if (l->hookstate == SKINNY_ONHOOK) {
 				l->hookstate = SKINNY_OFFHOOK;
 				transmit_speaker_mode(s, SKINNY_SPEAKERON);
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 			}
 			if (skinnydebug)
 				ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
@@ -3479,7 +3522,8 @@
 			if (l->hookstate == SKINNY_ONHOOK){
 				l->hookstate = SKINNY_OFFHOOK;
 				transmit_speaker_mode(s, SKINNY_SPEAKERON);
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 			}
 
 			if (skinnydebug)
@@ -3563,9 +3607,10 @@
 		if (sub && sub->outgoing) {
 			/* We're answering a ringing call */
 			ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
-			transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_activatecallplane(s, l->instance);
 			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_CONNECTED, sub->callid);
 			transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
 			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
 			start_rtp(sub);
@@ -3577,7 +3622,8 @@
 				c = skinny_new(l, AST_STATE_DOWN);
 				if (c) {
 					sub = c->tech_pvt;
-					transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+					transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+					transmit_activatecallplane(s, l->instance);
 					if (skinnydebug)
 						ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
 					transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
@@ -3643,9 +3689,10 @@
 	if (sub && sub->outgoing) {
 		/* We're answering a ringing call */
 		ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
-		transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_activatecallplane(s, l->instance);
 		transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-		transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
+		transmit_callstatemessage(s, l->instance, SKINNY_CONNECTED, sub->callid);
 		transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
 		start_rtp(sub);
 		ast_setstate(sub->owner, AST_STATE_UP);
@@ -3656,7 +3703,8 @@
 			c = skinny_new(l, AST_STATE_DOWN);
 			if (c) {
 				sub = c->tech_pvt;
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 				if (skinnydebug)
 					ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
 				transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
@@ -3707,7 +3755,13 @@
 	}
 
 	sub->cxmode = SKINNY_CX_RECVONLY;
-	transmit_callstate(s, l->instance, l->hookstate, sub->callid);
+	transmit_closereceivechannel(s, sub->callid);
+	transmit_stopmediatransmission(s, sub->callid);
+	transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+	transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+	transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+	transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+	transmit_activatecallplane(s, l->instance);
 	if (skinnydebug)
 		ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
 	if (l->transfer && (sub->owner && sub->next && sub->next->owner) && ((!sub->outgoing) || (sub->next && !sub->next->outgoing))) {
@@ -4139,7 +4193,8 @@
 		l->hookstate = SKINNY_OFFHOOK;
 
 		sub = c->tech_pvt;
-		transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_activatecallplane(s, l->instance);
 		if (skinnydebug)
 			ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
 		transmit_displaymessage(s, NULL, l->instance, sub->callid); /* clear display */
@@ -4238,7 +4293,14 @@
 			ast_log(LOG_WARNING, "Attempted redial, but no previously dialed number found.\n");
 			l->hookstate = SKINNY_ONHOOK;
 			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
-			transmit_callstate(s, l->instance, SKINNY_ONHOOK, instance);
+			transmit_closereceivechannel(s, sub->callid);
+			transmit_stopmediatransmission(s, sub->callid);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, l->instance);
+			// change_callstate(s, l->instance, SKINNY_ONHOOK, instance); Should we use instance instead of sub->callid???
 			break;
 		}
 
@@ -4255,7 +4317,8 @@
 			if (l->hookstate == SKINNY_ONHOOK) {
 				l->hookstate = SKINNY_OFFHOOK;
 				transmit_speaker_mode(s, SKINNY_SPEAKERON);
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 			}
 			if (skinnydebug)
 				ast_verbose("Attempting to Clear display on Skinny %s@%s\n", l->name, d->name);
@@ -4295,7 +4358,8 @@
 			if (l->hookstate == SKINNY_ONHOOK) {
 				l->hookstate = SKINNY_OFFHOOK;
 				transmit_speaker_mode(s, SKINNY_SPEAKERON);
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(s, l->instance);
 			}
 
 			if (skinnydebug)
@@ -4369,7 +4433,13 @@
 		if (sub) {
 			sub->cxmode = SKINNY_CX_RECVONLY;
 			l->hookstate = SKINNY_ONHOOK;
-			transmit_callstate(s, l->instance, l->hookstate, sub->callid);
+			transmit_closereceivechannel(s, sub->callid);
+			transmit_stopmediatransmission(s, sub->callid);
+			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(s, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(s, l->instance);
 			if (skinnydebug)
 				ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
 			if (l->transfer && (sub->owner && sub->next && sub->next->owner) && ((!sub->outgoing) || (sub->next && !sub->next->outgoing))) {
@@ -4419,9 +4489,10 @@
 		if (sub && sub->outgoing) {
 			/* We're answering a ringing call */
 			ast_queue_control(sub->owner, AST_CONTROL_ANSWER);
-			transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_activatecallplane(s, l->instance);
 			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
+			transmit_callstatemessage(s, l->instance, SKINNY_CONNECTED, sub->callid);
 			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
 			start_rtp(sub);
 			ast_setstate(sub->owner, AST_STATE_UP);
