@@ -16,6 +16,11 @@ extern void free_dap_ringbuf();
1616
1717extern uint32_t DAP_ExecuteCommand (const uint8_t * request , uint8_t * response );
1818
19+ struct el_context {
20+ bool is_async ;
21+ };
22+
23+ static struct el_context k_el_context ;
1924uint8_t * el_process_buffer = NULL ;
2025
2126void el_process_buffer_malloc () {
@@ -66,11 +71,83 @@ void el_dap_data_process(void* buffer, size_t len) {
6671 usbip_network_send (kSock , el_process_buffer , res , 0 );
6772}
6873
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+
69143int el_dap_work (uint8_t * base , size_t len )
70144{
145+ uint16_t * length , payload_len ;
71146 uint8_t * data ;
72147 int sz , ret ;
73148
149+ memset (& k_el_context , 0 , sizeof (struct el_context ));
150+
74151 // read command code and protocol version
75152 data = base + 4 ;
76153 sz = 8 ;
@@ -93,8 +170,80 @@ int el_dap_work(uint8_t* base, size_t len)
93170 ret = recv (kSock , base , len , 0 );
94171 if (ret <= 0 )
95172 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+ }
97196 }
98197
99198 return 0 ;
100199}
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