3737#if MICROPY_PY_WEBSOCKET
3838
3939enum { FRAME_HEADER , FRAME_OPT , PAYLOAD };
40+ #define FRAME_OPCODE_MASK 0x0f
41+ enum {
42+ FRAME_CONT , FRAME_TXT , FRAME_BIN ,
43+ FRAME_CLOSE = 0x8 , FRAME_PING , FRAME_PONG
44+ };
45+
4046enum { BLOCKING_WRITE = 1 };
4147
4248typedef struct _mp_obj_websocket_t {
@@ -50,6 +56,8 @@ typedef struct _mp_obj_websocket_t {
5056 byte buf_pos ;
5157 byte buf [6 ];
5258 byte opts ;
59+ // Copy of current frame's flags
60+ byte ws_flags ;
5361} mp_obj_websocket_t ;
5462
5563STATIC mp_obj_t websocket_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
@@ -87,8 +95,24 @@ STATIC mp_uint_t websocket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int
8795
8896 switch (self -> state ) {
8997 case FRAME_HEADER : {
98+ // TODO: Split frame handling below is untested so far, so conservatively disable it
9099 assert (self -> buf [0 ] & 0x80 );
91100
101+ // "Control frames MAY be injected in the middle of a fragmented message."
102+ // So, they must be processed before data frames (and not alter
103+ // self->ws_flags)
104+ if ((self -> buf [0 ] & FRAME_OPCODE_MASK ) >= FRAME_CLOSE ) {
105+ // TODO: implement
106+ assert (0 );
107+ }
108+
109+ if ((self -> buf [0 ] & FRAME_OPCODE_MASK ) == FRAME_CONT ) {
110+ // Preserve previous frame type
111+ self -> ws_flags = (self -> ws_flags & FRAME_OPCODE_MASK ) | (self -> buf [0 ] & ~FRAME_OPCODE_MASK );
112+ } else {
113+ self -> ws_flags = self -> buf [0 ];
114+ }
115+
92116 // Reset mask in case someone will use "simplified" protocol
93117 // without masks.
94118 memset (self -> mask , 0 , sizeof (self -> mask ));
0 commit comments