This is an automated email from Gerrit. "fanoush <fano...@gmail.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8358
-- gerrit commit 0e5130503c8eb77e5d94a5dc7a1255f37cc02f96 Author: fanoush <fano...@gmail.com> Date: Mon Sep 2 13:49:19 2024 +0200 rtt server: fix for dropped data when target has no space rtt_write_channel may write less data then requested, default buffer size for channel 0 is 16 bytes so currently anything larger then this is dropped. This fix implements per connection buffer and uses the connection->input_pending flag to retry writes Change-Id: If9e46260e47b3781c8e6c4ec40df97ce596d193f Signed-off-by: fanoush <fano...@gmail.com> diff --git a/src/server/rtt_server.c b/src/server/rtt_server.c index 9769153475..c8b93b30af 100644 --- a/src/server/rtt_server.c +++ b/src/server/rtt_server.c @@ -28,6 +28,12 @@ struct rtt_service { char *hello_message; }; +struct rtt_connection_data { + unsigned char data[64]; + unsigned int len; + unsigned int idx; +}; + static int read_callback(unsigned int channel, const uint8_t *buffer, size_t length, void *user_data) { @@ -56,7 +62,14 @@ static int rtt_new_connection(struct connection *connection) { int ret; struct rtt_service *service; + struct rtt_connection_data *data; + + data = calloc(1, sizeof(struct rtt_connection_data)); + if (!data) + return ERROR_FAIL; + + connection->priv = (void*)data; service = connection->service->priv; LOG_DEBUG("rtt: New connection for channel %u", service->channel); @@ -79,31 +92,53 @@ static int rtt_connection_closed(struct connection *connection) service = (struct rtt_service *)connection->service->priv; rtt_unregister_sink(service->channel, &read_callback, connection); - LOG_DEBUG("rtt: Connection for channel %u closed", service->channel); + free(connection->priv); + LOG_DEBUG("rtt: Connection for channel %u closed", service->channel); return ERROR_OK; } static int rtt_input(struct connection *connection) { int bytes_read; - unsigned char buffer[1024]; + unsigned char *ptr; struct rtt_service *service; - size_t length; + struct rtt_connection_data *data; + size_t length, to_write; + data = (struct rtt_connection_data *)connection->priv; service = (struct rtt_service *)connection->service->priv; - bytes_read = connection_read(connection, buffer, sizeof(buffer)); - if (!bytes_read) - return ERROR_SERVER_REMOTE_CLOSED; - else if (bytes_read < 0) { - LOG_ERROR("error during read: %s", strerror(errno)); - return ERROR_SERVER_REMOTE_CLOSED; - } + if (connection->input_pending == false) { + bytes_read = connection_read(connection, data->data, sizeof(data->data)); - length = bytes_read; - rtt_write_channel(service->channel, buffer, &length); + if (!bytes_read) + return ERROR_SERVER_REMOTE_CLOSED; + else if (bytes_read < 0) { + LOG_ERROR("error during read: %s", strerror(errno)); + return ERROR_SERVER_REMOTE_CLOSED; + } + data->len = bytes_read; + data->idx = 0; + } + if (data->len > 0){ + // try sending data + ptr = data->data + data->idx; + to_write = length = data->len - data->idx; + rtt_write_channel(service->channel, ptr, &length); + + if (length < to_write){ + // continue next time + data->idx += length; + connection->input_pending = true; + } else { + // we wrote everything + data->len=0; + data->idx=0; + connection->input_pending = false; + } + } return ERROR_OK; } --