23 #ifdef HAVE_ARPA_INET_H
24 #include <arpa/inet.h>
30 #ifdef HAVE_NETINET_TCP_H
31 #include <netinet/tcp.h>
35 #ifdef HAVE_SYS_IOCTL_H
36 #include <sys/ioctl.h>
38 #ifdef HAVE_SYS_SOCKET_H
39 #include <sys/socket.h>
41 #include <sys/types.h>
59 #define STRINGIFY(x) #x
62 #define DAP_PKT_HDR_SIGNATURE 0x00504144
63 #define DAP_PKT_TYPE_REQUEST 0x01
64 #define DAP_PKT_TYPE_RESPONSE 0x02
66 #define CMSIS_DAP_TCP_PORT 4441
67 #define CMSIS_DAP_PACKET_SIZE 1024
79 #define DEFAULT_MIN_TIMEOUT_MS 150
96 #define HEADER_SIGNATURE_OFFSET 0
97 #define HEADER_LENGTH_OFFSET sizeof(uint32_t)
98 #define HEADER_PACKET_TYPE_OFFSET (sizeof(uint32_t) + sizeof(uint16_t))
99 #define HEADER_RESERVED_OFFSET (sizeof(uint32_t) + sizeof(uint16_t) + \
101 #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint16_t) + \
129 switch (WSAGetLastError()) {
131 case WSAECONNABORTED:
155 LOG_ERROR(
"The hostname or IP address of the CMSIS-DAP adapter must be specified");
163 LOG_ERROR(
"CMSIS-DAP: unable to allocate memory");
168 struct addrinfo hints = {
169 .ai_family = AF_UNSPEC,
170 .ai_socktype = SOCK_STREAM
172 struct addrinfo *result, *rp;
175 LOG_INFO(
"CMSIS-DAP: Connecting to %s:%s using TCP backend",
183 LOG_ERROR(
"CMSIS-DAP: getaddrinfo: %s\n", gai_strerror(s));
193 for (rp = result; rp ; rp = rp->ai_next) {
194 fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
198 if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
206 freeaddrinfo(result);
209 LOG_ERROR(
"CMSIS-DAP: unable to connect to device %s:%s",
220 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (
const char *)&one,
sizeof(one));
258 LOG_DEBUG_IO(
"CMSIS-DAP: using tcp timeout %d msec", wait_ms);
264 LOG_DEBUG_IO(
"CMSIS-DAP: extending timeout to %d msec", wait_ms);
289 struct cmsis_dap_tcp_packet_hdr header;
296 LOG_ERROR(
"CMSIS-DAP: Unrecognized packet signature 0x%08x",
301 LOG_ERROR(
"CMSIS-DAP: Unrecognized packet type 0x%02x",
306 LOG_ERROR(
"CMSIS-DAP: Packet length %d too large to fit.",
313 unsigned int total_len =
HEADER_SIZE + header.length;
316 LOG_DEBUG_IO(
"Read %u bytes (%u payload)", total_len, (
unsigned int)header.length);
317 return (
int)total_len;
324 if (remaining <= 0) {
325 if (timeout_expected)
328 LOG_ERROR(
"CMSIS-DAP: TCP read timed out");
341 }
else if (ret == 0) {
342 LOG_ERROR(
"CMSIS-DAP: connection closed by peer");
348 int err = WSAGetLastError();
351 if (err == WSAEWOULDBLOCK || err == WSAETIMEDOUT) {
353 LOG_ERROR(
"CMSIS-DAP: TCP read timed out");
361 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ETIMEDOUT) {
363 LOG_ERROR(
"CMSIS-DAP: TCP read timed out");
371 LOG_ERROR(
"CMSIS-DAP: error reading data");
384 LOG_ERROR(
"CMSIS-DAP: Packet length %d exceeds TCP buffer size!", len);
399 LOG_DEBUG_IO(
"Writing %d bytes (%d payload)", len, txlen);
404 would_block = (WSAGetLastError() == WSAEWOULDBLOCK);
406 would_block = (errno == EAGAIN || errno == EWOULDBLOCK);
409 LOG_ERROR(
"CMSIS-DAP: TCP write timed out");
414 }
else if (retval != (
int)len) {
415 LOG_ERROR(
"CMSIS-DAP: error writing data");
425 unsigned int packet_buffer_size = pkt_sz +
HEADER_SIZE;
428 uint8_t *buf = malloc(2 * packet_buffer_size);
430 LOG_ERROR(
"CMSIS-DAP: unable to allocate CMSIS-DAP packet buffer");
497 LOG_INFO(
"CMSIS-DAP: using minimum timeout of %d ms for TCP packets.",
505 .handler = &cmsis_dap_handle_tcp_host,
507 .help =
"set the host name to use (for TCP backend only)",
508 .usage =
"<host_name>",
512 .handler = &cmsis_dap_handle_tcp_port,
514 .help =
"set the port number to use for DAP (for TCP backend only)",
515 .usage =
"<port_number>",
518 .name =
"min_timeout",
519 .handler = &cmsis_dap_handle_tcp_min_timeout,
521 .help =
"set the minimum timeout in milliseconds to wait for response "
522 "packets (for TCP backend only)",
523 .usage =
"<milliseconds>",
#define CMSIS_DAP_TIMEOUT_SHORT_MS
#define HEADER_PACKET_TYPE_OFFSET
static void cmsis_dap_tcp_free(struct cmsis_dap *dap)
static char * cmsis_dap_tcp_host
#define HEADER_RESERVED_OFFSET
static int cmsis_dap_tcp_read(struct cmsis_dap *dap, int transfer_timeout_ms, enum cmsis_dap_blocking blocking)
#define DAP_PKT_HDR_SIGNATURE
#define DEFAULT_MIN_TIMEOUT_MS
static int cmsis_dap_tcp_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
static char * cmsis_dap_tcp_port
static bool is_socket_error_fatal(void)
COMMAND_HANDLER(cmsis_dap_handle_tcp_port)
static char cmsis_dap_tcp_port_default[]
static void cmsis_dap_tcp_close(struct cmsis_dap *dap)
static void cmsis_dap_tcp_cancel_all(struct cmsis_dap *dap)
#define HEADER_LENGTH_OFFSET
#define DAP_PKT_TYPE_REQUEST
static int cmsis_dap_tcp_open(struct cmsis_dap *dap, const uint16_t vids[] __attribute__((unused)), const uint16_t pids[] __attribute__((unused)), const char *serial __attribute__((unused)))
const struct command_registration cmsis_dap_tcp_subcommand_handlers[]
struct __attribute__((packed))
#define DAP_PKT_TYPE_RESPONSE
const struct cmsis_dap_backend cmsis_dap_tcp_backend
#define CMSIS_DAP_TCP_PORT
static int cmsis_dap_tcp_min_timeout_ms
#define CMSIS_DAP_PACKET_SIZE
static int cmsis_dap_tcp_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
#define HEADER_SIGNATURE_OFFSET
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
void log_socket_error(const char *socket_desc)
#define LOG_DEBUG_IO(expr ...)
#define LOG_ERROR(expr ...)
#define ERROR_TIMEOUT_REACHED
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static void socket_block(int fd)
static int read_socket(int handle, void *buffer, unsigned int count)
static int socket_recv_timeout(int fd, unsigned long timeout_msec)
static int close_socket(int sock)
static int socket_send_timeout(int fd, unsigned long timeout_msec)
static int write_socket(int handle, const void *buffer, unsigned int count)
static void socket_nonblock(int fd)
unsigned int read_buffer_len
unsigned int read_buffer_size
unsigned int read_buffer_consumed
unsigned int packet_buffer_size
unsigned int packet_usable_size
struct cmsis_dap_backend_data * bdata
static uint16_t le_to_h_u16(const uint8_t *buf)
static void h_u32_to_le(uint8_t *buf, uint32_t val)
static void h_u16_to_le(uint8_t *buf, uint16_t val)
static uint32_t le_to_h_u32(const uint8_t *buf)