OpenOCD
rtt_server.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /*
4  * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include <stdint.h>
12 #include <rtt/rtt.h>
13 
14 #include "server.h"
15 #include "rtt_server.h"
16 
26 struct rtt_service {
27  unsigned int channel;
29 };
30 
31 static int read_callback(unsigned int channel, const uint8_t *buffer,
32  size_t length, void *user_data)
33 {
34  int ret;
35  struct connection *connection;
36  size_t offset;
37 
38  connection = (struct connection *)user_data;
39  offset = 0;
40 
41  while (offset < length) {
43 
44  if (ret < 0) {
45  LOG_ERROR("Failed to write data to socket.");
46  return ERROR_FAIL;
47  }
48 
49  offset += ret;
50  }
51 
52  return ERROR_OK;
53 }
54 
56 {
57  int ret;
58  struct rtt_service *service;
59 
61 
62  LOG_DEBUG("rtt: New connection for channel %u", service->channel);
63 
65 
66  if (ret != ERROR_OK)
67  return ret;
68 
69  if (service->hello_message)
70  connection_write(connection, service->hello_message, strlen(service->hello_message));
71 
72  return ERROR_OK;
73 }
74 
76 {
77  struct rtt_service *service;
78 
81 
82  LOG_DEBUG("rtt: Connection for channel %u closed", service->channel);
83 
84  return ERROR_OK;
85 }
86 
87 static int rtt_input(struct connection *connection)
88 {
89  int bytes_read;
90  unsigned char buffer[1024];
91  struct rtt_service *service;
92  size_t length;
93 
95  bytes_read = connection_read(connection, buffer, sizeof(buffer));
96 
97  if (!bytes_read)
99  else if (bytes_read < 0) {
100  LOG_ERROR("error during read: %s", strerror(errno));
102  }
103 
104  length = bytes_read;
105  rtt_write_channel(service->channel, buffer, &length);
106 
107  return ERROR_OK;
108 }
109 
110 static const struct service_driver rtt_service_driver = {
111  .name = "rtt",
112  .new_connection_during_keep_alive_handler = NULL,
113  .new_connection_handler = rtt_new_connection,
114  .input_handler = rtt_input,
115  .connection_closed_handler = rtt_connection_closed,
116  .keep_client_alive_handler = NULL,
117 };
118 
119 COMMAND_HANDLER(handle_rtt_start_command)
120 {
121  int ret;
122  struct rtt_service *service;
123 
124  if (CMD_ARGC < 2 || CMD_ARGC > 3)
126 
127  service = calloc(1, sizeof(struct rtt_service));
128 
129  if (!service)
130  return ERROR_FAIL;
131 
132  COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
133 
134  if (CMD_ARGC >= 3) {
135  const char *hello_message = CMD_ARGV[2];
136  size_t hello_length = strlen(hello_message);
137 
138  service->hello_message = malloc(hello_length + 2);
139  if (!service->hello_message) {
140  LOG_ERROR("Out of memory");
141  free(service);
142  return ERROR_FAIL;
143  }
144  strcpy(service->hello_message, hello_message);
145  service->hello_message[hello_length] = '\n';
146  service->hello_message[hello_length + 1] = '\0';
147  }
149 
150  if (ret != ERROR_OK) {
151  free(service);
152  return ERROR_FAIL;
153  }
154 
155  return ERROR_OK;
156 }
157 
158 COMMAND_HANDLER(handle_rtt_stop_command)
159 {
160  if (CMD_ARGC != 1)
162 
163  remove_service("rtt", CMD_ARGV[0]);
164 
165  return ERROR_OK;
166 }
167 
169  {
170  .name = "start",
171  .handler = handle_rtt_start_command,
172  .mode = COMMAND_ANY,
173  .help = "Start a RTT server",
174  .usage = "<port> <channel> [message]"
175  },
176  {
177  .name = "stop",
178  .handler = handle_rtt_stop_command,
179  .mode = COMMAND_ANY,
180  .help = "Stop a RTT server",
181  .usage = "<port>"
182  },
184 };
185 
186 static const struct command_registration rtt_server_command_handlers[] = {
187  {
188  .name = "server",
189  .mode = COMMAND_ANY,
190  .help = "RTT server",
191  .usage = "",
193  },
195 };
196 
197 static const struct command_registration rtt_command_handlers[] = {
198  {
199  .name = "rtt",
200  .mode = COMMAND_ANY,
201  .help = "RTT",
202  .usage = "",
204  },
206 };
207 
209 {
211 }
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:156
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:402
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:151
#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:442
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:253
static int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix, const struct command_registration *cmds)
Register one or more commands in the specified context, as children of parent (or top-level commends,...
Definition: command.h:274
@ COMMAND_ANY
Definition: command.h:42
uint8_t length
Definition: esp_usb_jtag.c:1
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
int rtt_register_sink(unsigned int channel_index, rtt_sink_read read, void *user_data)
Register an RTT sink.
Definition: rtt/rtt.c:206
int rtt_unregister_sink(unsigned int channel_index, rtt_sink_read read, void *user_data)
Unregister an RTT sink.
Definition: rtt/rtt.c:232
int rtt_write_channel(unsigned int channel_index, const uint8_t *buffer, size_t *length)
Write to an RTT channel.
Definition: rtt/rtt.c:288
static int rtt_connection_closed(struct connection *connection)
Definition: rtt_server.c:75
static const struct command_registration rtt_command_handlers[]
Definition: rtt_server.c:197
static int rtt_new_connection(struct connection *connection)
Definition: rtt_server.c:55
static int rtt_input(struct connection *connection)
Definition: rtt_server.c:87
COMMAND_HANDLER(handle_rtt_start_command)
Definition: rtt_server.c:119
static int read_callback(unsigned int channel, const uint8_t *buffer, size_t length, void *user_data)
Definition: rtt_server.c:31
static const struct command_registration rtt_server_subcommand_handlers[]
Definition: rtt_server.c:168
int rtt_server_register_commands(struct command_context *ctx)
Definition: rtt_server.c:208
static const struct command_registration rtt_server_command_handlers[]
Definition: rtt_server.c:186
static const struct service_driver rtt_service_driver
Definition: rtt_server.c:110
int connection_write(struct connection *connection, const void *data, int len)
Definition: server.c:732
int connection_read(struct connection *connection, void *data, int len)
Definition: server.c:744
int remove_service(const char *name, const char *port)
Definition: server.c:355
int add_service(const struct service_driver *driver, const char *port, int max_connections, void *priv)
Definition: server.c:198
#define CONNECTION_LIMIT_UNLIMITED
Definition: server.h:34
#define ERROR_SERVER_REMOTE_CLOSED
Definition: server.h:119
const char * name
Definition: command.h:235
struct service * service
Definition: server.h:41
unsigned int channel
Definition: rtt_server.c:27
char * hello_message
Definition: rtt_server.c:28
const char * name
the name of the server
Definition: server.h:49
Definition: server.h:67
void * priv
Definition: server.h:81
#define NULL
Definition: usb.h:16
uint8_t offset[4]
Definition: vdebug.c:9