[asterisk-commits] qwell: branch qwell/fun_with_transports r383603 - in /team/qwell/fun_with_tra...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 22 12:44:54 CDT 2013


Author: qwell
Date: Fri Mar 22 12:44:50 2013
New Revision: 383603

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383603
Log:
Don't look at this.  It's horrible.

It totally works though.  Sort of.  Except there's no SRTP yet.  And the
threading is completely broken, and will be until I bother to look at how
that's all supposed to work.

It can register and calls can be started.  Sometimes it'll even hangup without
crashing, too.  Not frequently though.

Also, no IPv6 support is possible, because of a flaw in how custom transport
types get registered in pjproject.

Added:
    team/qwell/fun_with_transports/res/res_sip_transport_websocket.c   (with props)
Modified:
    team/qwell/fun_with_transports/include/asterisk/res_sip.h
    team/qwell/fun_with_transports/res/res_sip.c
    team/qwell/fun_with_transports/res/res_sip/config_transport.c

Modified: team/qwell/fun_with_transports/include/asterisk/res_sip.h
URL: http://svnview.digium.com/svn/asterisk/team/qwell/fun_with_transports/include/asterisk/res_sip.h?view=diff&rev=383603&r1=383602&r2=383603
==============================================================================
--- team/qwell/fun_with_transports/include/asterisk/res_sip.h (original)
+++ team/qwell/fun_with_transports/include/asterisk/res_sip.h Fri Mar 22 12:44:50 2013
@@ -75,7 +75,8 @@
 	AST_SIP_TRANSPORT_UDP,
 	AST_SIP_TRANSPORT_TCP,
 	AST_SIP_TRANSPORT_TLS,
-	/* XXX Websocket ? */
+	AST_SIP_TRANSPORT_WS,
+	AST_SIP_TRANSPORT_WSS,
 };
 
 /*! \brief Maximum number of ciphers supported for a TLS transport */

Modified: team/qwell/fun_with_transports/res/res_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/fun_with_transports/res/res_sip.c?view=diff&rev=383603&r1=383602&r2=383603
==============================================================================
--- team/qwell/fun_with_transports/res/res_sip.c (original)
+++ team/qwell/fun_with_transports/res/res_sip.c Fri Mar 22 12:44:50 2013
@@ -224,7 +224,7 @@
 	}
 
 	/* If the host is IPv6 turn the transport into an IPv6 version */
-	if (pj_strchr(&sip_uri->host, ':')) {
+	if (pj_strchr(&sip_uri->host, ':') && type < PJSIP_TRANSPORT_START_OTHER) {
 		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
 	}
 
@@ -234,8 +234,8 @@
 		return -1;
 	}
 
-	/* If IPv6 was not specified in the host but is in the transport, set the proper type */
-	if (!pj_strchr(&sip_uri->host, ':') && pj_strchr(&local_addr, ':')) {
+	/* If IPv6 was specified in the transport, set the proper type */
+	if (pj_strchr(&local_addr, ':') && type < PJSIP_TRANSPORT_START_OTHER) {
 		type = (pjsip_transport_type_e)(((int)type) + PJSIP_TRANSPORT_IPV6);
 	}
 

Modified: team/qwell/fun_with_transports/res/res_sip/config_transport.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/fun_with_transports/res/res_sip/config_transport.c?view=diff&rev=383603&r1=383602&r2=383603
==============================================================================
--- team/qwell/fun_with_transports/res/res_sip/config_transport.c (original)
+++ team/qwell/fun_with_transports/res/res_sip/config_transport.c Fri Mar 22 12:44:50 2013
@@ -168,8 +168,11 @@
 		transport->type = AST_SIP_TRANSPORT_TCP;
 	} else if (!strcasecmp(var->value, "tls")) {
 		transport->type = AST_SIP_TRANSPORT_TLS;
-	} else {
-		/* TODO: Implement websockets */
+	} else if (!strcasecmp(var->value, "ws")) {
+		transport->type = AST_SIP_TRANSPORT_WS;
+	} else if (!strcasecmp(var->value, "wss")) {
+		transport->type = AST_SIP_TRANSPORT_WSS;
+	} else {
 		return -1;
 	}
 

Added: team/qwell/fun_with_transports/res/res_sip_transport_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/fun_with_transports/res/res_sip_transport_websocket.c?view=auto&rev=383603
==============================================================================
--- team/qwell/fun_with_transports/res/res_sip_transport_websocket.c (added)
+++ team/qwell/fun_with_transports/res/res_sip_transport_websocket.c Fri Mar 22 12:44:50 2013
@@ -1,0 +1,188 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Jason Parker <jparker at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*** MODULEINFO
+	<use type="module">res_http_websocket</use>
+	<support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include <pjsip.h>
+
+#include "asterisk/http_websocket.h"
+#include "asterisk/res_sip.h"
+#include "asterisk/module.h"
+
+static int transport_type_ws;
+static int transport_type_wss;
+
+struct ws_transport {
+	pjsip_transport transport;
+	struct ast_websocket *ws_session;
+};
+
+static pj_status_t ws_send_msg(pjsip_transport *transport,
+                            pjsip_tx_data *tdata,
+                            const pj_sockaddr_t *rem_addr,
+                            int addr_len,
+                            void *token,
+                            pjsip_transport_callback callback)
+{
+	struct ws_transport *wstransport = (struct ws_transport *)transport;
+
+	char buf[1024];
+	pj_ssize_t size = pjsip_msg_print(tdata->msg, buf, sizeof(buf));
+
+	ast_websocket_write(wstransport->ws_session, AST_WEBSOCKET_OPCODE_TEXT, buf, size);
+
+	return PJ_SUCCESS;
+}
+
+static pj_status_t ws_shutdown(pjsip_transport *transport)
+{
+	return PJ_SUCCESS;
+}
+
+static pj_status_t ws_destroy_transport(pjsip_transport *transport)
+{
+	struct ws_transport *wstransport = (struct ws_transport *)transport;
+
+	if (wstransport->transport.ref_cnt) {
+		pj_atomic_destroy(wstransport->transport.ref_cnt);
+	}
+
+	if (wstransport->transport.lock) {
+		pj_lock_destroy(wstransport->transport.lock);
+	}
+
+	pjsip_endpt_release_pool(wstransport->transport.endpt, wstransport->transport.pool);
+
+	return PJ_SUCCESS;
+}
+
+static int ws_recv(void *data)
+{
+	struct ast_websocket *session = (struct ast_websocket *)data;
+
+	pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
+	struct pjsip_tpmgr *tpmgr = pjsip_endpt_get_tpmgr(endpt);
+
+	pj_pool_t *pool = pjsip_endpt_create_pool(endpt, "ws", 512, 512);
+	struct ws_transport *newtransport = PJ_POOL_ZALLOC_T(pool, struct ws_transport);
+
+	pj_atomic_create(pool, 0, &newtransport->transport.ref_cnt);
+	pj_lock_create_recursive_mutex(pool, pool->obj_name, &newtransport->transport.lock);
+
+	newtransport->transport.pool = pool;
+	newtransport->transport.key.type = ast_websocket_is_secure(session) ? transport_type_wss : transport_type_ws;
+	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);
+
+	newtransport->transport.endpt = endpt;
+	newtransport->transport.tpmgr = tpmgr;
+	newtransport->transport.send_msg = &ws_send_msg;
+	newtransport->transport.do_shutdown = &ws_shutdown;
+	newtransport->transport.destroy = &ws_destroy_transport;
+	newtransport->ws_session = session;
+
+	pj_atomic_inc(newtransport->transport.ref_cnt);
+
+	pjsip_transport_register(newtransport->transport.tpmgr, (pjsip_transport *)newtransport);
+
+	if (ast_websocket_set_nonblock(session)) {
+		ast_websocket_unref(session);
+		return 0;
+	}
+
+	while ((ast_wait_for_input(ast_websocket_fd(session), -1)) > 0) {
+		char *payload;
+		uint64_t payload_len;
+		enum ast_websocket_opcode opcode;
+		int fragmented;
+
+		if (ast_websocket_read(session, &payload, &payload_len, &opcode, &fragmented)) {
+			break;
+		}
+
+		if (opcode == AST_WEBSOCKET_OPCODE_TEXT || opcode == AST_WEBSOCKET_OPCODE_BINARY) {
+			pjsip_rx_data *rdata;
+			int recvd;
+			pj_str_t buf;
+
+			rdata = PJ_POOL_ZALLOC_T(newtransport->transport.pool, pjsip_rx_data);
+
+			rdata->tp_info.pool = newtransport->transport.pool;
+			rdata->tp_info.transport = &newtransport->transport;
+
+			pj_gettimeofday(&rdata->pkt_info.timestamp);
+
+			pj_memcpy(rdata->pkt_info.packet, payload, payload_len);
+			rdata->pkt_info.len = payload_len;
+			rdata->pkt_info.zero = 0;
+
+		        pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, ast_sockaddr_stringify(ast_websocket_remote_address(session))), &rdata->pkt_info.src_addr);
+			rdata->pkt_info.src_addr.addr.sa_family = pj_AF_INET();
+
+			rdata->pkt_info.src_addr_len = sizeof(rdata->pkt_info.src_addr);
+
+			pj_ansi_strcpy(rdata->pkt_info.src_name, ast_sockaddr_stringify_host(ast_websocket_remote_address(session)));
+			rdata->pkt_info.src_port = ast_sockaddr_port(ast_websocket_remote_address(session));
+
+//			rdata->pkt_info.src_addr_len = sizeof(pj_sockaddr_in);
+
+			recvd = pjsip_tpmgr_receive_packet(rdata->tp_info.transport->tpmgr, rdata);
+		} else if (opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
+			return -1;
+		}
+	}
+
+	pj_atomic_dec(newtransport->transport.ref_cnt);
+
+	pjsip_transport_shutdown(&newtransport->transport);
+
+	ast_websocket_unref(session);
+
+	return 0;
+}
+
+static void websocket_cb(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
+{
+	ast_sip_push_task(NULL, ws_recv, session);
+}
+
+static int load_module(void)
+{
+	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WS", 5060, &transport_type_ws);
+	pjsip_transport_register_type(PJSIP_TRANSPORT_RELIABLE, "WSS", 5060, &transport_type_wss);
+
+	ast_websocket_add_protocol("sip", websocket_cb);
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	return 0;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "SIP WebSocket Transport Support",
+		.load = load_module,
+		.unload = unload_module,
+		.load_pri = AST_MODPRI_APP_DEPEND,
+	   );

Propchange: team/qwell/fun_with_transports/res/res_sip_transport_websocket.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/qwell/fun_with_transports/res/res_sip_transport_websocket.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/qwell/fun_with_transports/res/res_sip_transport_websocket.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the asterisk-commits mailing list