diff --git a/CHANGES b/CHANGES
index 8324aed19647cb7c28df20ff51fa618f10f59c3e..85658a4eceaae8f6ed6740810f0bf4ca3bc71b2b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -30,6 +30,14 @@ app_voicemail
  * The 'Comedian Mail' prompts can now be overriden using the 'vm-login' and
    'vm-newuser' configuration options in voicemail.conf.
 
+res_pjsip_transport_websocket
+------------------
+ * Removed non-secure websocket support.  Firefox and Chrome have not allowed
+   non-secure websockets for quite some time so this shouldn't be an issue
+   for people.  Attempting to use a non-secure websocket may or may not work
+   when Asterisk attempts to send SIP requests to do something like initiate
+   call hangup.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 13.13.0 to Asterisk 13.14.0 ----------
 ------------------------------------------------------------------------------
diff --git a/res/res_pjsip/security_events.c b/res/res_pjsip/security_events.c
index 5c30e1c5e7a55f2bd599291dcd79aa922bfbac80..ef3a748b2fd5424976ec21f116d18bd3c05542d4 100644
--- a/res/res_pjsip/security_events.c
+++ b/res/res_pjsip/security_events.c
@@ -44,9 +44,9 @@ static enum ast_transport security_event_get_transport(pjsip_rx_data *rdata)
 	} else if (rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS ||
 		rdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS6) {
 		return AST_TRANSPORT_TLS;
-	} else if (!strcmp(rdata->tp_info.transport->type_name, "WS")) {
+	} else if (!strcasecmp(rdata->tp_info.transport->type_name, "WS")) {
 		return AST_TRANSPORT_WS;
-	} else if (!strcmp(rdata->tp_info.transport->type_name, "WSS")) {
+	} else if (!strcasecmp(rdata->tp_info.transport->type_name, "WSS")) {
 		return AST_TRANSPORT_WSS;
 	} else {
 		return 0;
diff --git a/res/res_pjsip_nat.c b/res/res_pjsip_nat.c
index 59ef71c5c7db3eedddde3af862820cab5aa0cd51..7404ef5f01c39732f7a5b4b613bcac9e9bf6fa82 100644
--- a/res/res_pjsip_nat.c
+++ b/res/res_pjsip_nat.c
@@ -35,7 +35,9 @@
 static void rewrite_uri(pjsip_rx_data *rdata, pjsip_sip_uri *uri)
 {
 	pj_cstr(&uri->host, rdata->pkt_info.src_name);
-	if (strcasecmp("udp", rdata->tp_info.transport->type_name)) {
+	if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) {
+		/* WSS is special, we don't want to overwrite the URI at all as it needs to be ws */
+	} else if (strcasecmp("udp", rdata->tp_info.transport->type_name)) {
 		uri->transport_param = pj_str(rdata->tp_info.transport->type_name);
 	} else {
 		uri->transport_param.slen = 0;
diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c
index 82ade56e08603777acf7c828335185bbfcc1c7f4..ff8e346f4d956aaebe1e2b6c229f2ef0235a7e59 100644
--- a/res/res_pjsip_transport_websocket.c
+++ b/res/res_pjsip_transport_websocket.c
@@ -38,7 +38,6 @@
 #include "asterisk/res_pjsip_session.h"
 #include "asterisk/taskprocessor.h"
 
-static int transport_type_ws;
 static int transport_type_wss;
 
 /*!
@@ -149,6 +148,7 @@ static int transport_create(void *data)
 	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
 	struct pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt);
 
+	char *ws_addr_str;
 	pj_pool_t *pool;
 	pj_str_t buf;
 	pj_status_t status;
@@ -183,9 +183,23 @@ static int transport_create(void *data)
 		goto on_error;
 	}
 
-	pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session))), &newtransport->transport.key.rem_addr);
+	/*
+	 * The type_name here is mostly used by log messages eihter in
+	 * pjproject or Asterisk.  Other places are reconstituting subscriptions
+	 * after a restart (which could never work for a websocket connection anyway),
+	 * received MESSAGE requests to set PJSIP_TRANSPORT, and most importantly
+	 * by pjproject when generating the Via header.
+	 */
+	newtransport->transport.type_name = ast_websocket_is_secure(newtransport->ws_session)
+		? "WSS" : "WS";
+
+	ws_addr_str = ast_sockaddr_stringify(ast_websocket_remote_address(newtransport->ws_session));
+	ast_debug(4, "Creating websocket transport for %s:%s\n",
+		newtransport->transport.type_name, ws_addr_str);
+
+	pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ws_addr_str), &newtransport->transport.key.rem_addr);
 	newtransport->transport.key.rem_addr.addr.sa_family = pj_AF_INET();
-	newtransport->transport.key.type = ast_websocket_is_secure(newtransport->ws_session) ? transport_type_wss : transport_type_ws;
+	newtransport->transport.key.type = transport_type_wss;
 
 	newtransport->transport.addr_len = pj_sockaddr_get_len(&newtransport->transport.key.rem_addr);
 
@@ -196,7 +210,6 @@ static int transport_create(void *data)
 	newtransport->transport.local_name.host.slen = pj_ansi_strlen(newtransport->transport.local_name.host.ptr);
 	newtransport->transport.local_name.port = pj_sockaddr_get_port(&newtransport->transport.key.rem_addr);
 
-	newtransport->transport.type_name = (char *)pjsip_transport_get_type_name(newtransport->transport.key.type);
 	newtransport->transport.flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)newtransport->transport.key.type);
 	newtransport->transport.info = (char *)pj_pool_alloc(newtransport->transport.pool, 64);
 
@@ -382,19 +395,27 @@ static pj_bool_t websocket_on_rx_msg(pjsip_rx_data *rdata)
 
 	long type = rdata->tp_info.transport->key.type;
 
-	if (type != (long)transport_type_ws && type != (long)transport_type_wss) {
+	if (type != (long) transport_type_wss) {
 		return PJ_FALSE;
 	}
 
-	if ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && !contact->star &&
-		(PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
+	contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
+	if (contact
+		&& !contact->star
+		&& (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) {
 		pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri);
+		const pj_str_t *txp_str = &STR_WS;
+
+		ast_debug(4, "%s re-writing Contact URI from %.*s:%d%s%.*s to %s:%d;transport=%s\n",
+			pjsip_rx_data_get_info(rdata),
+			(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port,
+			pj_strlen(&uri->transport_param) ? ";transport=" : "",
+			(int)pj_strlen(&uri->transport_param), pj_strbuf(&uri->transport_param),
+			rdata->pkt_info.src_name ?: "", rdata->pkt_info.src_port, pj_strbuf(txp_str));
 
 		pj_cstr(&uri->host, rdata->pkt_info.src_name);
 		uri->port = rdata->pkt_info.src_port;
-		ast_debug(4, "Re-wrote Contact URI host/port to %.*s:%d\n",
-			(int)pj_strlen(&uri->host), pj_strbuf(&uri->host), uri->port);
-		pj_strdup(rdata->tp_info.pool, &uri->transport_param, &STR_WS);
+		pj_strdup(rdata->tp_info.pool, &uri->transport_param, txp_str);
 	}
 
 	rdata->msg_info.via->rport_param = 0;
@@ -429,8 +450,16 @@ static int load_module(void)
 {
 	CHECK_PJSIP_MODULE_LOADED();
 
-	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws);
-	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "WS", 5060, &transport_type_wss);
+	/*
+	 * We only need one transport type defined.  Firefox and Chrome
+	 * do not support anything other than secure websockets anymore.
+	 *
+	 * Also we really cannot have two transports with the same name
+	 * because it would be ambiguous.  Outgoing requests may try to
+	 * find the transport by name and pjproject only finds the first
+	 * one registered.
+	 */
+	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE | PJSIP_TRANSPORT_SECURE, "ws", 5060, &transport_type_wss);
 
 	if (ast_sip_register_service(&websocket_module) != PJ_SUCCESS) {
 		return AST_MODULE_LOAD_DECLINE;