core: Added WS support/events to Kamailio core
authorPeter Dunkley <peter.dunkley@crocodile-rcs.com>
Sat, 16 Jun 2012 16:06:33 +0000 (17:06 +0100)
committerPeter Dunkley <peter.dunkley@crocodile-rcs.com>
Sat, 16 Jun 2012 16:06:33 +0000 (17:06 +0100)
events.c
events.h
tcp_conn.h
tcp_read.c

index 5ad2b44..d4a24f8 100644 (file)
--- a/events.c
+++ b/events.c
@@ -96,6 +96,11 @@ int sr_event_register_cb(int type, sr_event_cb_f f)
                                        _sr_events_list.tcp_msrp_frame = f;
                                else return -1;
                        break;
+               case SREV_TCP_WS_FRAME:
+                               if(_sr_events_list.tcp_ws_frame==0)
+                                       _sr_events_list.tcp_ws_frame = f;
+                               else return -1;
+                       break;
                default:
                        return -1;
        }
@@ -187,6 +192,12 @@ int sr_event_exec(int type, void *data)
                                        ret = _sr_events_list.tcp_msrp_frame(data);
                                        return ret;
                                } else return 1;
+               case SREV_TCP_WS_FRAME:
+                               if(unlikely(_sr_events_list.tcp_ws_frame!=0))
+                               {
+                                       ret = _sr_events_list.tcp_ws_frame(data);
+                                       return ret;
+                               } else return 1;
                default:
                        return -1;
        }
@@ -216,6 +227,8 @@ int sr_event_enabled(int type)
                                return (_sr_events_list.tcp_http_100c!=0)?1:0;
                case SREV_TCP_MSRP_FRAME:
                                return (_sr_events_list.tcp_msrp_frame!=0)?1:0;
+               case SREV_TCP_WS_FRAME:
+                               return (_sr_events_list.tcp_ws_frame!=0)?1:0;
        }
        return 0;
 }
index 1a4c5e0..f919a00 100644 (file)
--- a/events.h
+++ b/events.h
@@ -32,6 +32,7 @@
 #define SREV_NET_DGRAM_IN              7
 #define SREV_TCP_HTTP_100C             8
 #define SREV_TCP_MSRP_FRAME            9
+#define SREV_TCP_WS_FRAME              10
 
 
 typedef int (*sr_event_cb_f)(void *data);
@@ -46,6 +47,7 @@ typedef struct sr_event_cb {
        sr_event_cb_f net_dgram_in;
        sr_event_cb_f tcp_http_100c;
        sr_event_cb_f tcp_msrp_frame;
+       sr_event_cb_f tcp_ws_frame;
 } sr_event_cb_t;
 
 void sr_event_cb_init(void);
index a8a7e04..3b3f546 100644 (file)
@@ -75,6 +75,7 @@
 #define F_CONN_WANTS_RD  4096  /* conn. should be watched for READ */
 #define F_CONN_WANTS_WR  8192  /* conn. should be watched for WRITE */
 #define F_CONN_PASSIVE  16384 /* conn. created via accept() and not connect()*/
+#define F_CONN_WS      32768 /* conn. is a websocket */
 
 #ifndef NO_READ_HTTP11
 #define READ_HTTP11
 #define READ_MSRP
 #endif
 
+#ifndef NO_READ_WS
+#define READ_WS
+#endif
+
 enum tcp_req_errors {  TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
                                                TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
 enum tcp_req_states {  H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND,
index f73a239..c68dbdd 100644 (file)
@@ -110,6 +110,11 @@ int is_msg_complete(struct tcp_req* r);
 #define HTTP11CONTINUE_LEN     (sizeof(HTTP11CONTINUE)-1)
 #endif
 
+#ifdef READ_WS
+static int ws_process_msg(char* tcpbuf, unsigned int len,
+               struct receive_info* rcv_info, struct tcp_connection* con);
+#endif
+
 #define TCPCONN_TIMEOUT_MIN_RUN  1 /* run the timers each new tick */
 
 /* types used in io_wait* */
@@ -439,7 +444,11 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
                if (bytes<=0) return bytes;
        }
        p=r->parsed;
-       
+#ifdef READ_WS
+       if (c->flags & F_CONN_WS)
+               return ws_process_msg(p, bytes, &c->rcv, c);
+#endif
+
        while(p<r->pos && r->error==TCP_REQ_OK){
                switch((unsigned char)r->state){
                        case H_BODY: /* read the body*/
@@ -1015,6 +1024,30 @@ int msrp_process_msg(char* tcpbuf, unsigned int len,
 }
 #endif
 
+#ifdef READ_WS
+static int ws_process_msg(char* tcpbuf, unsigned int len,
+               struct receive_info* rcv_info, struct tcp_connection* con)
+{
+       int ret;
+       tcp_event_info_t tev;
+
+       ret = 0;
+       LM_DBG("WebSocket Message: [[>>>\n%.*s<<<]]\n", len, tcpbuf);
+       if(likely(sr_event_enabled(SREV_TCP_WS_FRAME))) {
+               memset(&tev, 0, sizeof(tcp_event_info_t));
+               tev.type = SREV_TCP_WS_FRAME;
+               tev.buf = tcpbuf;
+               tev.len = len;
+               tev.rcv = rcv_info;
+               tev.con = con;
+               ret = sr_event_exec(SREV_TCP_WS_FRAME, (void*)(&tev));
+       } else {
+               LM_DBG("no callback registering for handling WebSockets - dropping!\n");
+       }
+       return ret;
+}
+#endif
+
 /**
  * @brief wrapper around receive_msg() to clone the tcpbuf content
  *