OpenOCD
cmsis_dap_tcp.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Provides CMSIS-DAP protocol over a TCP/IP socket. *
5  * UART and SWO are currently unsupported. *
6  * *
7  * Copyright (C) 2025 by Brian Kuschak <bkuschak@gmail.com> *
8  * *
9  * Adapted from cmsis_dap_usb_hid.c. Copyright (C) 2013-2018 by: *
10  * MickaĆ«l Thomas <mickael9@gmail.com> *
11  * Maksym Hilliaka <oter@frozen-team.com> *
12  * Phillip Pearson <pp@myelin.co.nz> *
13  * Paul Fertser <fercerpav@gmail.com> *
14  * mike brown <mike@theshedworks.org.uk> *
15  * Spencer Oliver <spen@spen-soft.co.uk> *
16  * *
17  ***************************************************************************/
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #ifdef HAVE_ARPA_INET_H
24 #include <arpa/inet.h>
25 #endif
26 #include <errno.h>
27 #ifdef HAVE_NETDB_H
28 #include <netdb.h>
29 #endif
30 #ifdef HAVE_NETINET_TCP_H
31 #include <netinet/tcp.h>
32 #endif
33 #include <stdbool.h>
34 #include <string.h>
35 #ifdef HAVE_SYS_IOCTL_H
36 #include <sys/ioctl.h>
37 #endif
38 #ifdef HAVE_SYS_SOCKET_H
39 #include <sys/socket.h>
40 #endif
41 #include <sys/types.h>
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 
46 #ifdef _WIN32
47 #include <winsock2.h>
48 #include <ws2tcpip.h>
49 #endif
50 
51 #include "helper/command.h"
52 #include "helper/log.h"
53 #include "helper/replacements.h"
54 #include "helper/system.h"
55 #include "helper/time_support.h"
56 #include "cmsis_dap.h"
57 #include "server/server.h"
58 
59 #define STRINGIFY(x) #x
60 
61 // If the protocol changes in the future, the SIGNATURE should also be changed.
62 #define DAP_PKT_HDR_SIGNATURE 0x00504144 // "DAP"
63 #define DAP_PKT_TYPE_REQUEST 0x01
64 #define DAP_PKT_TYPE_RESPONSE 0x02
65 
66 #define CMSIS_DAP_TCP_PORT 4441 // Default. Can be overridden.
67 #define CMSIS_DAP_PACKET_SIZE 1024 // Max payload size not including
68  // header.
69 
70 /* When flushing after an error, the CMSIS-DAP driver assumes the pipeline is
71  * empty if it doesn't get a response after a short 10 msec timeout. While this
72  * works for USB, it may not work for TCP/IP due to higher network latency. TCP
73  * response packets may take longer to arrive. We set a lower bound on timeout
74  * for blocking reads, to give enough time for packets to arrive.
75  *
76  * The user may override this default value by setting the parameter
77  * 'cmsis-dap tcp min_timeout'
78  */
79 #define DEFAULT_MIN_TIMEOUT_MS 150
80 
81 /* CMSIS-DAP requests are variable length. With CMSIS-DAP over USB, the
82  * transfer sizes are preserved by the USB stack. However, TCP/IP is stream
83  * oriented so we perform our own packetization to preserve the boundaries
84  * between each request. This short header is prepended to each CMSIS-DAP
85  * request and response before being sent over the socket. Little endian format
86  * is used for multibyte values.
87  */
88 struct __attribute__((packed)) cmsis_dap_tcp_packet_hdr {
89  uint32_t signature; // "DAP"
90  uint16_t length; // Not including header length.
91  uint8_t packet_type;
92  uint8_t reserved; // Reserved for future use.
93 };
94 
95 /* Defines for struct cmsis_dap_tcp_packet_hdr requested by reviewer. */
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) + \
100  sizeof(uint8_t))
101 #define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint16_t) + \
102  2 * sizeof(uint8_t))
103 
105  int sockfd;
107 
108  // Region of dap->packet_buffer used to accumulate socket reads.
109  uint8_t *read_buffer;
110 
111  unsigned int read_buffer_size; // read_buffer capacity
112  unsigned int read_buffer_len; // number of bytes buffered
113  unsigned int read_buffer_consumed; // number to be discarded
114 };
115 
116 static char *cmsis_dap_tcp_host;
120 
121 static void cmsis_dap_tcp_close(struct cmsis_dap *dap);
122 static int cmsis_dap_tcp_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);
123 static void cmsis_dap_tcp_free(struct cmsis_dap *dap);
124 
125 // True if the peer is definitely gone (socket closed / aborted / reset).
126 static bool is_socket_error_fatal(void)
127 {
128 #ifdef _WIN32
129  switch (WSAGetLastError()) {
130  case WSAECONNRESET:
131  case WSAECONNABORTED:
132  return true;
133  default:
134  return false;
135  }
136 #else
137  switch (errno) {
138  case ECONNRESET:
139  case ECONNABORTED:
140  case EPIPE:
141  return true;
142  default:
143  return false;
144  }
145 #endif
146 }
147 
148 static int cmsis_dap_tcp_open(struct cmsis_dap *dap,
149  const uint16_t vids[] __attribute__((unused)),
150  const uint16_t pids[] __attribute__((unused)),
151  const char *serial __attribute__((unused)))
152 {
153  // Skip the open if the user has not provided a hostname.
154  if (!cmsis_dap_tcp_host) {
155  LOG_ERROR("The hostname or IP address of the CMSIS-DAP adapter must be specified");
156  return ERROR_FAIL;
157  }
158 
159  // Ignore vids, pids, serial. We use host and port subcommands instead.
160 
161  dap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));
162  if (!dap->bdata) {
163  LOG_ERROR("CMSIS-DAP: unable to allocate memory");
164  return ERROR_FAIL;
165  }
166  dap->bdata->socket_closed = false;
167 
168  struct addrinfo hints = {
169  .ai_family = AF_UNSPEC,
170  .ai_socktype = SOCK_STREAM
171  };
172  struct addrinfo *result, *rp;
173  int fd = 0;
174 
175  LOG_INFO("CMSIS-DAP: Connecting to %s:%s using TCP backend",
177 
178  /* Some of the following code was taken from remote_bitbang.c */
179  /* Obtain address(es) matching host/port */
180  int s = getaddrinfo(cmsis_dap_tcp_host, cmsis_dap_tcp_port, &hints,
181  &result);
182  if (s != 0) {
183  LOG_ERROR("CMSIS-DAP: getaddrinfo: %s\n", gai_strerror(s));
184  free(dap->bdata);
185  return ERROR_FAIL;
186  }
187 
188  /* getaddrinfo() returns a list of address structures.
189  Try each address until we successfully connect(2).
190  If socket(2) (or connect(2)) fails, we (close the socket
191  and) try the next address. */
192 
193  for (rp = result; rp ; rp = rp->ai_next) {
194  fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
195  if (fd == -1)
196  continue;
197 
198  if (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1) {
199  LOG_DEBUG("Connected.");
200  break; /* Success */
201  }
202 
203  close(fd);
204  }
205 
206  freeaddrinfo(result);
207 
208  if (!rp) { /* No address succeeded */
209  LOG_ERROR("CMSIS-DAP: unable to connect to device %s:%s",
211  log_socket_error("Failed to connect");
212  free(dap->bdata);
213  dap->bdata = NULL;
214  return ERROR_FAIL;
215  }
216 
217  /* Set NODELAY to minimize latency. */
218  int one = 1;
219  /* On Windows optval has to be a const char *. */
220  setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
221 
222  dap->bdata->sockfd = fd;
223 
224  int retval = cmsis_dap_tcp_alloc(dap, CMSIS_DAP_PACKET_SIZE);
225  if (retval != ERROR_OK) {
226  cmsis_dap_tcp_close(dap);
227  return retval;
228  }
229  return ERROR_OK;
230 }
231 
232 static void cmsis_dap_tcp_close(struct cmsis_dap *dap)
233 {
234  if (close_socket(dap->bdata->sockfd) != 0)
235  log_socket_error("close_socket");
236 
237  if (dap->bdata)
238  free(dap->bdata);
239  dap->bdata = NULL;
240  cmsis_dap_tcp_free(dap);
241 }
242 
243 static int cmsis_dap_tcp_read(struct cmsis_dap *dap, int transfer_timeout_ms,
244  enum cmsis_dap_blocking blocking)
245 {
246  if (dap->bdata->socket_closed)
247  return ERROR_FAIL;
248 
249  /* Sometimes the CMSIS-DAP driver requests a very short timeout that it
250  * expects may time out. In that case, we won't print an error message.
251  */
252  bool timeout_expected = (transfer_timeout_ms <= CMSIS_DAP_TIMEOUT_SHORT_MS) ?
253  true : false;
254 
255  int wait_ms = (blocking == CMSIS_DAP_NON_BLOCKING) ? 0 :
256  transfer_timeout_ms;
257  if (wait_ms) {
258  LOG_DEBUG_IO("CMSIS-DAP: using tcp timeout %d msec", wait_ms);
259 
260  // Don't use very short timeouts with TCP/IP as it may not be as fast
261  // to respond as USB. User configurable minimum value.
262  if (wait_ms < cmsis_dap_tcp_min_timeout_ms) {
264  LOG_DEBUG_IO("CMSIS-DAP: extending timeout to %d msec", wait_ms);
265  }
266  }
267  int64_t deadline = timeval_ms() + wait_ms;
268  socket_recv_timeout(dap->bdata->sockfd, wait_ms);
269 
270  if (blocking == CMSIS_DAP_NON_BLOCKING)
272  else
273  socket_block(dap->bdata->sockfd);
274 
275  // Discard any previously consumed packet.
276  if (dap->bdata->read_buffer_consumed) {
277  unsigned int remaining = dap->bdata->read_buffer_len - dap->bdata->read_buffer_consumed;
278  if (remaining)
279  memmove(dap->bdata->read_buffer,
281  remaining);
282  dap->bdata->read_buffer_len = remaining;
283  dap->bdata->read_buffer_consumed = 0;
284  }
285 
286  while (true) {
287  // Header available?
288  if (dap->bdata->read_buffer_len >= HEADER_SIZE) {
289  struct cmsis_dap_tcp_packet_hdr header;
290  header.signature = le_to_h_u32(dap->bdata->read_buffer + HEADER_SIGNATURE_OFFSET);
291  header.length = le_to_h_u16(dap->bdata->read_buffer + HEADER_LENGTH_OFFSET);
292  header.packet_type = dap->bdata->read_buffer[HEADER_PACKET_TYPE_OFFSET];
293  header.reserved = dap->bdata->read_buffer[HEADER_RESERVED_OFFSET];
294 
295  if (header.signature != DAP_PKT_HDR_SIGNATURE) {
296  LOG_ERROR("CMSIS-DAP: Unrecognized packet signature 0x%08x",
297  header.signature);
298  dap->bdata->read_buffer_len = 0; // Discard buffer
299  return ERROR_FAIL;
300  } else if (header.packet_type != DAP_PKT_TYPE_RESPONSE) {
301  LOG_ERROR("CMSIS-DAP: Unrecognized packet type 0x%02x",
302  header.packet_type);
303  dap->bdata->read_buffer_len = 0;
304  return ERROR_FAIL;
305  } else if (header.length + HEADER_SIZE > dap->bdata->read_buffer_size) {
306  LOG_ERROR("CMSIS-DAP: Packet length %d too large to fit.",
307  header.length);
308  dap->bdata->read_buffer_len = 0;
309  return ERROR_FAIL;
310  }
311 
312  // Complete packet available?
313  unsigned int total_len = HEADER_SIZE + header.length;
314  if (dap->bdata->read_buffer_len >= total_len) {
315  dap->bdata->read_buffer_consumed = total_len;
316  LOG_DEBUG_IO("Read %u bytes (%u payload)", total_len, (unsigned int)header.length);
317  return (int)total_len;
318  }
319  }
320 
321  // Update timeout and accumulate from the socket into read_buffer.
322  if (blocking == CMSIS_DAP_BLOCKING) {
323  int64_t remaining = deadline - timeval_ms();
324  if (remaining <= 0) {
325  if (timeout_expected)
326  LOG_DEBUG_IO("CMSIS-DAP: TCP read timed out");
327  else
328  LOG_ERROR("CMSIS-DAP: TCP read timed out");
329  return ERROR_TIMEOUT_REACHED;
330  }
331  socket_recv_timeout(dap->bdata->sockfd, (unsigned long)remaining);
332  }
333 
334  unsigned int space = dap->bdata->read_buffer_size - dap->bdata->read_buffer_len;
335  int ret = read_socket(dap->bdata->sockfd,
336  (char *)(dap->bdata->read_buffer + dap->bdata->read_buffer_len), space);
337 
338  if (ret > 0) {
339  dap->bdata->read_buffer_len += ret;
340  continue;
341  } else if (ret == 0) {
342  LOG_ERROR("CMSIS-DAP: connection closed by peer");
343  dap->bdata->socket_closed = true;
344  return ERROR_FAIL;
345  }
346  // ret < 0
347 #ifdef _WIN32
348  int err = WSAGetLastError();
349  if (err == WSAEINTR)
350  continue;
351  if (err == WSAEWOULDBLOCK || err == WSAETIMEDOUT) {
352  if (blocking == CMSIS_DAP_BLOCKING && !timeout_expected)
353  LOG_ERROR("CMSIS-DAP: TCP read timed out");
354  else
355  LOG_DEBUG_IO("CMSIS-DAP: TCP read timed out");
356  return ERROR_TIMEOUT_REACHED;
357  }
358 #else
359  if (errno == EINTR)
360  continue;
361  if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ETIMEDOUT) {
362  if (blocking == CMSIS_DAP_BLOCKING && !timeout_expected)
363  LOG_ERROR("CMSIS-DAP: TCP read timed out");
364  else
365  LOG_DEBUG_IO("CMSIS-DAP: TCP read timed out");
366  return ERROR_TIMEOUT_REACHED;
367  }
368 #endif
369  if (is_socket_error_fatal())
370  dap->bdata->socket_closed = true;
371  LOG_ERROR("CMSIS-DAP: error reading data");
372  log_socket_error("read_socket");
373  return ERROR_FAIL;
374  }
375 }
376 
377 static int cmsis_dap_tcp_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
378 {
379  if (dap->bdata->socket_closed)
380  return ERROR_FAIL;
381 
382  const unsigned int len = txlen + HEADER_SIZE;
383  if (len > dap->packet_buffer_size) {
384  LOG_ERROR("CMSIS-DAP: Packet length %d exceeds TCP buffer size!", len);
385  return ERROR_FAIL;
386  }
387 
388  /* Set the header values. */
393 
394  // Timeout to prevent hang due to a dead peer.
395  socket_block(dap->bdata->sockfd);
396  socket_send_timeout(dap->bdata->sockfd, timeout_ms);
397 
398  /* write data to device */
399  LOG_DEBUG_IO("Writing %d bytes (%d payload)", len, txlen);
400  int retval = write_socket(dap->bdata->sockfd, dap->packet_buffer, len);
401  if (retval < 0) {
402  bool would_block;
403 #ifdef _WIN32
404  would_block = (WSAGetLastError() == WSAEWOULDBLOCK);
405 #else
406  would_block = (errno == EAGAIN || errno == EWOULDBLOCK);
407 #endif
408  if (would_block)
409  LOG_ERROR("CMSIS-DAP: TCP write timed out");
410  else if (is_socket_error_fatal())
411  dap->bdata->socket_closed = true;
412  log_socket_error("write_socket");
413  return ERROR_FAIL;
414  } else if (retval != (int)len) {
415  LOG_ERROR("CMSIS-DAP: error writing data");
416  log_socket_error("write_socket short write");
417  return ERROR_FAIL;
418  }
419  return retval;
420 }
421 
422 static int cmsis_dap_tcp_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
423 {
424  // Reserve space for the packet header.
425  unsigned int packet_buffer_size = pkt_sz + HEADER_SIZE;
426 
427  // Allocate separate regions for command (write) and response (read).
428  uint8_t *buf = malloc(2 * packet_buffer_size);
429  if (!buf) {
430  LOG_ERROR("CMSIS-DAP: unable to allocate CMSIS-DAP packet buffer");
431  return ERROR_FAIL;
432  }
433 
434  // Command buffer in the first half of dap->packet_buffer.
435  dap->packet_buffer = buf;
436  dap->packet_size = pkt_sz;
437  dap->packet_usable_size = pkt_sz;
438  dap->packet_buffer_size = packet_buffer_size;
439  dap->command = dap->packet_buffer + HEADER_SIZE;
440 
441  // Response buffer in the second half of dap->packet_buffer.
442  dap->bdata->read_buffer = dap->packet_buffer + packet_buffer_size;
443  dap->bdata->read_buffer_size = packet_buffer_size;
444  dap->bdata->read_buffer_len = 0;
445  dap->bdata->read_buffer_consumed = 0;
446  dap->response = dap->bdata->read_buffer + HEADER_SIZE;
447 
448  return ERROR_OK;
449 }
450 
451 static void cmsis_dap_tcp_free(struct cmsis_dap *dap)
452 {
453  free(dap->packet_buffer);
454  dap->packet_buffer = NULL;
455 }
456 
457 static void cmsis_dap_tcp_cancel_all(struct cmsis_dap *dap)
458 {
459 }
460 
461 COMMAND_HANDLER(cmsis_dap_handle_tcp_port)
462 {
463  if (CMD_ARGC != 1)
465 
467  free(cmsis_dap_tcp_port);
468 
469  cmsis_dap_tcp_port = strdup(CMD_ARGV[0]);
470  if (!cmsis_dap_tcp_port) {
471  LOG_ERROR("CMSIS-DAP: out of memory");
472  return ERROR_FAIL;
473  }
474  return ERROR_OK;
475 }
476 
477 COMMAND_HANDLER(cmsis_dap_handle_tcp_host)
478 {
479  if (CMD_ARGC != 1)
481 
482  free(cmsis_dap_tcp_host);
483  cmsis_dap_tcp_host = strdup(CMD_ARGV[0]);
484  if (!cmsis_dap_tcp_host) {
485  LOG_ERROR("CMSIS-DAP: out of memory");
486  return ERROR_FAIL;
487  }
488  return ERROR_OK;
489 }
490 
491 COMMAND_HANDLER(cmsis_dap_handle_tcp_min_timeout)
492 {
493  if (CMD_ARGC != 1)
495 
497  LOG_INFO("CMSIS-DAP: using minimum timeout of %d ms for TCP packets.",
499  return ERROR_OK;
500 }
501 
503  {
504  .name = "host",
505  .handler = &cmsis_dap_handle_tcp_host,
506  .mode = COMMAND_CONFIG,
507  .help = "set the host name to use (for TCP backend only)",
508  .usage = "<host_name>",
509  },
510  {
511  .name = "port",
512  .handler = &cmsis_dap_handle_tcp_port,
513  .mode = COMMAND_CONFIG,
514  .help = "set the port number to use for DAP (for TCP backend only)",
515  .usage = "<port_number>",
516  },
517  {
518  .name = "min_timeout",
519  .handler = &cmsis_dap_handle_tcp_min_timeout,
520  .mode = COMMAND_CONFIG,
521  .help = "set the minimum timeout in milliseconds to wait for response "
522  "packets (for TCP backend only)",
523  .usage = "<milliseconds>",
524  },
526 };
527 
529  .name = "tcp",
530  .open = cmsis_dap_tcp_open,
531  .close = cmsis_dap_tcp_close,
532  .read = cmsis_dap_tcp_read,
533  .write = cmsis_dap_tcp_write,
534  .packet_buffer_alloc = cmsis_dap_tcp_alloc,
535  .packet_buffer_free = cmsis_dap_tcp_free,
536  .cancel_all = cmsis_dap_tcp_cancel_all,
537 };
char * serial
Definition: adapter.c:49
cmsis_dap_blocking
Definition: cmsis_dap.h:67
@ CMSIS_DAP_NON_BLOCKING
Definition: cmsis_dap.h:68
@ CMSIS_DAP_BLOCKING
Definition: cmsis_dap.h:69
#define CMSIS_DAP_TIMEOUT_SHORT_MS
Definition: cmsis_dap.h:12
#define HEADER_PACKET_TYPE_OFFSET
Definition: cmsis_dap_tcp.c:98
static void cmsis_dap_tcp_free(struct cmsis_dap *dap)
static char * cmsis_dap_tcp_host
#define HEADER_RESERVED_OFFSET
Definition: cmsis_dap_tcp.c:99
static int cmsis_dap_tcp_read(struct cmsis_dap *dap, int transfer_timeout_ms, enum cmsis_dap_blocking blocking)
#define DAP_PKT_HDR_SIGNATURE
Definition: cmsis_dap_tcp.c:62
#define DEFAULT_MIN_TIMEOUT_MS
Definition: cmsis_dap_tcp.c:79
static int cmsis_dap_tcp_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
static char * cmsis_dap_tcp_port
#define HEADER_SIZE
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)
#define STRINGIFY(x)
Definition: cmsis_dap_tcp.c:59
static void cmsis_dap_tcp_cancel_all(struct cmsis_dap *dap)
#define HEADER_LENGTH_OFFSET
Definition: cmsis_dap_tcp.c:97
#define DAP_PKT_TYPE_REQUEST
Definition: cmsis_dap_tcp.c:63
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))
Definition: cmsis_dap_tcp.c:88
#define DAP_PKT_TYPE_RESPONSE
Definition: cmsis_dap_tcp.c:64
const struct cmsis_dap_backend cmsis_dap_tcp_backend
#define CMSIS_DAP_TCP_PORT
Definition: cmsis_dap_tcp.c:66
static int cmsis_dap_tcp_min_timeout_ms
#define CMSIS_DAP_PACKET_SIZE
Definition: cmsis_dap_tcp.c:67
static int cmsis_dap_tcp_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
#define HEADER_SIGNATURE_OFFSET
Definition: cmsis_dap_tcp.c:96
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:161
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:405
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:156
#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...
Definition: command.h:445
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_CONFIG
Definition: command.h:41
uint8_t length
Definition: esp_usb_jtag.c:1
void log_socket_error(const char *socket_desc)
Definition: log.c:506
#define LOG_DEBUG_IO(expr ...)
Definition: log.h:116
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define ERROR_TIMEOUT_REACHED
Definition: log.h:191
#define LOG_INFO(expr ...)
Definition: log.h:141
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
static void socket_block(int fd)
Definition: replacements.h:192
static int read_socket(int handle, void *buffer, unsigned int count)
Definition: replacements.h:174
static int socket_recv_timeout(int fd, unsigned long timeout_msec)
Definition: replacements.h:227
static int close_socket(int sock)
Definition: replacements.h:183
static int socket_send_timeout(int fd, unsigned long timeout_msec)
Definition: replacements.h:241
static int write_socket(int handle, const void *buffer, unsigned int count)
Definition: replacements.h:165
static void socket_nonblock(int fd)
Definition: replacements.h:203
unsigned int read_buffer_len
unsigned int read_buffer_size
unsigned int read_buffer_consumed
const char * name
Definition: cmsis_dap.h:73
unsigned int packet_buffer_size
Definition: cmsis_dap.h:38
unsigned int packet_usable_size
Definition: cmsis_dap.h:37
unsigned int packet_size
Definition: cmsis_dap.h:36
struct cmsis_dap_backend_data * bdata
Definition: cmsis_dap.h:34
uint8_t * response
Definition: cmsis_dap.h:41
uint8_t * command
Definition: cmsis_dap.h:40
uint8_t * packet_buffer
Definition: cmsis_dap.h:39
const char * name
Definition: command.h:239
int64_t timeval_ms(void)
static uint16_t le_to_h_u16(const uint8_t *buf)
Definition: types.h:122
static void h_u32_to_le(uint8_t *buf, uint32_t val)
Definition: types.h:178
static void h_u16_to_le(uint8_t *buf, uint16_t val)
Definition: types.h:208
static uint32_t le_to_h_u32(const uint8_t *buf)
Definition: types.h:112
#define NULL
Definition: usb.h:16