diff --git a/libvoice/broadcom/brcm-line.c b/libvoice/broadcom/brcm-line.c
index 022964b9c4b8ebdb6a5653e78dd5f5a07c9d8fb4..33c557c30493970ea5856fd4c8ea865bd74b5dc3 100644
--- a/libvoice/broadcom/brcm-line.c
+++ b/libvoice/broadcom/brcm-line.c
@@ -388,6 +388,8 @@ int voice_line_close(int line)
 	return 0;
 }
 
+//-------------------------------------------------------------
+// Shut down the voice engine and release all resources
 int voice_engine_shutdown(void)
 {
 	EPSTATUS status;
@@ -452,3 +454,30 @@ int voice_get_rtp_stats(int line, int connection, int reset, struct rtp_stats_t
 
 	return 0;
 }
+
+//-------------------------------------------------------------
+// Write a media packet (e.g. RTP, RTCP) to the voice engine
+int voice_write_media_packet(const struct media_packet_t *packet) {
+	EPPACKET ep_packet;
+	EPSTATUS ret;
+
+	if (lines[packet->line].epHandle.lineId == -1) {
+		ENDPT_DBG("%s: bad packet from line %d\n", __func__, packet->line);
+		return -1;
+	}
+
+	if (packet->rtp[1] == 200  || packet->rtp[1] == 201 ) {
+		ep_packet.mediaType = 1;	// RTCP packets
+	} else {
+		ep_packet.mediaType = 0;	// RTP packets
+	}
+	ep_packet.packetp = packet->rtp;
+
+	ret = vrgEndptPacket(&lines[packet->line].epHandle, packet->connection_id, &ep_packet, packet->rtp_size, 0);
+	if (ret != EPSTATUS_SUCCESS) {
+		ENDPT_DBG("%s: vrgEndptPacket failed, %s\n", __func__, brcm_get_error_code_str(ret));
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/libvoice/libvoice.h b/libvoice/libvoice.h
index c2157bc68176e342736d6a2c7b5ce279fee62838..7da18a73ae0744ee78422621c4902e8c31e1d61a 100644
--- a/libvoice/libvoice.h
+++ b/libvoice/libvoice.h
@@ -224,5 +224,6 @@ int voice_get_rtp_stats(int line, int connection, int reset, struct rtp_stats_t
 int voice_set_country(const char *country_code);
 int voice_register_cb_event_report(void (*voice_cb_event_report)(int line, const char *event, int data));
 int voice_register_cb_egress_media(void (*cb_egress_media)(const struct media_packet_t *packet, int size));
+int voice_write_media_packet(const struct media_packet_t *packet);
 
 #endif
diff --git a/line.c b/line.c
index 7f7e17b580bc6ca41a15a0cade009b62fdd5d823..2050ca8fa78efd6da599ff2acea863641347a03b 100644
--- a/line.c
+++ b/line.c
@@ -68,36 +68,6 @@ static const struct epsig epsig_map[] = { // For generating a signal to the phon
 	{ .name = "", .epsig = EPSIG_LAST },
 };
 
-//----------------------------------------------------------------------
-// Handle audio packets from Asterisk and send them to the voice engine.
-void lineAudioTx(pe_packet_t *p) {
-	EPPACKET ep_packet;
-	EPSTATUS ret;
-	int conIdx;
-	struct media_packet_t *ap = (struct media_packet_t *)p->data;
-
-	if (ap->rtp[1] == 200  || ap->rtp[1] == 201 ) {
-		ep_packet.mediaType = 1;	// RTCP packets
-	} else {
-		ep_packet.mediaType = 0;	// RTP packets
-	}
-
-	ep_packet.packetp = ap->rtp;
-	conIdx = voice_connection_find(ap->line, ap->connection_id);
-
-	if (conIdx == -1 || (ap->rtp[0] != 0x80 && ap->rtp[0] != 0x81) || !ap->rtp_size ||
-			lines[connections[conIdx].line].epHandle.lineId == -1) {
-		ENDPT_DBG("bad audio packet\n");
-		return;
-	}
-
-	ret = vrgEndptPacket(&lines[connections[conIdx].line].epHandle,
-			ap->connection_id, &ep_packet, ap->rtp_size, 0);
-	if (ret != EPSTATUS_SUCCESS) {
-		ENDPT_DBG("Error vrgEndptPacket: %s\n", brcm_get_error_code_str(ret));
-	}
-}
-
 static int sendDectEventToAsterisk(int line, struct dect_event_t dectEvnt) {
 	struct line_event_t *msg;
 
diff --git a/line.h b/line.h
index 0a1cd6b2204a1d720c98461b99130e2e87a2bcbb..1ea51344370a2aa467ece367b979b5f693ccbf3f 100644
--- a/line.h
+++ b/line.h
@@ -32,7 +32,6 @@ struct line_req_t {
 	struct voice_ubus_req_t ubus;
 };
 
-//-------------------------------------------------------------
 int find_endpt_from_asterisk_id(int line);
 int lineNewConnectionByPbx(int line, int conId, struct voice_ubus_req_t *ubusReq);
 int lineCloseConnectionByPbx(int line, int conId, struct voice_ubus_req_t *ubusReq);
@@ -40,7 +39,6 @@ int lineReleaseConnectionByPbx(int line, int conId, struct voice_ubus_req_t *ubu
 int lineUpdateConnectionByPbx(int line, int pcm_state);
 int lineNewConnectionByDect(int line, const char *cid, int pcmId, struct voice_ubus_req_t *ubusReq);
 int lineCloseConnectionByDect(int line, int pcmId, struct voice_ubus_req_t *ubusReq);
-void lineAudioTx(pe_packet_t *p);
 int line_signal(int line, char *signame, const char *data, struct voice_ubus_req_t *ubusReq);
 
 #endif
diff --git a/main.c b/main.c
index 3b52122dc73f94d3f4e226529ebbf00100f31ca2..75bba4f43442879bcf165400b8e8ee111781e669 100644
--- a/main.c
+++ b/main.c
@@ -27,12 +27,26 @@ static pe_bus_t *audio_rx_bus;
 static pe_bus_t *audio_tx_bus;
 int picoBase = -1;
 
-// Send audio data to asterisk
+// Send a media packet to Asterisk
 static void send_media_to_asterisk(const struct media_packet_t *packet, int size) {
 	pe_bus_send(audio_tx_bus, (uint8_t *)packet, size);
 	return 0;
 }
 
+// Send a media packet to voice engine
+void send_media_to_voice_engine(pe_packet_t *p) {
+	int conIdx;
+	struct media_packet_t *packet = (struct media_packet_t *)p->data;
+
+	conIdx = voice_connection_find(packet->line, packet->connection_id);
+	if (conIdx == -1 || (packet->rtp[0] != 0x80 && packet->rtp[0] != 0x81) || !packet->rtp_size) {
+		ENDPT_DBG("%s: bad packet\n", __func__);
+		return;
+	}
+
+	voice_write_media_packet(packet);
+}
+
 // Handle media stream from Asterisk on audio rx socket and re-posts it to internal audio rx bus
 static void audio_rx_stream_handler(pe_stream_t *stream __attribute__((unused)), pe_event_t *event) {
 	if (pe_bus_receive(audio_rx_bus, (pe_event_t *)event) < 0) {
@@ -130,7 +144,7 @@ static void streams_and_buses_init(void) {
 
 	audio_rx_bus = pe_bus_new(audio_rx_fd);
 	if (!audio_rx_bus) exit_failure("Failed to create audio_rx bus");
-	pe_bus_add_handler(audio_rx_bus, lineAudioTx);
+	pe_bus_add_handler(audio_rx_bus, send_media_to_voice_engine);
 
 	/* Send audio frames to asterisk. */
 	audio_tx_bus = pe_bus_new(audio_tx_fd);