Module: sip-router
Branch: pd/websocket
Commit: d3e770533b908acf73b359ba556a972c1330a118
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d3e770533b908acf73b359ba556a972c1330a118

Author: Peter Dunkley <[email protected]>
Committer: Peter Dunkley <[email protected]>
Date:   Sun Jun 17 14:29:44 2012 +0100

modules/websocket: more work on WebSocket framing and base-protocol

---

 modules/websocket/ws_frame.c |   75 +++++++++++++++++++++++++++++++++++++-----
 modules/websocket/ws_frame.h |    1 +
 modules/websocket/ws_mod.c   |   45 +++++++++++++------------
 3 files changed, 90 insertions(+), 31 deletions(-)

diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c
index bce0a09..0b0b474 100644
--- a/modules/websocket/ws_frame.c
+++ b/modules/websocket/ws_frame.c
@@ -22,6 +22,7 @@
  */
 
 #include "../../tcp_conn.h"
+#include "../../lib/kcore/kstats_wrapper.h"
 #include "../../lib/kmi/tree.h"
 #include "ws_frame.h"
 #include "ws_mod.h"
@@ -177,10 +178,10 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame)
        frame->masking_key[3] = (buf[mask_start + 3] & 0xff);
 
        /* Decode and unmask payload */
-       if (len < frame->payload_len + mask_start)
+       if (len != frame->payload_len + mask_start + 4)
        {
-               LM_WARN("message not complete payload_len = %u but only "
-                       "received %u\n", frame->payload_len, len);
+               LM_WARN("message not complete frame size %u but received %u\n",
+                       frame->payload_len + mask_start + 4, len);
                return -1;
        }
        frame->payload_data = &buf[mask_start + 4];
@@ -197,27 +198,75 @@ static int decode_and_validate_ws_frame(ws_frame_t *frame)
        return frame->opcode;
 }
 
-static int handle_sip_message(ws_frame_t *msg)
+static int encode_and_send_ws_frame(ws_frame_t *frame)
+{
+       /* TODO: convert ws_frame_t into a binary WebSocket frame and send over
+          TCP/TLS */
+
+       update_stat(ws_transmitted_frames, 1);
+
+       return 0;
+}
+
+static int handle_sip_message(ws_frame_t *frame)
 {
        LM_INFO("Received SIP message\n");
+
+       /* TODO: drop SIP message into route {} for processing */
+
        return 0;
 }
 
-static int handle_close(ws_frame_t *msg)
+static int handle_close(ws_frame_t *frame)
 {
+       unsigned short code = 0;
+       str reason = {0, 0};
+
+       update_stat(ws_remote_closed_connections, 1);
+       update_stat(ws_current_connections, -1);
        LM_INFO("Received Close\n");
+
+       if (frame->payload_len >= 2)
+               code =    ((frame->payload_data[0] & 0xff) << 8)
+                       | ((frame->payload_data[1] & 0xff) << 0);
+
+       if (frame->payload_len > 2)
+       {
+               reason.s = &frame->payload_data[2];
+               reason.len = frame->payload_len - 2;
+       }
+
+       LM_INFO("Close: %hu %.*s\n", code, reason.len, reason.s); 
+
+       /* TODO: cleanly close TCP/TLS connection */
+
        return 0;
 }
 
-static int handle_ping(ws_frame_t *msg)
+static int handle_ping(ws_frame_t *frame)
 {
+       ws_frame_t ws_frame;
+
        LM_INFO("Received Ping\n");
+
+       memset(&ws_frame, 0, sizeof(ws_frame_t));
+       ws_frame.fin = 1;
+       ws_frame.opcode = OPCODE_PONG;
+       ws_frame.payload_len = frame->payload_len;
+       ws_frame.payload_data =  frame->payload_data;
+       ws_frame.tcpinfo = frame->tcpinfo;
+
+       encode_and_send_ws_frame(&ws_frame);
+
        return 0;
 }
 
-static int handle_pong(ws_frame_t *msg)
+static int handle_pong(ws_frame_t *frame)
 {
        LM_INFO("Received Pong\n");
+
+       LM_INFO("Pong: %.*s\n", frame->payload_len, frame->payload_data);
+
        return 0;
 }
 
@@ -226,6 +275,8 @@ int ws_frame_received(void *data)
        ws_frame_t ws_frame;
        tcp_event_info_t *tev = (tcp_event_info_t *) data;
 
+       update_stat(ws_received_frames, 1);
+
        if (tev == NULL || tev->buf == NULL || tev->len <= 0)
        {
                LM_WARN("received bad frame\n");
@@ -278,12 +329,18 @@ int ws_frame_received(void *data)
 
 struct mi_root *ws_mi_close(struct mi_root *cmd, void *param)
 {
-       /* TODO close specified or all connections */
+       /* TODO Close specified or all connections */
        return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
 }
 
 struct mi_root *ws_mi_ping(struct mi_root *cmd, void *param)
 {
-       /* TODO ping specified connection */
+       /* TODO Ping specified connection */
+       return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+}
+
+struct mi_root *ws_mi_pong(struct mi_root *cmd, void *param)
+{
+       /* TODO Pong specified connection */
        return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
 }
diff --git a/modules/websocket/ws_frame.h b/modules/websocket/ws_frame.h
index 782367f..aef04e0 100644
--- a/modules/websocket/ws_frame.h
+++ b/modules/websocket/ws_frame.h
@@ -30,5 +30,6 @@
 int ws_frame_received(void *data);
 struct mi_root *ws_mi_close(struct mi_root *cmd, void *param);
 struct mi_root *ws_mi_ping(struct mi_root *cmd, void *param);
+struct mi_root *ws_mi_pong(struct mi_root *cmd, void *param);
 
 #endif /* _WS_FRAME_H */
diff --git a/modules/websocket/ws_mod.c b/modules/websocket/ws_mod.c
index 4ca1758..302e0db 100644
--- a/modules/websocket/ws_mod.c
+++ b/modules/websocket/ws_mod.c
@@ -58,40 +58,41 @@ static struct mi_root *mi_dump(struct mi_root *cmd, void 
*param);
 
 static cmd_export_t cmds[]= 
 {
-    {"ws_handle_handshake", (cmd_function)ws_handle_handshake, 0,
-       0, 0,
-       ANY_ROUTE},
-    {0, 0, 0, 0, 0, 0}
+    { "ws_handle_handshake", (cmd_function)ws_handle_handshake,
+       0, 0, 0,
+       ANY_ROUTE },
+    { 0, 0, 0, 0, 0, 0 }
 };
 
 static param_export_t params[]=
 {
-       {"ping_interval",       INT_PARAM, &ws_ping_interval},
-       {0, 0}
+       { "ping_interval",      INT_PARAM, &ws_ping_interval },
+       { 0, 0 }
 };
 
 static stat_export_t stats[] =
 {
-       {"ws_current_connections",       0, &ws_current_connections },
-       {"ws_failed_connections",        0, &ws_failed_connections },
-       {"ws_failed_handshakes",         0, &ws_failed_handshakes },
-       {"ws_local_closed_connections",  0, &ws_local_closed_connections },
-       {"ws_max_concurrent_connections",0, &ws_max_concurrent_connections },
-       {"ws_received_frames",           0, &ws_received_frames },
-       {"ws_remote_closed_connections", 0, &ws_remote_closed_connections },
-       {"ws_successful_handshakes",     0, &ws_successful_handshakes },
-       {"ws_transmitted_frames",        0, &ws_transmitted_frames },
-       {0, 0, 0}
+       { "ws_current_connections",       0, &ws_current_connections },
+       { "ws_failed_connections",        0, &ws_failed_connections },
+       { "ws_failed_handshakes",         0, &ws_failed_handshakes },
+       { "ws_local_closed_connections",  0, &ws_local_closed_connections },
+       { "ws_max_concurrent_connections",0, &ws_max_concurrent_connections },
+       { "ws_received_frames",           0, &ws_received_frames },
+       { "ws_remote_closed_connections", 0, &ws_remote_closed_connections },
+       { "ws_successful_handshakes",     0, &ws_successful_handshakes },
+       { "ws_transmitted_frames",        0, &ws_transmitted_frames },
+       { 0, 0, 0 }
 };
 
 static mi_export_t mi_cmds[] =
 {
-       { "ws_close",   ws_mi_close,   0, 0, 0},
-       { "ws_disable", ws_mi_disable, 0, 0, 0},
-       { "ws_dump",    mi_dump,       0, 0, 0},
-       { "ws_enable",  ws_mi_enable,  0, 0, 0},
-       { "ws_ping",    ws_mi_ping,    0, 0, 0},
-       { 0, 0, 0, 0, 0}
+       { "ws_close",   ws_mi_close,   0, 0, 0 },
+       { "ws_disable", ws_mi_disable, 0, 0, 0 },
+       { "ws_dump",    mi_dump,       0, 0, 0 },
+       { "ws_enable",  ws_mi_enable,  0, 0, 0 },
+       { "ws_ping",    ws_mi_ping,    0, 0, 0 },
+       { "ws_pong",    ws_mi_pong,    0, 0, 0 },
+       { 0, 0, 0, 0, 0 }
 };
 
 struct module_exports exports= 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to