flash/nor/stm32l4x: Remove redundant error messages
[openocd.git] / src / server / rtt_server.c
blobdf2247bacd004cc18e0f111c25f695fc2840a3a8
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /*
4 * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>
5 */
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
11 #include <stdint.h>
12 #include <rtt/rtt.h>
14 #include "server.h"
15 #include "rtt_server.h"
17 /**
18 * @file
20 * RTT server.
22 * This server allows access to Real Time Transfer (RTT) channels via TCP
23 * connections.
26 struct rtt_service {
27 unsigned int channel;
30 static int read_callback(unsigned int channel, const uint8_t *buffer,
31 size_t length, void *user_data)
33 int ret;
34 struct connection *connection;
35 size_t offset;
37 connection = (struct connection *)user_data;
38 offset = 0;
40 while (offset < length) {
41 ret = connection_write(connection, buffer + offset, length - offset);
43 if (ret < 0) {
44 LOG_ERROR("Failed to write data to socket.");
45 return ERROR_FAIL;
48 offset += ret;
51 return ERROR_OK;
54 static int rtt_new_connection(struct connection *connection)
56 int ret;
57 struct rtt_service *service;
59 service = connection->service->priv;
61 LOG_DEBUG("rtt: New connection for channel %u", service->channel);
63 ret = rtt_register_sink(service->channel, &read_callback, connection);
65 if (ret != ERROR_OK)
66 return ret;
68 return ERROR_OK;
71 static int rtt_connection_closed(struct connection *connection)
73 struct rtt_service *service;
75 service = (struct rtt_service *)connection->service->priv;
76 rtt_unregister_sink(service->channel, &read_callback, connection);
78 LOG_DEBUG("rtt: Connection for channel %u closed", service->channel);
80 return ERROR_OK;
83 static int rtt_input(struct connection *connection)
85 int bytes_read;
86 unsigned char buffer[1024];
87 struct rtt_service *service;
88 size_t length;
90 service = (struct rtt_service *)connection->service->priv;
91 bytes_read = connection_read(connection, buffer, sizeof(buffer));
93 if (!bytes_read)
94 return ERROR_SERVER_REMOTE_CLOSED;
95 else if (bytes_read < 0) {
96 LOG_ERROR("error during read: %s", strerror(errno));
97 return ERROR_SERVER_REMOTE_CLOSED;
100 length = bytes_read;
101 rtt_write_channel(service->channel, buffer, &length);
103 return ERROR_OK;
106 static const struct service_driver rtt_service_driver = {
107 .name = "rtt",
108 .new_connection_during_keep_alive_handler = NULL,
109 .new_connection_handler = rtt_new_connection,
110 .input_handler = rtt_input,
111 .connection_closed_handler = rtt_connection_closed,
112 .keep_client_alive_handler = NULL,
115 COMMAND_HANDLER(handle_rtt_start_command)
117 int ret;
118 struct rtt_service *service;
120 if (CMD_ARGC != 2)
121 return ERROR_COMMAND_SYNTAX_ERROR;
123 service = malloc(sizeof(struct rtt_service));
125 if (!service)
126 return ERROR_FAIL;
128 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);
130 ret = add_service(&rtt_service_driver, CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED, service);
132 if (ret != ERROR_OK) {
133 free(service);
134 return ERROR_FAIL;
137 return ERROR_OK;
140 COMMAND_HANDLER(handle_rtt_stop_command)
142 if (CMD_ARGC != 1)
143 return ERROR_COMMAND_SYNTAX_ERROR;
145 remove_service("rtt", CMD_ARGV[0]);
147 return ERROR_OK;
150 static const struct command_registration rtt_server_subcommand_handlers[] = {
152 .name = "start",
153 .handler = handle_rtt_start_command,
154 .mode = COMMAND_ANY,
155 .help = "Start a RTT server",
156 .usage = "<port> <channel>"
159 .name = "stop",
160 .handler = handle_rtt_stop_command,
161 .mode = COMMAND_ANY,
162 .help = "Stop a RTT server",
163 .usage = "<port>"
165 COMMAND_REGISTRATION_DONE
168 static const struct command_registration rtt_server_command_handlers[] = {
170 .name = "server",
171 .mode = COMMAND_ANY,
172 .help = "RTT server",
173 .usage = "",
174 .chain = rtt_server_subcommand_handlers
176 COMMAND_REGISTRATION_DONE
179 static const struct command_registration rtt_command_handlers[] = {
181 .name = "rtt",
182 .mode = COMMAND_ANY,
183 .help = "RTT",
184 .usage = "",
185 .chain = rtt_server_command_handlers
187 COMMAND_REGISTRATION_DONE
190 int rtt_server_register_commands(struct command_context *ctx)
192 return register_commands(ctx, NULL, rtt_command_handlers);