Skip to content

Commit

Permalink
refactor(network): Refactor usbip and tcp process code
Browse files Browse the repository at this point in the history
In previous versions, parsing of the usbip protocol was implemented
via a global state machine and shared with elaphureLink.

The refactored code removes these global state machines and handles them
with the corresponding protocol header commands.
  • Loading branch information
windowsair committed Feb 16, 2024
1 parent 8abe565 commit 16f8b53
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 243 deletions.
38 changes: 35 additions & 3 deletions components/elaphureLink/elaphureLink_protocol.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "components/elaphureLink/elaphureLink_protocol.h"

#include "main/DAP_handle.h"

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>

extern int kRestartDAPHandle;
extern int kSock;
extern int usbip_network_send(int s, const void *dataptr, size_t size, int flags);

Expand All @@ -25,15 +27,13 @@ void el_process_buffer_malloc() {
el_process_buffer = malloc(1500);
}


void el_process_buffer_free() {
if (el_process_buffer != NULL) {
free(el_process_buffer);
el_process_buffer = NULL;
}
}


int el_handshake_process(int fd, void *buffer, size_t len) {
if (len != sizeof(el_request_handshake)) {
return -1;
Expand All @@ -59,10 +59,42 @@ int el_handshake_process(int fd, void *buffer, size_t len) {
return 0;
}


void el_dap_data_process(void* buffer, size_t len) {
int res = DAP_ExecuteCommand(buffer, (uint8_t *)el_process_buffer);
res &= 0xFFFF;

usbip_network_send(kSock, el_process_buffer, res, 0);
}

int el_dap_work(uint8_t* base, size_t len)
{
uint8_t *data;
int sz, ret;

// read command code and protocol version
data = base + 4;
sz = 8;
do {
ret = recv(kSock, data, sz, 0);
if (ret <= 0)
return ret;
sz -= ret;
data += ret;
} while (sz > 0);

ret = el_handshake_process(kSock, base, 12);
if (ret)
return ret;

kRestartDAPHandle = DELETE_HANDLE;
el_process_buffer_malloc();
// data process
while(1) {
ret = recv(kSock, base, len, 0);
if (ret <= 0)
return ret;
el_dap_data_process(base, ret);
}

return 0;
}
2 changes: 2 additions & 0 deletions components/elaphureLink/elaphureLink_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ int el_handshake_process(int fd, void* buffer, size_t len);
void el_dap_data_process(void* buffer, size_t len);


int el_dap_work(uint8_t* base, size_t len);

void el_process_buffer_malloc();
void el_process_buffer_free();

Expand Down
2 changes: 1 addition & 1 deletion main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set(COMPONENT_ADD_INCLUDEDIRS "${PROJECT_PATH}")
set(COMPONENT_SRCS
main.c timer.c tcp_server.c usbip_server.c DAP_handle.c
kcp_server.c tcp_netconn.c uart_bridge.c wifi_handle.c)
uart_bridge.c wifi_handle.c)

register_component()
85 changes: 29 additions & 56 deletions main/DAP_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,15 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
// Point to the beginning of the URB packet

#if (USE_WINUSB == 1)
send_stage2_submit(header, 0, 0);
send_stage2_submit_data_fast(header, NULL, 0);

// always send constant size buf -> cuz we don't care about the IN packet size
// and to unify the style, we set aside the length of the section
xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY);
xTaskNotifyGive(kDAPTaskHandle);

#else
send_stage2_submit(header, 0, 0);
send_stage2_submit_data_fast(header, NULL, 0);

xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY);
xTaskNotifyGive(kDAPTaskHandle);
Expand All @@ -131,22 +131,6 @@ void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
// send_stage2_submit(header, 0, 0);
}

void handle_dap_data_response(usbip_stage2_header *header)
{
return;
// int resLength = dap_respond & 0xFFFF;
// if (resLength)
// {

// send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength);
// dap_respond = 0;
// }
// else
// {
// send_stage2_submit(header, 0, 0);
// }
}

void handle_swo_trace_response(usbip_stage2_header *header)
{
#if (SWO_FUNCTION_ENABLE == 1)
Expand Down Expand Up @@ -261,54 +245,43 @@ void DAP_Thread(void *argument)
}
}

int fast_reply(uint8_t *buf, uint32_t length)
int fast_reply(uint8_t *buf, uint32_t length, int dap_req_num)
{
usbip_stage2_header *buf_header = (usbip_stage2_header *)buf;
if (length == 48 &&
buf_header->base.command == PP_HTONL(USBIP_STAGE2_REQ_SUBMIT) &&
buf_header->base.direction == PP_HTONL(USBIP_DIR_IN) &&
buf_header->base.ep == PP_HTONL(1))
{
if (dap_respond > 0)
{
DapPacket_t *item;
size_t packetSize = 0;
item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
pdMS_TO_TICKS(10), DAP_HANDLE_SIZE);
if (packetSize == DAP_HANDLE_SIZE)
{

if (dap_req_num > 0) {
DapPacket_t *item;
size_t packetSize = 0;
item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
portMAX_DELAY, DAP_HANDLE_SIZE);
if (packetSize == DAP_HANDLE_SIZE) {
#if (USE_WINUSB == 1)
send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length);
send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length);
#else
send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE);
send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE);
#endif

if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
{
--dap_respond;
xSemaphoreGive(data_response_mux);
}

vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
return 1;
}
else if (packetSize > 0)
{
os_printf("Wrong data out packet size:%d!\r\n", packetSize);
if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) {
--dap_respond;
xSemaphoreGive(data_response_mux);
}
////TODO: fast reply
}
else
{
buf_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT);
buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT);
buf_header->u.ret_submit.status = 0;
buf_header->u.ret_submit.data_length = 0;
buf_header->u.ret_submit.error_count = 0;
usbip_network_send(kSock, buf, 48, 0);

vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
return 1;
} else if (packetSize > 0) {
os_printf("Wrong data out packet size:%d!\r\n", packetSize);
}
////TODO: fast reply
} else {
buf_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT);
buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT);
buf_header->u.ret_submit.status = 0;
buf_header->u.ret_submit.data_length = 0;
buf_header->u.ret_submit.error_count = 0;
usbip_network_send(kSock, buf, 48, 0);
return 1;
}

return 0;
}

Expand Down
3 changes: 1 addition & 2 deletions main/DAP_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ enum reset_handle_t
};

void handle_dap_data_request(usbip_stage2_header *header, uint32_t length);
void handle_dap_data_response(usbip_stage2_header *header);
void handle_swo_trace_response(usbip_stage2_header *header);
void handle_dap_unlink();

int fast_reply(uint8_t *buf, uint32_t length);
int fast_reply(uint8_t *buf, uint32_t length, int dap_req_num);

#endif
93 changes: 30 additions & 63 deletions main/tcp_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@
extern TaskHandle_t kDAPTaskHandle;
extern int kRestartDAPHandle;

uint8_t kState = ACCEPTING;
int kSock = -1;

void tcp_server_task(void *pvParameters)
{
uint8_t tcp_rx_buffer[1500];
char addr_str[128];
enum usbip_server_state_t usbip_state = WAIT_DEVLIST;
uint8_t *data;
int addr_family;
int ip_protocol;
int header;
int ret, sz;

int on = 1;
while (1)
Expand Down Expand Up @@ -111,75 +114,39 @@ void tcp_server_task(void *pvParameters)
setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on));
os_printf("Socket accepted\r\n");

while (1)
{
int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
// Error occured during receiving
if (len < 0)
{
os_printf("recv failed: errno %d\r\n", errno);
break;
}
// Connection closed
else if (len == 0)
{
os_printf("Connection closed\r\n");
break;
}
// Data received
// Read header
sz = 4;
data = &tcp_rx_buffer[0];
do {
ret = recv(kSock, data, sz, 0);
if (ret <= 0)
goto cleanup;
sz -= ret;
data += ret;
} while (sz > 0);

header = *((int *)(tcp_rx_buffer));
header = ntohl(header);

if (header == EL_LINK_IDENTIFIER) {
el_dap_work(tcp_rx_buffer, sizeof(tcp_rx_buffer));
} else if ((header & 0xFFFF) == 0x8003 ||
(header & 0xFFFF) == 0x8005) { // usbip OP_REQ_DEVLIST/OP_REQ_IMPORT
if ((header & 0xFFFF) == 0x8005)
usbip_state = WAIT_DEVLIST;
else
{
// #ifdef CONFIG_EXAMPLE_IPV6
// // Get the sender's ip address as string
// if (sourceAddr.sin6_family == PF_INET)
// {
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
// }
// else if (sourceAddr.sin6_family == PF_INET6)
// {
// inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
// }
// #else
// inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
// #endif

switch (kState)
{
case ACCEPTING:
kState = ATTACHING;

case ATTACHING:
// elaphureLink handshake
if (el_handshake_process(kSock, tcp_rx_buffer, len) == 0) {
// handshake successed
kState = EL_DATA_PHASE;
kRestartDAPHandle = DELETE_HANDLE;
el_process_buffer_malloc();
break;
}

attach(tcp_rx_buffer, len);
break;

case EMULATING:
emulate(tcp_rx_buffer, len);
break;
case EL_DATA_PHASE:
el_dap_data_process(tcp_rx_buffer, len);
break;
default:
os_printf("unkonw kstate!\r\n");
}
}
usbip_state = WAIT_IMPORT;
usbip_worker(tcp_rx_buffer, sizeof(tcp_rx_buffer), &usbip_state);
} else {
os_printf("Unknown protocol\n");
}
// kState = ACCEPTING;

cleanup:
if (kSock != -1)
{
os_printf("Shutting down socket and restarting...\r\n");
//shutdown(kSock, 0);
close(kSock);
if (kState == EMULATING || kState == EL_DATA_PHASE)
kState = ACCEPTING;

// Restart DAP Handle
el_process_buffer_free();
Expand Down
Loading

0 comments on commit 16f8b53

Please sign in to comment.