0
0
Fork 0

feat: Add elaphureLink support

This commit is contained in:
windowsair 2022-07-22 19:04:47 +08:00
parent 0f9f0eb27e
commit 40778a7dc6
7 changed files with 202 additions and 15 deletions

View File

@ -0,0 +1,4 @@
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_SRCS "./elaphureLink_protocol.c")
register_component()

View File

@ -0,0 +1,68 @@
#include "components/elaphureLink/elaphureLink_protocol.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
extern int kSock;
extern int usbip_network_send(int s, const void *dataptr, size_t size, int flags);
extern void malloc_dap_ringbuf();
extern void free_dap_ringbuf();
extern uint32_t DAP_ExecuteCommand(const uint8_t *request, uint8_t *response);
uint8_t* el_process_buffer = NULL;
void el_process_buffer_malloc() {
if (el_process_buffer != NULL)
return;
free_dap_ringbuf();
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;
}
el_request_handshake* req = (el_request_handshake*)buffer;
if (ntohl(req->el_link_identifier) != EL_LINK_IDENTIFIER) {
return -1;
}
if (ntohl(req->command) != EL_COMMAND_HANDSHAKE) {
return -1;
}
el_response_handshake res;
res.el_link_identifier = htonl(EL_LINK_IDENTIFIER);
res.command = htonl(EL_COMMAND_HANDSHAKE);
res.el_dap_version = htonl(EL_DAP_VERSION);
usbip_network_send(fd, &res, sizeof(el_response_handshake), 0);
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);
}

View File

@ -0,0 +1,53 @@
#ifndef __ELAPHURELINK_PROTOCOL_H__
#define __ELAPHURELINK_PROTOCOL_H__
#include <stdint.h>
#include <stddef.h>
#define EL_LINK_IDENTIFIER 0x8a656c70
#define EL_DAP_VERSION 0x00000001
#define EL_COMMAND_HANDSHAKE 0x00000000
typedef struct
{
uint32_t el_link_identifier;
uint32_t command;
uint32_t el_proxy_version
} __attribute__((packed)) el_request_handshake;
typedef struct
{
uint32_t el_link_identifier;
uint32_t command;
uint32_t el_dap_version
} __attribute__((packed)) el_response_handshake;
/**
* @brief elahpureLink Proxy handshake phase process
*
* @param fd socket fd
* @param buffer packet buffer
* @param len packet length
* @return 0 on Success, other on failed.
*/
int el_handshake_process(int fd, void* buffer, size_t len);
/**
* @brief Process dap data and send to socket
*
* @param buffer dap data buffer
* @param len dap data length
*/
void el_dap_data_process(void* buffer, size_t len);
void el_process_buffer_malloc();
void el_process_buffer_free();
#endif

View File

@ -58,7 +58,7 @@ typedef struct
extern int kSock; extern int kSock;
extern TaskHandle_t kDAPTaskHandle; extern TaskHandle_t kDAPTaskHandle;
int kRestartDAPHandle = 0; int kRestartDAPHandle = NO_SIGNAL;
static DapPacket_t DAPDataProcessed; static DapPacket_t DAPDataProcessed;
@ -74,6 +74,36 @@ static RingbufHandle_t dap_dataOUT_handle = NULL;
static SemaphoreHandle_t data_response_mux = NULL; static SemaphoreHandle_t data_response_mux = NULL;
void malloc_dap_ringbuf() {
if (data_response_mux && xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
{
if (dap_dataIN_handle == NULL) {
dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * DAP_BUFFER_NUM, RINGBUF_TYPE_BYTEBUF);
}
if (dap_dataOUT_handle == NULL) {
dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * DAP_BUFFER_NUM, RINGBUF_TYPE_BYTEBUF);
}
xSemaphoreGive(data_response_mux);
}
}
void free_dap_ringbuf() {
if (data_response_mux && xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE) {
if (dap_dataIN_handle) {
vRingbufferDelete(dap_dataIN_handle);
}
if (dap_dataOUT_handle) {
vRingbufferDelete(dap_dataOUT_handle);
}
dap_dataIN_handle = dap_dataOUT_handle = NULL;
xSemaphoreGive(data_response_mux);
}
}
void handle_dap_data_request(usbip_stage2_header *header, uint32_t length) void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
{ {
uint8_t *data_in = (uint8_t *)header; uint8_t *data_in = (uint8_t *)header;
@ -168,21 +198,28 @@ void DAP_Thread(void *argument)
{ {
if (kRestartDAPHandle) if (kRestartDAPHandle)
{ {
vRingbufferDelete(dap_dataIN_handle); free_dap_ringbuf();
vRingbufferDelete(dap_dataOUT_handle);
dap_dataIN_handle = dap_dataOUT_handle = NULL;
dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * DAP_BUFFER_NUM, RINGBUF_TYPE_BYTEBUF); if (kRestartDAPHandle == RESET_HANDLE) {
dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * DAP_BUFFER_NUM, RINGBUF_TYPE_BYTEBUF); malloc_dap_ringbuf();
if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL) if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL)
{ {
os_printf("Can not create DAP ringbuf/mux!\r\n"); os_printf("Can not create DAP ringbuf/mux!\r\n");
vTaskDelete(NULL); vTaskDelete(NULL);
} }
kRestartDAPHandle = 0;
} }
ulTaskNotifyTake(pdFALSE, portMAX_DELAY); kRestartDAPHandle = NO_SIGNAL;
}
ulTaskNotifyTake(pdFALSE, portMAX_DELAY); // wait event
if (dap_dataIN_handle == NULL || dap_dataOUT_handle == NULL) {
continue; // may be use elaphureLink, wait...
}
packetSize = 0; packetSize = 0;
item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize, item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
pdMS_TO_TICKS(1), DAP_HANDLE_SIZE); pdMS_TO_TICKS(1), DAP_HANDLE_SIZE);

View File

@ -3,6 +3,13 @@
#include "components/USBIP/usbip_defs.h" #include "components/USBIP/usbip_defs.h"
enum reset_handle_t
{
NO_SIGNAL = 0,
RESET_HANDLE = 1,
DELETE_HANDLE = 2,
};
void handle_dap_data_request(usbip_stage2_header *header, uint32_t length); void handle_dap_data_request(usbip_stage2_header *header, uint32_t length);
void handle_dap_data_response(usbip_stage2_header *header); void handle_dap_data_response(usbip_stage2_header *header);
void handle_swo_trace_response(usbip_stage2_header *header); void handle_swo_trace_response(usbip_stage2_header *header);

View File

@ -13,6 +13,9 @@
#include "main/wifi_configuration.h" #include "main/wifi_configuration.h"
#include "main/usbip_server.h" #include "main/usbip_server.h"
#include "main/DAP_handle.h"
#include "components/elaphureLink/elaphureLink_protocol.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
@ -146,12 +149,24 @@ void tcp_server_task(void *pvParameters)
kState = ATTACHING; kState = ATTACHING;
case 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); attach(tcp_rx_buffer, len);
break; break;
case EMULATING: case EMULATING:
emulate(tcp_rx_buffer, len); emulate(tcp_rx_buffer, len);
break; break;
case EL_DATA_PHASE:
el_dap_data_process(tcp_rx_buffer, len);
break;
default: default:
os_printf("unkonw kstate!\r\n"); os_printf("unkonw kstate!\r\n");
} }
@ -163,11 +178,13 @@ void tcp_server_task(void *pvParameters)
os_printf("Shutting down socket and restarting...\r\n"); os_printf("Shutting down socket and restarting...\r\n");
//shutdown(kSock, 0); //shutdown(kSock, 0);
close(kSock); close(kSock);
if (kState == EMULATING) if (kState == EMULATING || kState == EL_DATA_PHASE)
kState = ACCEPTING; kState = ACCEPTING;
// Restart DAP Handle // Restart DAP Handle
kRestartDAPHandle = 1; el_process_buffer_free();
kRestartDAPHandle = RESET_HANDLE;
if (kDAPTaskHandle) if (kDAPTaskHandle)
xTaskNotifyGive(kDAPTaskHandle); xTaskNotifyGive(kDAPTaskHandle);

View File

@ -9,7 +9,8 @@ enum state_t
{ {
ACCEPTING, ACCEPTING,
ATTACHING, ATTACHING,
EMULATING EMULATING,
EL_DATA_PHASE
}; };
extern uint8_t kState; extern uint8_t kState;
extern int kSock; extern int kSock;