Skip to content

Commit 4aeaebb

Browse files
committed
feat(dap): Add support for elaphureLink vendor command
1 parent 47d26b9 commit 4aeaebb

File tree

4 files changed

+161
-17
lines changed

4 files changed

+161
-17
lines changed

components/DAP/source/DAP.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,20 +1670,6 @@ static uint32_t DAP_WriteAbort(const uint8_t *request, uint8_t *response) {
16701670
return ((5U << 16) | num);
16711671
}
16721672

1673-
1674-
// Process DAP Vendor command request and prepare response
1675-
// Default function (can be overridden)
1676-
// request: pointer to request data
1677-
// response: pointer to response data
1678-
// return: number of bytes in response (lower 16 bits)
1679-
// number of bytes in request (upper 16 bits)
1680-
__WEAK uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
1681-
(void)request;
1682-
*response = ID_DAP_Invalid;
1683-
return ((1U << 16) | 1U);
1684-
}
1685-
1686-
16871673
// Process DAP command request and prepare response
16881674
// request: pointer to request data
16891675
// response: pointer to response data

components/DAP/source/DAP_vendor.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "components/DAP/config/DAP_config.h"
2929
#include "components/DAP/include/DAP.h"
30+
#include "components/elaphureLink/elaphureLink_protocol.h"
3031

3132
//**************************************************************************************************
3233
/**
@@ -68,7 +69,9 @@ uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
6869
case ID_DAP_Vendor5: break;
6970
case ID_DAP_Vendor6: break;
7071
case ID_DAP_Vendor7: break;
71-
case ID_DAP_Vendor8: break;
72+
case ID_DAP_Vendor8:
73+
num = el_vendor_command(request, response);
74+
break;
7275
case ID_DAP_Vendor9: break;
7376
case ID_DAP_Vendor10: break;
7477
case ID_DAP_Vendor11: break;

components/elaphureLink/elaphureLink_protocol.c

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ extern void free_dap_ringbuf();
1616

1717
extern 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;
1924
uint8_t* el_process_buffer = NULL;
2025

2126
void 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+
69143
int 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+

components/elaphureLink/elaphureLink_protocol.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66

77
#define EL_LINK_IDENTIFIER 0x8a656c70
88

9-
#define EL_DAP_VERSION 0x00000001
9+
#define EL_DAP_VERSION 0x10000 // v1.0.0 support vendor command
1010

1111
#define EL_COMMAND_HANDSHAKE 0x00000000
1212

13+
#define EL_VENDOR_COMMAND_PERFIX 0x88
14+
#define EL_NATIVE_COMMAND_PASSTHROUGH 0x1
15+
#define EL_VENDOR_SCOPE_ENTER 0x2
16+
#define EL_VENDOR_SCOPE_EXIT 0x3
1317

1418
typedef struct
1519
{
@@ -47,6 +51,8 @@ int el_handshake_process(int fd, void* buffer, size_t len);
4751
void el_dap_data_process(void* buffer, size_t len);
4852

4953

54+
uint32_t el_vendor_command(const uint8_t *request, uint8_t *response);
55+
5056
int el_dap_work(uint8_t* base, size_t len);
5157

5258
void el_process_buffer_malloc();

0 commit comments

Comments
 (0)