@@ -16,6 +16,11 @@ extern void free_dap_ringbuf();
16
16
17
17
extern uint32_t DAP_ExecuteCommand (const uint8_t * request , uint8_t * response );
18
18
19
+ struct el_context {
20
+ bool is_async ;
21
+ };
22
+
23
+ static struct el_context k_el_context ;
19
24
uint8_t * el_process_buffer = NULL ;
20
25
21
26
void el_process_buffer_malloc () {
@@ -66,11 +71,83 @@ void el_dap_data_process(void* buffer, size_t len) {
66
71
usbip_network_send (kSock , el_process_buffer , res , 0 );
67
72
}
68
73
74
+ static inline int recv_all (int fd , uint8_t * buf , size_t size , int flag )
75
+ {
76
+ const size_t total = size ;
77
+ int ret ;
78
+
79
+ if (size == 0 )
80
+ return 0 ;
81
+
82
+ do {
83
+ ret = recv (fd , buf , size , flag );
84
+ if (ret <= 0 )
85
+ return ret ;
86
+
87
+ buf += ret ;
88
+ size -= ret ;
89
+ } while (size );
90
+
91
+ return total ;
92
+ }
93
+
94
+ static int el_vendor_command_pre_process (uint8_t * base , int recved_len )
95
+ {
96
+ int offset = 0 ;
97
+ int payload_len , remain_len , packet_len ;
98
+ uint16_t * payload ;
99
+ int ret ;
100
+
101
+ while (recved_len - offset >= 4 ) {
102
+ payload = (uint16_t * )(base + offset + 2 );
103
+ payload_len = ntohs (* payload );
104
+ packet_len = 4 + payload_len ;
105
+
106
+ if (offset + packet_len > recved_len )
107
+ break ;
108
+
109
+ el_dap_data_process (base + offset , packet_len );
110
+ offset += packet_len ;
111
+ }
112
+
113
+ // already process done
114
+ remain_len = recved_len - offset ;
115
+ if (remain_len == 0 )
116
+ return 1 ;
117
+
118
+ memmove (base , base + offset , remain_len );
119
+ if (remain_len < 4 ) {
120
+ ret = recv (kSock , base + remain_len , 4 - remain_len , 0 );
121
+ if (ret <= 0 )
122
+ return ret ;
123
+ offset = 4 ;
124
+ remain_len = 0 ;
125
+ } else {
126
+ offset = remain_len ;
127
+ remain_len -= 4 ;
128
+ }
129
+
130
+ payload = (uint16_t * )(base + 2 );
131
+ payload_len = ntohs (* payload );
132
+ if (payload_len - remain_len > 0 ) {
133
+ ret = recv (kSock , base + offset , payload_len - remain_len , 0 );
134
+ if (ret <= 0 )
135
+ return ret ;
136
+ }
137
+
138
+ el_dap_data_process (base , 4 + payload_len );
139
+
140
+ return 1 ;
141
+ }
142
+
69
143
int el_dap_work (uint8_t * base , size_t len )
70
144
{
145
+ uint16_t * length , payload_len ;
71
146
uint8_t * data ;
72
147
int sz , ret ;
73
148
149
+ memset (& k_el_context , 0 , sizeof (struct el_context ));
150
+
74
151
// read command code and protocol version
75
152
data = base + 4 ;
76
153
sz = 8 ;
@@ -93,8 +170,80 @@ int el_dap_work(uint8_t* base, size_t len)
93
170
ret = recv (kSock , base , len , 0 );
94
171
if (ret <= 0 )
95
172
return ret ;
96
- el_dap_data_process (base , ret );
173
+
174
+ if (* base == EL_VENDOR_COMMAND_PERFIX ) {
175
+ ret = el_vendor_command_pre_process (base , ret );
176
+ if (ret <= 0 )
177
+ return ret ;
178
+ } else {
179
+ el_dap_data_process (base , ret );
180
+ }
181
+
182
+ if (k_el_context .is_async ) {
183
+ do {
184
+ ret = recv_all (kSock , base , 4 , 0 );
185
+ if (ret <= 0 )
186
+ return ret ;
187
+ length = (uint16_t * )(base + 2 );
188
+ payload_len = ntohs (* length );
189
+
190
+ ret = recv_all (kSock , base + 4 , payload_len , 0 );
191
+ if (ret <= 0 )
192
+ return ret ;
193
+ el_dap_data_process (base , 4 + ntohs (* length ));
194
+ } while (k_el_context .is_async );
195
+ }
97
196
}
98
197
99
198
return 0 ;
100
199
}
200
+
201
+ uint32_t el_native_command_passthrough (const uint8_t * request , uint8_t * response )
202
+ {
203
+ int ret ;
204
+
205
+ request += 2 ; // skip header (length field)
206
+
207
+ ret = DAP_ExecuteCommand (request , response + 3 );
208
+ ret &= 0xFFFF ;
209
+
210
+ response [0 ] = 0x00 ; // status
211
+ response [1 ] = (ret >> 8 ) & 0xFF ;
212
+ response [2 ] = ret & 0xFF ;
213
+
214
+ return ret + 4 ; // header + payload
215
+ }
216
+
217
+ uint32_t el_vendor_command (const uint8_t * request , uint8_t * response )
218
+ {
219
+ uint8_t type ;
220
+ uint32_t ret = 0 ;
221
+
222
+ type = * request ++ ;
223
+
224
+ switch (type ) {
225
+ case EL_NATIVE_COMMAND_PASSTHROUGH :
226
+ ret = el_native_command_passthrough (request , response );
227
+ break ;
228
+ case EL_VENDOR_SCOPE_ENTER :
229
+ memset (& k_el_context , 0 , sizeof (struct el_context ));
230
+ k_el_context .is_async = true;
231
+ * response ++ = 0 ; // status
232
+ * response ++ = 0 ;
233
+ * response ++ = 0 ;
234
+ ret = 4 ;
235
+ break ;
236
+ case EL_VENDOR_SCOPE_EXIT :
237
+ k_el_context .is_async = false;
238
+ * response ++ = 0 ; // status
239
+ * response ++ = 0 ;
240
+ * response ++ = 0 ;
241
+ ret = 4 ;
242
+ break ;
243
+ default :
244
+ break ;
245
+ }
246
+
247
+ return ret ;
248
+ }
249
+
0 commit comments