Index: channels/chan_skinny.c
===================================================================
--- channels/chan_skinny.c	(revision 78336)
+++ channels/chan_skinny.c	(working copy)
@@ -1587,8 +1587,9 @@
 	return -1; /* main loop will destroy the session */
 }
 
-static int transmit_response(struct skinnysession *s, struct skinny_req *req)
+static int transmit_response(struct skinny_device *d, struct skinny_req *req)
 {
+	struct skinnysession *s = d->session;
 	int res = 0;
 
 	if (!s) {
@@ -1626,7 +1627,7 @@
 	return 1;
 }
 
-static void transmit_speaker_mode(struct skinnysession *s, int mode)
+static void transmit_speaker_mode(struct skinny_device *d, int mode)
 {
 	struct skinny_req *req;
 
@@ -1634,10 +1635,10 @@
 		return;
 
 	req->data.setspeaker.mode = htolel(mode);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 /*
-static void transmit_microphone_mode(struct skinnysession *s, int mode)
+static void transmit_microphone_mode(skinny_device *d, int mode)
 {
 	struct skinny_req *req;
 
@@ -1645,11 +1646,11 @@
 		return;
 
 	req->data.setmicrophone.mode = htolel(mode);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 */
 
-static void transmit_callinfo(struct skinnysession *s, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
+static void transmit_callinfo(struct skinny_device *d, const char *fromname, const char *fromnum, const char *toname, const char *tonum, int instance, int callid, int calltype)
 {
 	struct skinny_req *req;
 
@@ -1657,7 +1658,7 @@
 		return;
 
 	if (skinnydebug)
-			ast_verbose("Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, s->device->name, instance);
+			ast_verbose("Setting Callinfo to %s(%s) from %s(%s) on %s(%d)\n", fromname, fromnum, toname, tonum, d->name, instance);
 
 	if (fromname) {
 		ast_copy_string(req->data.callinfo.callingPartyName, fromname, sizeof(req->data.callinfo.callingPartyName));
@@ -1674,10 +1675,10 @@
 	req->data.callinfo.instance = htolel(instance);
 	req->data.callinfo.reference = htolel(callid);
 	req->data.callinfo.type = htolel(calltype);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_connect(struct skinnysession *s, struct skinny_subchannel *sub)
+static void transmit_connect(struct skinny_device *d, struct skinny_subchannel *sub)
 {
 	struct skinny_req *req;
 	struct skinny_line *l = sub->parent;
@@ -1694,10 +1695,10 @@
 	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
 	req->data.openreceivechannel.echo = htolel(0);
 	req->data.openreceivechannel.bitrate = htolel(0);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_tone(struct skinnysession *s, int tone, int instance, int reference)
+static void transmit_tone(struct skinny_device *d, int tone, int instance, int reference)
 {
 	struct skinny_req *req;
 
@@ -1722,10 +1723,10 @@
 	if (tone > 0) {
 		req->data.starttone.tone = htolel(tone);
 	}
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_selectsoftkeys(struct skinnysession *s, int instance, int callid, int softkey)
+static void transmit_selectsoftkeys(struct skinny_device *d, int instance, int callid, int softkey)
 {
 	struct skinny_req *req;
 
@@ -1736,10 +1737,10 @@
 	req->data.selectsoftkey.reference = htolel(callid);
 	req->data.selectsoftkey.softKeySetIndex = htolel(softkey);
 	req->data.selectsoftkey.validKeyMask = htolel(0xFFFFFFFF);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_lamp_indication(struct skinnysession *s, int stimulus, int instance, int indication)
+static void transmit_lamp_indication(struct skinny_device *d, int stimulus, int instance, int indication)
 {
 	struct skinny_req *req;
 
@@ -1749,10 +1750,10 @@
 	req->data.setlamp.stimulus = htolel(stimulus);
 	req->data.setlamp.stimulusInstance = htolel(instance);
 	req->data.setlamp.deviceStimulus = htolel(indication);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_ringer_mode(struct skinnysession *s, int mode)
+static void transmit_ringer_mode(struct skinny_device *d, int mode)
 {
 	struct skinny_req *req;
 
@@ -1774,10 +1775,10 @@
 	/* XXX the value here doesn't seem to change anything.  Must be higher than 0.
 	   Perhaps a packet capture can shed some light on this. */
 	req->data.setringer.unknown2 = htolel(1);
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_displaymessage(struct skinnysession *s, const char *text, int instance, int reference)
+static void transmit_displaymessage(struct skinny_device *d, const char *text, int instance, int reference)
 {
 	struct skinny_req *req;
 
@@ -1799,10 +1800,10 @@
 			ast_verbose("Displaying message '%s'\n", req->data.displaytext.text);
 	}
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_displaynotify(struct skinnysession *s, const char *text, int t)
+static void transmit_displaynotify(struct skinny_device *d, const char *text, int t)
 {
 	struct skinny_req *req;
 
@@ -1815,10 +1816,10 @@
 	if (skinnydebug)
 		ast_verbose("Displaying notify '%s'\n", text);
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_displaypromptstatus(struct skinnysession *s, const char *text, int t, int instance, int callid)
+static void transmit_displaypromptstatus(struct skinny_device *d, const char *text, int t, int instance, int callid)
 {
 	struct skinny_req *req;
 
@@ -1844,10 +1845,10 @@
 			ast_verbose("Displaying Prompt Status '%s'\n", text);
 	}
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_dialednumber(struct skinnysession *s, const char *text, int instance, int callid)
+static void transmit_dialednumber(struct skinny_device *d, const char *text, int instance, int callid)
 {
 	struct skinny_req *req;
 
@@ -1858,102 +1859,124 @@
 	req->data.dialednumber.lineInstance = htolel(instance);
 	req->data.dialednumber.callReference = htolel(callid);
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 }
 
-static void transmit_callstate(struct skinnysession *s, int instance, int state, unsigned callid)
+static void transmit_closereceivechannel(struct skinny_device *d, 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(d, req);
+}
 
-		req->data.stopmedia.conferenceId = htolel(callid);
-		req->data.stopmedia.passThruPartyId = htolel(callid);
-		transmit_response(s, req);
+static void transmit_stopmediatransmission(struct skinny_device *d, 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(d, req);
+}
 
+static void transmit_callstatemessage(struct skinny_device *d, int instance, int state, unsigned callid)
+{
+	struct skinny_req *req;
+
 	if (!(req = req_alloc(sizeof(struct call_state_message), CALL_STATE_MESSAGE)))
 		return;
 
 	req->data.callstate.callState = htolel(state);
 	req->data.callstate.lineInstance = htolel(instance);
 	req->data.callstate.callReference = htolel(callid);
-	transmit_response(s, req);
+	transmit_response(d, req);
+}
 
-	if (state == SKINNY_ONHOOK) {
-		transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
-	}
+static void transmit_activatecallplane(struct skinny_device *d, 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(d, req);
 }
 
 static int skinny_extensionstate_cb(char *context, char *exten, int state, void *data)
 {
 	struct skinny_speeddial *sd = data;
 	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(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(d, 0);
+			transmit_stopmediatransmission(d, 0);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(d, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, 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(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(d, 0);
+			transmit_stopmediatransmission(d, 0);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(d, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, sd->instance);
+			break;
+		case AST_EXTENSION_RINGING:
+		case AST_EXTENSION_UNAVAILABLE:
+			transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_BLINK);
+			transmit_callstatemessage(d, 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(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_ON);
+			transmit_callstatemessage(d, sd->instance, SKINNY_CALLREMOTEMULTILINE, 0);
+			break;
+		case AST_EXTENSION_ONHOLD:
+			transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_WINK);
+			transmit_callstatemessage(d, sd->instance, SKINNY_HOLD, 0);
+			break;
+		case AST_EXTENSION_NOT_INUSE:
+		default:
+			transmit_lamp_indication(d, STIMULUS_LINE, sd->instance, SKINNY_LAMP_OFF);
+			transmit_closereceivechannel(d, 0);
+			transmit_stopmediatransmission(d, 0);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, sd->instance, 0);
+			transmit_callstatemessage(d, sd->instance, SKINNY_ONHOOK, 0);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, sd->instance);
+			break;
+		}
 	}
 
-	transmit_lamp_indication(s, STIMULUS_LINE, sd->instance, lamp);
-	transmit_callstate(s, sd->instance, callstate, 0);
 	sd->laststate = state;
 
 	return 0;
@@ -1983,17 +2006,17 @@
 			ast_app_inboxcount(l->mailbox, &new, &old);
 			if (skinnydebug)
 				ast_verbose("Skinny %s@%s has voicemail!\n", l->name, d->name);
-			transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
+			transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, l->mwiblink?SKINNY_LAMP_BLINK:SKINNY_LAMP_ON);
 			device_lamp++;
 		} else {
-			transmit_lamp_indication(s, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);
+			transmit_lamp_indication(d, STIMULUS_VOICEMAIL, l->instance, SKINNY_LAMP_OFF);
 		}
 	}
 	/* If at least one line has VM, turn the device level lamp on */
 	if (device_lamp)
-		transmit_lamp_indication(s, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_ON);
+		transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_ON);
 	else
-		transmit_lamp_indication(s, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF);
+		transmit_lamp_indication(d, STIMULUS_VOICEMAIL, 0, SKINNY_LAMP_OFF);
 }
 
 /* I do not believe skinny can deal with video.
@@ -2107,7 +2130,7 @@
 				req->data.reset.resetType = 1;
 
 			ast_verb(3, "%s device %s.\n", (fullrestart) ? "Restarting" : "Resetting", d->id);
-			transmit_response(d->session, req);
+			transmit_response(d, req);
 		}
 	}
 	ast_mutex_unlock(&devicelock);
@@ -2531,7 +2554,7 @@
 		ast_rtp_codec_setpref(sub->rtp, &l->prefs);
 
 	/* Create the RTP connection */
-	transmit_connect(d->session, sub);
+	transmit_connect(d, sub);
  	ast_mutex_unlock(&sub->lock);
 }
 
@@ -2541,7 +2564,6 @@
 	struct skinny_subchannel *sub = c->tech_pvt;
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 	int res = 0;
 
 	ast_copy_string(l->lastnumberdialed, c->exten, sizeof(l->lastnumberdialed));
@@ -2553,7 +2575,7 @@
 	res = ast_pbx_run(c);
 	if (res) {
 		ast_log(LOG_WARNING, "PBX exited non-zero\n");
-		transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
+		transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid);
 	}
 	return NULL;
 }
@@ -2564,7 +2586,6 @@
 	struct skinny_subchannel *sub = c->tech_pvt;
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 	int len = 0;
 	int timeout = firstdigittimeout;
 	int res = 0;
@@ -2591,7 +2612,7 @@
 		len = strlen(d->exten);
 
 		if (!ast_ignore_pattern(c->context, d->exten)) {
-			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+			transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 		}
 		if (ast_exists_extension(c, c->context, d->exten, 1, l->cid_num)) {
 			if (!res || !ast_matchmore_extension(c, c->context, d->exten, 1, l->cid_num)) {
@@ -2600,7 +2621,7 @@
 					ast_copy_string(l->call_forward, d->exten, sizeof(l->call_forward));
 					ast_verb(3, "Setting call forward to '%s' on channel %s\n",
 							l->call_forward, c->name);
-					transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
+					transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
 					if (res) {
 						break;
 					}
@@ -2608,7 +2629,7 @@
 					ast_indicate(c, -1);
  					ast_safe_sleep(c, 1000);
 					memset(d->exten, 0, sizeof(d->exten));
-					transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
+					transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
 					len = 0;
 					getforward = 0;
 				} else {
@@ -2626,7 +2647,7 @@
 		} else if (res == 0) {
 			ast_debug(1, "Not enough digits (%s) (and no ambiguous match)...\n", d->exten);
 			memset(d->exten, 0, sizeof(d->exten));
-			transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
+			transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid);
 			if (sub->owner && sub->owner->_state != AST_STATE_UP) {
 				ast_indicate(c, -1);
 				ast_hangup(c);
@@ -2636,7 +2657,7 @@
 			   ((d->exten[0] != '*') || (!ast_strlen_zero(d->exten) > 2))) {
 			ast_log(LOG_WARNING, "Can't match [%s] from '%s' in context %s\n", d->exten, c->cid.cid_num ? c->cid.cid_num : "<Unknown Caller>", c->context);
 			memset(d->exten, 0, sizeof(d->exten));
-			transmit_tone(s, SKINNY_REORDER, l->instance, sub->callid);
+			transmit_tone(d, SKINNY_REORDER, l->instance, sub->callid);
 			/* hang out for 3 seconds to let congestion play */
 			ast_safe_sleep(c, 3000);
 			break;
@@ -2663,7 +2684,6 @@
 	struct skinny_subchannel *sub = ast->tech_pvt;
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 
 	if (!d->registered) {
 		ast_log(LOG_ERROR, "Device not registered, cannot call %s\n", dest);
@@ -2695,12 +2715,12 @@
 		break;
 	}
 
-	transmit_callstate(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);
-	transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
-	transmit_ringer_mode(s, SKINNY_RING_INSIDE);
+	transmit_callstatemessage(d, l->instance, SKINNY_RINGIN, sub->callid);
+	transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGIN);
+	transmit_displaypromptstatus(d, "Ring-In", 0, l->instance, sub->callid);
+	transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, l->cid_name, l->cid_num, l->instance, sub->callid, 1);
+	transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_BLINK);
+	transmit_ringer_mode(d, SKINNY_RING_INSIDE);
 
 	ast_setstate(ast, AST_STATE_RINGING);
 	ast_queue_control(ast, AST_CONTROL_RINGING);
@@ -2728,14 +2748,26 @@
 	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_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
-			transmit_speaker_mode(s, SKINNY_SPEAKEROFF);
+			transmit_closereceivechannel(d, sub->callid);
+			transmit_stopmediatransmission(d, sub->callid);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, l->instance);
+			transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
+			transmit_speaker_mode(d, 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_ringer_mode(s, SKINNY_RING_OFF);
-			transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
+			transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
+			transmit_closereceivechannel(d, sub->callid);
+			transmit_stopmediatransmission(d, sub->callid);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, l->instance);
+			transmit_ringer_mode(d, SKINNY_RING_OFF);
+			transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_OFF);
 			do_housekeeping(s);
 		}
 	}
@@ -2758,7 +2790,6 @@
 	struct skinny_subchannel *sub = ast->tech_pvt;
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 	char exten[AST_MAX_EXTENSION] = "";
 
 	ast_copy_string(exten, S_OR(ast->macroexten, ast->exten), sizeof(exten));
@@ -2773,14 +2804,14 @@
 		ast_setstate(ast, AST_STATE_UP);
 	}
 
-	transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+	transmit_tone(d, 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_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
-	transmit_displaypromptstatus(s, "Connected", 0, l->instance, sub->callid);
+	transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2);
+	transmit_callstatemessage(d, l->instance, SKINNY_CONNECTED, sub->callid);
+	transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
+	transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
 	return res;
 }
 
@@ -2896,7 +2927,7 @@
 	int tmp;
 	/* not right */
 	sprintf(tmp, "%d", digit);
-	transmit_tone(d->session, digit, l->instance, sub->callid);
+	transmit_tone(d, digit, l->instance, sub->callid);
 #endif
 	return -1; /* Stop inband indications */
 }
@@ -2971,11 +3002,11 @@
 	case AST_CONTROL_RINGING:
 		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_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 */
+				transmit_tone(d, SKINNY_ALERT, l->instance, sub->callid);
+				transmit_callstatemessage(d, l->instance, SKINNY_RINGOUT, sub->callid);
+				transmit_dialednumber(d, exten, l->instance, sub->callid);
+				transmit_displaypromptstatus(d, "Ring Out", 0, l->instance, sub->callid);
+				transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
 				sub->ringing = 1;
 				break;
 			}
@@ -2983,8 +3014,8 @@
 		return -1;
 	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_tone(d, SKINNY_BUSYTONE, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_BUSY, sub->callid);
 			sub->alreadygone = 1;
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
@@ -2992,8 +3023,8 @@
 		return -1;
 	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_tone(d, SKINNY_REORDER, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_CONGESTION, sub->callid);
 			sub->alreadygone = 1;
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
@@ -3001,16 +3032,16 @@
 		return -1;
 	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_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 */
+			transmit_tone(d, SKINNY_ALERT, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_PROGRESS, sub->callid);
+			transmit_displaypromptstatus(d, "Call Progress", 0, l->instance, sub->callid);
+			transmit_callinfo(d, ast->cid.cid_name, ast->cid.cid_num, exten, exten, l->instance, sub->callid, 2); /* 2 = outgoing from phone */
 			sub->progress = 1;
 			break;
 		}
 		return -1;
 	case -1:
-		transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+		transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 		break;
 	case AST_CONTROL_HOLD:
 		ast_moh_start(ast, data, l->mohinterpret);
@@ -3122,7 +3153,6 @@
 {
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 	struct skinny_req *req;
 
 	/* Don't try to hold a channel that doesn't exist */
@@ -3141,23 +3171,23 @@
 		return 0;
 
 	req->data.activatecallplane.lineInstance = htolel(l->instance);
-	transmit_response(s, req);
+	transmit_response(d, req);
 
 	if (!(req = req_alloc(sizeof(struct close_receive_channel_message), CLOSE_RECEIVE_CHANNEL_MESSAGE)))
 		return 0;
 
 	req->data.closereceivechannel.conferenceId = htolel(sub->callid);
 	req->data.closereceivechannel.partyId = htolel(sub->callid);
-	transmit_response(s, req);
+	transmit_response(d, req);
 
 	if (!(req = req_alloc(sizeof(struct stop_media_transmission_message), STOP_MEDIA_TRANSMISSION_MESSAGE)))
 		return 0;
 
 	req->data.stopmedia.conferenceId = htolel(sub->callid);
 	req->data.stopmedia.passThruPartyId = htolel(sub->callid);
-	transmit_response(s, req);
+	transmit_response(d, req);
 
-	transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK);
+	transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_WINK);
 	sub->onhold = 1;
 	return 1;
 }
@@ -3166,7 +3196,6 @@
 {
 	struct skinny_line *l = sub->parent;
 	struct skinny_device *d = l->parent;
-	struct skinnysession *s = d->session;
 	struct skinny_req *req;
 
 	/* Don't try to unhold a channel that doesn't exist */
@@ -3183,10 +3212,10 @@
 		return 0;
 
 	req->data.activatecallplane.lineInstance = htolel(l->instance);
-	transmit_response(s, req);
+	transmit_response(d, req);
 
-	transmit_connect(s, sub);
-	transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
+	transmit_connect(d, sub);
+	transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
 	sub->onhold = 0;
 	return 1;
 }
@@ -3196,13 +3225,14 @@
 	if (!(req = req_alloc(0, KEEP_ALIVE_ACK_MESSAGE)))
 		return -1;
 
-	transmit_response(s, req);
+	transmit_response(s->device, req);
 	do_housekeeping(s);
 	return 1;
 }
 
 static int handle_register_message(struct skinny_req *req, struct skinnysession *s)
 {
+	struct skinny_device *d = s->device;
 	char name[16];
 	int res;
 
@@ -3215,7 +3245,7 @@
 			return -1;
 
 		snprintf(req->data.regrej.errMsg, sizeof(req->data.regrej.errMsg), "No Authority: %s", name);
-		transmit_response(s, req);
+		transmit_response(d, req);
 		return 0;
 	}
 	ast_verb(3, "Device '%s' successfully registered\n", name);
@@ -3230,14 +3260,14 @@
 	req->data.regack.res2[0] = '0';
 	req->data.regack.res2[1] = '\0';
 	req->data.regack.secondaryKeepAlive = htolel(keep_alive);
-	transmit_response(s, req);
+	transmit_response(d, req);
 	if (skinnydebug)
 		ast_verbose("Requesting capabilities\n");
 
 	if (!(req = req_alloc(0, CAPABILITIES_REQ_MESSAGE)))
 		return -1;
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 
 	return res;
 }
@@ -3357,8 +3387,14 @@
 		if (ast_strlen_zero(l->lastnumberdialed)) {
 			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_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_closereceivechannel(d, sub->callid);
+			transmit_stopmediatransmission(d, sub->callid);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, l->instance);
 			break;
 		}
 
@@ -3370,16 +3406,17 @@
 			l = sub->parent;
 			if (l->hookstate == SKINNY_ONHOOK) {
 				l->hookstate = SKINNY_OFFHOOK;
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-			transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
+			transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+			transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
 
 			if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
-				transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+				transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 			}
 			ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
 			if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -3410,17 +3447,18 @@
 			l = sub->parent;
 			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_speaker_mode(d, SKINNY_SPEAKERON);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-			transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
+			transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+			transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
 
 			if (!ast_ignore_pattern(c->context, sd->exten)) {
-				transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+				transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 			}
 			if (ast_exists_extension(c, c->context, sd->exten, 1, l->cid_num)) {
 				ast_copy_string(c->exten, sd->exten, sizeof(c->exten));
@@ -3478,19 +3516,20 @@
 
 			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_speaker_mode(d, SKINNY_SPEAKERON);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-			transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
+			transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+			transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
 
 			if (!ast_ignore_pattern(c->context, vmexten)) {
-				transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+				transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 			}
 
 			if (ast_exists_extension(c, c->context, l->vmexten, 1, l->cid_num)) {
@@ -3519,13 +3558,13 @@
 		if (l->dnd != 0){
 			ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
 			l->dnd = 0;
-			transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
-			transmit_displaynotify(s, "DnD disabled", 10);
+			transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
+			transmit_displaynotify(d, "DnD disabled", 10);
 		} else {
 			ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
 			l->dnd = 1;
-			transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
-			transmit_displaynotify(s, "DnD enabled", 10);
+			transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
+			transmit_displaynotify(d, "DnD enabled", 10);
 		}
 		break;
 	case STIMULUS_FORWARDBUSY:
@@ -3552,9 +3591,9 @@
 		}
 
 		/* turn the speaker on */
-		transmit_speaker_mode(s, SKINNY_SPEAKERON);
-		transmit_ringer_mode(s, SKINNY_RING_OFF);
-		transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
+		transmit_speaker_mode(d, SKINNY_SPEAKERON);
+		transmit_ringer_mode(d, SKINNY_RING_OFF);
+		transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
 
 		l->hookstate = SKINNY_OFFHOOK;
 
@@ -3563,11 +3602,12 @@
 		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_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-			transmit_callstate(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);
+			transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_activatecallplane(d, l->instance);
+			transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_CONNECTED, sub->callid);
+			transmit_displaypromptstatus(d, "Connected", 0, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
 			start_rtp(sub);
 			ast_setstate(sub->owner, AST_STATE_UP);
 		} else {
@@ -3577,12 +3617,13 @@
 				c = skinny_new(l, AST_STATE_DOWN);
 				if (c) {
 					sub = c->tech_pvt;
-					transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+					transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+					transmit_activatecallplane(d, 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 */
-					transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-					transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
+					transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+					transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+					transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
 					/* start the switch thread */
 					if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
@@ -3629,7 +3670,7 @@
 		l = sub->parent;
 	}
 
-	transmit_ringer_mode(s, SKINNY_RING_OFF);
+	transmit_ringer_mode(d, SKINNY_RING_OFF);
 	l->hookstate = SKINNY_OFFHOOK;
 
 	ast_device_state_changed("Skinny/%s@%s", l->name, d->name);
@@ -3638,15 +3679,16 @@
 		return 1;
 	}
 
-	transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
+	transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
 
 	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_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-		transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
-		transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
+		transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_activatecallplane(d, l->instance);
+		transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
+		transmit_callstatemessage(d, l->instance, SKINNY_CONNECTED, sub->callid);
+		transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
 		start_rtp(sub);
 		ast_setstate(sub->owner, AST_STATE_UP);
 	} else {
@@ -3656,12 +3698,13 @@
 			c = skinny_new(l, AST_STATE_DOWN);
 			if (c) {
 				sub = c->tech_pvt;
-				transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-				transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-				transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
+				transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+				transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+				transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
 				/* start the switch thread */
 				if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
@@ -3707,7 +3750,13 @@
 	}
 
 	sub->cxmode = SKINNY_CX_RECVONLY;
-	transmit_callstate(s, l->instance, l->hookstate, sub->callid);
+	transmit_closereceivechannel(d, sub->callid);
+	transmit_stopmediatransmission(d, sub->callid);
+	transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+	transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+	transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+	transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+	transmit_activatecallplane(d, 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))) {
@@ -3794,7 +3843,7 @@
 	snprintf(req->data.speeddial.speedDialDirNumber, sizeof(req->data.speeddial.speedDialDirNumber), sd->exten);
 	snprintf(req->data.speeddial.speedDialDisplayName, sizeof(req->data.speeddial.speedDialDisplayName), sd->label);
 
-	transmit_response(s, req);
+	transmit_response(d, req);
 	return 1;
 }
 
@@ -3832,7 +3881,7 @@
 		memcpy(req->data.linestat.lineDirNumber, l->name, sizeof(req->data.linestat.lineDirNumber));
 		memcpy(req->data.linestat.lineDisplayName, l->label, sizeof(req->data.linestat.lineDisplayName));
 	}
-	transmit_response(s,req);
+	transmit_response(d,req);
 	return 1;
 }
 
@@ -3854,7 +3903,7 @@
 	req->data.definetimedate.seconds = htolel(cmtime.tm_sec);
 	req->data.definetimedate.milliseconds = htolel(cmtime.tm_usec / 1000);
 	req->data.definetimedate.timestamp = htolel(tv.tv_sec);
-	transmit_response(s, req);
+	transmit_response(s->device, req);
 	return 1;
 }
 
@@ -4002,7 +4051,7 @@
 		ast_verbose("Sending %d template to %s\n",
 					d->type,
 					d->name);
-	transmit_response(s, req);
+	transmit_response(d, req);
 	return 1;
 }
 
@@ -4013,7 +4062,7 @@
 		return -1;
 
 	snprintf(req->data.version.version, sizeof(req->data.version.version), d->version_id);
-	transmit_response(s, req);
+	transmit_response(d, req);
 	return 1;
 }
 
@@ -4027,7 +4076,7 @@
 			sizeof(req->data.serverres.server[0].serverName));
 	req->data.serverres.serverListenPort[0] = htolel(ourport);
 	req->data.serverres.serverIpAddr[0] = htolel(d->ourip.s_addr);
-	transmit_response(s, req);
+	transmit_response(d, req);
 	return 1;
 }
 
@@ -4104,7 +4153,7 @@
 	req->data.startmedia.qualifier.vad = htolel(0);
 	req->data.startmedia.qualifier.packets = htolel(0);
 	req->data.startmedia.qualifier.bitRate = htolel(0);
-	transmit_response(s, req);
+	transmit_response(d, req);
 
 	return 1;
 }
@@ -4139,14 +4188,15 @@
 		l->hookstate = SKINNY_OFFHOOK;
 
 		sub = c->tech_pvt;
-		transmit_callstate(s, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+		transmit_activatecallplane(d, 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 */
-		transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
+		transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+		transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
 
 		if (!ast_ignore_pattern(c->context, req->data.enbloccallmessage.calledParty)) {
-			transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+			transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 		}
 		ast_copy_string(c->exten, req->data.enbloccallmessage.calledParty, sizeof(c->exten));
 		if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -4186,8 +4236,8 @@
 		}
 		softkeymode++;
 	}
-	transmit_response(s,req);
-	transmit_selectsoftkeys(s, 0, 0, KEYDEF_ONHOOK);
+	transmit_response(s->device,req);
+	transmit_selectsoftkeys(s->device, 0, 0, KEYDEF_ONHOOK);
 	return 1;
 }
 
@@ -4237,8 +4287,15 @@
 		if (ast_strlen_zero(l->lastnumberdialed)) {
 			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_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_closereceivechannel(d, sub->callid);
+			transmit_stopmediatransmission(d, sub->callid);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, l->instance);
+			// change_callstate(d, l->instance, SKINNY_ONHOOK, instance); Should we use instance instead of sub->callid???
 			break;
 		}
 
@@ -4254,17 +4311,18 @@
 			sub = c->tech_pvt;
 			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_speaker_mode(d, SKINNY_SPEAKERON);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-			transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_RINGOUT);
+			transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+			transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_RINGOUT);
 
 			if (!ast_ignore_pattern(c->context, l->lastnumberdialed)) {
-				transmit_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
+				transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
 			}
 			ast_copy_string(c->exten, l->lastnumberdialed, sizeof(c->exten));
 			if (ast_pthread_create(&t, NULL, skinny_newcall, c)) {
@@ -4283,8 +4341,8 @@
 			c = sub->owner;
 		}
 
-		/* transmit_ringer_mode(s,SKINNY_RING_OFF);
-		transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */
+		/* transmit_ringer_mode(d,SKINNY_RING_OFF);
+		transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON); */
 
 		/* l->hookstate = SKINNY_OFFHOOK; */
 
@@ -4294,15 +4352,16 @@
 			sub = c->tech_pvt;
 			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_speaker_mode(d, SKINNY_SPEAKERON);
+				transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+				transmit_activatecallplane(d, 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 */
-			transmit_tone(s, SKINNY_DIALTONE, l->instance, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_OFFHOOK);
+			transmit_displaymessage(d, NULL, l->instance, sub->callid); /* clear display */
+			transmit_tone(d, SKINNY_DIALTONE, l->instance, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_OFFHOOK);
 
 			/* start the switch thread */
 			if (ast_pthread_create(&t, NULL, skinny_ss, c)) {
@@ -4337,13 +4396,13 @@
 		if (l->dnd != 0){
 			ast_verb(3, "Disabling DND on %s@%s\n", l->name, d->name);
 			l->dnd = 0;
-			transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
-			transmit_displaynotify(s, "DnD disabled", 10);
+			transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_ON);
+			transmit_displaynotify(d, "DnD disabled", 10);
 		} else {
 			ast_verb(3, "Enabling DND on %s@%s\n", l->name, d->name);
 			l->dnd = 1;
-			transmit_lamp_indication(s, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
-			transmit_displaynotify(s, "DnD enabled", 10);
+			transmit_lamp_indication(d, STIMULUS_FORWARDALL, 1, SKINNY_LAMP_OFF);
+			transmit_displaynotify(d, "DnD enabled", 10);
 		}
 		break;
 	case SOFTKEY_CFWDBUSY:
@@ -4369,7 +4428,13 @@
 		if (sub) {
 			sub->cxmode = SKINNY_CX_RECVONLY;
 			l->hookstate = SKINNY_ONHOOK;
-			transmit_callstate(s, l->instance, l->hookstate, sub->callid);
+			transmit_closereceivechannel(d, sub->callid);
+			transmit_stopmediatransmission(d, sub->callid);
+			transmit_speaker_mode(d, SKINNY_SPEAKEROFF);
+			transmit_displaypromptstatus(d, NULL, 0, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_ONHOOK, sub->callid);
+			transmit_selectsoftkeys(d, 0, 0, KEYDEF_ONHOOK);
+			transmit_activatecallplane(d, 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))) {
@@ -4411,18 +4476,19 @@
 		if (skinnydebug)
 			ast_verbose("Received Softkey Event: Answer(%d/%d)\n", instance, callreference);
 
-		transmit_ringer_mode(s,SKINNY_RING_OFF);
-		transmit_lamp_indication(s, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
+		transmit_ringer_mode(d,SKINNY_RING_OFF);
+		transmit_lamp_indication(d, STIMULUS_LINE, l->instance, SKINNY_LAMP_ON);
 
 		l->hookstate = SKINNY_OFFHOOK;
 
 		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_tone(s, SKINNY_SILENCE, l->instance, sub->callid);
-			transmit_callstate(s, l->instance, SKINNY_CONNECTED, sub->callid);
-			transmit_selectsoftkeys(s, l->instance, sub->callid, KEYDEF_CONNECTED);
+			transmit_callstatemessage(d, l->instance, SKINNY_OFFHOOK, sub->callid);
+			transmit_activatecallplane(d, l->instance);
+			transmit_tone(d, SKINNY_SILENCE, l->instance, sub->callid);
+			transmit_callstatemessage(d, l->instance, SKINNY_CONNECTED, sub->callid);
+			transmit_selectsoftkeys(d, l->instance, sub->callid, KEYDEF_CONNECTED);
 			start_rtp(sub);
 			ast_setstate(sub->owner, AST_STATE_UP);
 		}
@@ -4484,7 +4550,7 @@
 	memcpy(req->data.softkeytemplate.softKeyTemplateDefinition,
 		soft_key_template_default,
 		sizeof(soft_key_template_default));
-	transmit_response(s,req);
+	transmit_response(s->device,req);
 	return 1;
 }
 
