@@ -32,6 +32,7 @@ typedef struct {
32
32
uint8_t frame_len ;
33
33
uint8_t payload_len_size ;
34
34
bool masked ;
35
+ bool closed ;
35
36
uint8_t mask [4 ];
36
37
int frame_index ;
37
38
size_t payload_remaining ;
@@ -49,14 +50,18 @@ void websocket_init(void) {
49
50
void websocket_handoff (socketpool_socket_obj_t * socket ) {
50
51
ESP_LOGI (TAG , "socket handed off" );
51
52
cp_serial .socket = * socket ;
53
+ cp_serial .closed = false;
54
+ cp_serial .opcode = 0 ;
55
+ cp_serial .frame_index = 0 ;
56
+ cp_serial .frame_len = 2 ;
52
57
// Mark the original socket object as closed without telling the lower level.
53
58
socket -> connected = false;
54
59
socket -> num = -1 ;
55
60
ESP_LOGI (TAG , "socket hand off done" );
56
61
}
57
62
58
63
bool websocket_connected (void ) {
59
- return common_hal_socketpool_socket_get_connected (& cp_serial .socket );
64
+ return ! cp_serial . closed && common_hal_socketpool_socket_get_connected (& cp_serial .socket );
60
65
}
61
66
62
67
static bool _read_byte (uint8_t * c ) {
@@ -70,6 +75,16 @@ static bool _read_byte(uint8_t *c) {
70
75
return true;
71
76
}
72
77
78
+ static void _send_raw (socketpool_socket_obj_t * socket , const uint8_t * buf , int len ) {
79
+ int sent = - EAGAIN ;
80
+ while (sent == - EAGAIN ) {
81
+ sent = socketpool_socket_send (socket , buf , len );
82
+ }
83
+ if (sent < len ) {
84
+ ESP_LOGE (TAG , "short send on %d err %d len %d" , socket -> num , sent , len );
85
+ }
86
+ }
87
+
73
88
static void _read_next_frame_header (void ) {
74
89
uint8_t h ;
75
90
if (cp_serial .frame_index == 0 && _read_byte (& h )) {
@@ -111,20 +126,53 @@ static void _read_next_frame_header(void) {
111
126
cp_serial .frame_index ++ ;
112
127
ESP_LOGI (TAG , "mask %08x" , (uint32_t )* cp_serial .mask );
113
128
}
129
+ // Reply to PINGs and CLOSE.
130
+ while ((cp_serial .opcode == 0x8 ||
131
+ cp_serial .opcode == 0x9 ) &&
132
+ cp_serial .frame_index >= cp_serial .frame_len ) {
133
+
134
+ if (cp_serial .frame_index == cp_serial .frame_len ) {
135
+ uint8_t opcode = 0x8 ; // CLOSE
136
+ if (cp_serial .opcode == 0x9 ) {
137
+ ESP_LOGI (TAG , "websocket ping" );
138
+ opcode = 0xA ; // PONG
139
+ }
140
+ uint8_t frame_header [2 ];
141
+ frame_header [0 ] = 1 << 7 | opcode ;
142
+ if (cp_serial .payload_remaining > 125 ) {
143
+ ESP_LOGE (TAG , "CLOSE or PING has long payload" );
144
+ }
145
+ frame_header [1 ] = cp_serial .payload_remaining ;
146
+ _send_raw (& cp_serial .socket , (const uint8_t * )frame_header , 2 );
147
+ }
148
+
149
+ if (cp_serial .payload_remaining > 0 && _read_byte (& h )) {
150
+ // Send the payload back to the client.
151
+ cp_serial .frame_index ++ ;
152
+ cp_serial .payload_remaining -- ;
153
+ _send_raw (& cp_serial .socket , & h , 1 );
154
+ }
155
+
156
+ if (cp_serial .payload_remaining == 0 ) {
157
+ cp_serial .frame_index = 0 ;
158
+ if (cp_serial .opcode == 0x8 ) {
159
+ ESP_LOGI (TAG , "websocket closed" );
160
+ cp_serial .closed = true;
161
+ }
162
+ }
163
+ }
114
164
}
115
165
116
166
static bool _read_next_payload_byte (uint8_t * c ) {
117
167
_read_next_frame_header ();
118
- if (cp_serial .frame_index >= cp_serial .frame_len &&
168
+ if (cp_serial .opcode == 0x1 &&
169
+ cp_serial .frame_index >= cp_serial .frame_len &&
119
170
cp_serial .payload_remaining > 0 ) {
120
171
if (_read_byte (c )) {
121
172
uint8_t mask_offset = (cp_serial .frame_index - cp_serial .frame_len ) % 4 ;
122
- ESP_LOGI (TAG , "payload byte read %02x mask offset %d" , * c , mask_offset );
123
173
* c ^= cp_serial .mask [mask_offset ];
124
- ESP_LOGI (TAG , "byte unmasked %02x" , * c );
125
174
cp_serial .frame_index ++ ;
126
175
cp_serial .payload_remaining -- ;
127
- ESP_LOGI (TAG , "payload remaining %d" , cp_serial .payload_remaining );
128
176
if (cp_serial .payload_remaining == 0 ) {
129
177
cp_serial .frame_index = 0 ;
130
178
}
@@ -148,16 +196,6 @@ char websocket_read_char(void) {
148
196
return c ;
149
197
}
150
198
151
- static void _send_raw (socketpool_socket_obj_t * socket , const uint8_t * buf , int len ) {
152
- int sent = - EAGAIN ;
153
- while (sent == - EAGAIN ) {
154
- sent = socketpool_socket_send (socket , buf , len );
155
- }
156
- if (sent < len ) {
157
- ESP_LOGE (TAG , "short send %d %d" , sent , len );
158
- }
159
- }
160
-
161
199
static void _websocket_send (_websocket * ws , const char * text , size_t len ) {
162
200
if (!websocket_connected ()) {
163
201
return ;
0 commit comments