37
37
#if MICROPY_PY_WEBSOCKET
38
38
39
39
enum { 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
+
40
46
enum { BLOCKING_WRITE = 1 };
41
47
42
48
typedef struct _mp_obj_websocket_t {
@@ -50,6 +56,8 @@ typedef struct _mp_obj_websocket_t {
50
56
byte buf_pos ;
51
57
byte buf [6 ];
52
58
byte opts ;
59
+ // Copy of current frame's flags
60
+ byte ws_flags ;
53
61
} mp_obj_websocket_t ;
54
62
55
63
STATIC 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
87
95
88
96
switch (self -> state ) {
89
97
case FRAME_HEADER : {
98
+ // TODO: Split frame handling below is untested so far, so conservatively disable it
90
99
assert (self -> buf [0 ] & 0x80 );
91
100
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
+
92
116
// Reset mask in case someone will use "simplified" protocol
93
117
// without masks.
94
118
memset (self -> mask , 0 , sizeof (self -> mask ));
0 commit comments