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;
 }
 

-- 

Reply via email to