@@ -18,8 +18,10 @@ LOG_MODULE_REGISTER(net_websocket, CONFIG_NET_WEBSOCKET_LOG_LEVEL);
1818#include <errno.h>
1919#include <stdbool.h>
2020#include <stdlib.h>
21+ #include <sys/byteorder.h>
2122
2223#include <sys/fdtable.h>
24+ #include <net/net_core.h>
2325#include <net/net_ip.h>
2426#include <net/socket.h>
2527#include <net/http_client.h>
@@ -437,7 +439,7 @@ int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
437439 s32_t timeout )
438440{
439441 struct websocket_context * ctx ;
440- u8_t header [14 ], hdr_len = 2 ;
442+ u8_t header [MAX_HEADER_LEN ], hdr_len = 2 ;
441443 u8_t * data_to_send = (u8_t * )payload ;
442444 int ret ;
443445
@@ -525,65 +527,34 @@ int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len,
525527 return ret ;
526528}
527529
528- #if 0
529- static void websocket_mask_pkt (struct net_pkt * pkt , u32_t masking_value ,
530- u32_t * data_read )
531- {
532- struct net_buf * frag ;
533- u16_t pos ;
534- int i ;
535-
536- frag = net_frag_get_pos (pkt ,
537- net_pkt_get_len (pkt ) - net_pkt_appdatalen (pkt ),
538- & pos );
539- if (!frag ) {
540- return ;
541- }
542-
543- NET_ASSERT (net_pkt_appdata (pkt ) == frag -> data + pos );
544-
545- while (frag ) {
546- for (i = pos ; i < frag -> len ; i ++ , (* data_read )++ ) {
547- frag -> data [i ] ^=
548- masking_value >> (8 * (3 - (* data_read ) % 4 ));
549- }
550-
551- pos = 0 ;
552- frag = frag -> frags ;
553- }
554- }
555- #endif
556-
557- static int websocket_strip_header (u8_t * buf , size_t buf_len , bool * masked ,
558- u32_t * mask_value , size_t * message_length ,
559- u32_t * message_type_flag , size_t * header_len )
530+ static void websocket_parse_header (u8_t * buf , size_t buf_len , bool * masked ,
531+ u32_t * mask_value , u64_t * message_length ,
532+ u32_t * message_type_flag , size_t * header_len )
560533{
561- #if 0
562- size_t read_pos = 0 ;
563- u16_t value ;
564- u8_t len ; /* message length byte */
565534 u8_t len_len ; /* length of the length field in header */
535+ u8_t len ; /* message length byte */
536+ u16_t value ;
566537
567538 value = sys_get_be16 (& buf [0 ]);
568539 if (value & 0x8000 ) {
569- * message_type_flag |= WS_FLAG_FINAL ;
540+ * message_type_flag |= WEBSOCKET_FLAG_FINAL ;
570541 }
571542
572543 switch (value & 0x0f00 ) {
573544 case 0x0100 :
574- * message_type_flag |= WS_FLAG_TEXT ;
545+ * message_type_flag |= WEBSOCKET_FLAG_TEXT ;
575546 break ;
576547 case 0x0200 :
577- * message_type_flag |= WS_FLAG_BINARY ;
548+ * message_type_flag |= WEBSOCKET_FLAG_BINARY ;
578549 break ;
579550 case 0x0800 :
580- * message_type_flag |= WS_FLAG_CLOSE ;
551+ * message_type_flag |= WEBSOCKET_FLAG_CLOSE ;
581552 break ;
582553 case 0x0900 :
583- * message_type_flag |= WS_FLAG_PING ;
554+ * message_type_flag |= WEBSOCKET_FLAG_PING ;
584555 break ;
585556 case 0x0A00 :
586- * message_type_flag |= WS_FLAG_PONG ;
557+ * message_type_flag |= WEBSOCKET_FLAG_PONG ;
587558 break ;
588559 }
589560
@@ -592,57 +563,32 @@ static int websocket_strip_header(u8_t *buf, size_t buf_len, bool *masked,
592563 len_len = 0 ;
593564 * message_length = len ;
594565 } else if (len == 126 ) {
595- u16_t msg_len ;
596-
597566 len_len = 2 ;
598-
599- frag = net_frag_read_be16 (frag , pos , & pos , & msg_len );
600- if (!frag && pos == 0xffff ) {
601- return - ENOMSG ;
602- }
603-
604- * message_length = msg_len ;
567+ * message_length = sys_get_be16 (& buf [2 ]);
605568 } else {
606- len_len = 4 ;
607-
608- frag = net_frag_read_be32 (frag , pos , & pos , message_length );
609- if (!frag && pos == 0xffff ) {
610- return - ENOMSG ;
611- }
569+ len_len = 8 ;
570+ * message_length = sys_get_be64 (& buf [2 ]);
612571 }
613572
614573 if (value & 0x0080 ) {
615574 * masked = true;
616- appdata_pos = 0 ;
617-
618- frag = net_frag_read_be32 (frag , pos , & pos , mask_value );
619- if (!frag && pos == 0xffff ) {
620- return - ENOMSG ;
621- }
575+ * mask_value = sys_get_be32 (& buf [2 + len_len ]);
622576 } else {
623577 * masked = false;
624- appdata_pos = len_len ;
625- }
626-
627- frag = net_frag_get_pos (pkt , pos + appdata_pos , & pos );
628- if (!frag && pos == 0xffff ) {
629- return - ENOMSG ;
630578 }
631579
632580 /* Minimum websocket header is 6 bytes, header length might be
633581 * bigger depending on length field len.
634582 */
635583 * header_len = 6 + len_len ;
636- #endif
637- return 0 ;
638584}
639585
640586int websocket_recv_msg (int ws_sock , u8_t * buf , size_t buf_len ,
641587 bool * masked , u32_t * mask_value , u32_t * message_type ,
642- s32_t timeout )
588+ u64_t * message_len , s32_t timeout )
643589{
644590 struct websocket_context * ctx ;
645- size_t message_length , header_len ;
591+ size_t header_len , pos_to_write = 0 ;
646592 u32_t message_type_flag ;
647593 int ret ;
648594
@@ -655,20 +601,71 @@ int websocket_recv_msg(int ws_sock, u8_t *buf, size_t buf_len,
655601 return - ENOENT ;
656602 }
657603
658- ret = recv (ctx -> real_sock , buf , buf_len ,
604+ if (!ctx -> header_received ) {
605+ ret = recv (ctx -> real_sock , & ctx -> header [ctx -> pos ],
606+ sizeof (ctx -> header ) - ctx -> pos ,
607+ timeout == K_NO_WAIT ? MSG_DONTWAIT : 0 );
608+ if (ret < 0 ) {
609+ return ret ;
610+ }
611+
612+ if (ret < sizeof (ctx -> header )) {
613+ ctx -> pos += ret ;
614+ return - EAGAIN ;
615+ }
616+
617+ /* All the header is now received, we can read the data next */
618+ ctx -> header_received = true;
619+
620+ websocket_parse_header (ctx -> header , ret , masked , mask_value ,
621+ message_len , & message_type_flag ,
622+ & header_len );
623+
624+ /* If there is any data in the header, then move it to the
625+ * data buffer.
626+ */
627+ if (header_len < sizeof (ctx -> header )) {
628+ NET_ASSERT (ctx -> pos <= sizeof (ctx -> header ));
629+
630+ memcpy (buf , & ctx -> header [header_len ],
631+ sizeof (ctx -> header ) - ctx -> pos );
632+ pos_to_write = sizeof (ctx -> header ) - ctx -> pos ;
633+ }
634+
635+ ctx -> message_len = * message_len ;
636+ }
637+
638+ ret = recv (ctx -> real_sock , & buf [pos_to_write ],
639+ buf_len - pos_to_write ,
659640 timeout == K_NO_WAIT ? MSG_DONTWAIT : 0 );
660641 if (ret < 0 ) {
661642 return ret ;
662643 }
663644
664- ret = websocket_strip_header (buf , buf_len , masked , mask_value ,
665- & message_length , & message_type_flag ,
666- & header_len );
667- if (ret < 0 ) {
668- return ret ;
645+ ret += pos_to_write ;
646+
647+ /* Unmask the data */
648+ websocket_mask_payload (buf , ret , * mask_value );
649+
650+ ctx -> total_read += ret ;
651+
652+ /* If we receive the end of the message and there is still data left,
653+ * store the remaining to header and tmp buffer.
654+ */
655+ if (ctx -> total_read >= ctx -> message_len ) {
656+ ret -= ctx -> total_read - ctx -> message_len ;
657+
658+ if (ret > 0 ) {
659+ /* Rest of the stuff is suppose to go to header temp
660+ * buffer and to user specified temp buf
661+ */
662+
663+ } else {
664+ ctx -> header_received = false;
665+ }
669666 }
670667
671- return 0 ;
668+ return ret ;
672669}
673670
674671static int websocket_send (struct websocket_context * ctx , const u8_t * buf ,
@@ -688,11 +685,13 @@ static int websocket_recv(struct websocket_context *ctx, u8_t *buf,
688685 bool masked ;
689686 u32_t mask_value ;
690687 u32_t message_type ;
688+ u64_t message_len ;
691689
692690 NET_DBG ("[%p] Waiting data, buf len %zd bytes" , ctx , buf_len );
693691
694692 return websocket_recv_msg (ctx -> sock , buf , buf_len , & masked ,
695- & mask_value , & message_type , timeout );
693+ & mask_value , & message_type , & message_len ,
694+ timeout );
696695}
697696
698697static ssize_t websocket_read_vmeth (void * obj , void * buffer , size_t count )
0 commit comments